首页 > 其他分享 >.NET分布式Orleans - 3 - Grain放置

.NET分布式Orleans - 3 - Grain放置

时间:2024-03-25 09:13:36浏览次数:29  
标签:Orleans 自定义 Grain 放置 NET 节点 Silo

在Orleans 7中,Grain放置是指确定将Grain对象放置在Orleans集群中的哪些物理节点上的过程。

Grain是Orleans中的基本单位,代表应用程序中的逻辑单元或实体。Grain放置策略是一种机制,用于根据不同的因素,将Grain对象放置在合适的节点上,以实现负载均衡、最小化网络延迟和提高容错性。

Grain放置的概念

Grain放置是指将Grain对象放置在Orleans集群中的物理节点上的过程。每个Grain对象都有一个唯一的标识符,Orleans根据Grain对象的标识符以及放置策略来决定将Grain对象放置在哪个节点上。

Grain放置的依据

Orleans 7中Grain放置的依据主要包括:

  • 负载均衡:确保集群中的每个节点负载尽可能均衡,避免某些节点负载过重。
  • 网络拓扑:考虑物理网络拓扑结构,将Grain对象放置在合适的物理节点上,以减少通信延迟。
  • 容错性:确保Grain对象在集群中的高可用性和容错性,避免单点故障。

Grain放置策略

Orleans 7中常见的Grain放置策略包括:

  • RandomPlacement:随机选择一个可用节点来放置Grain对象。这也是默认的策略。
  • ActivationCountBasedPlacement:根据节点上已激活的Grain对象数量选择当前负载最轻的节点来放置Grain对象,以实现负载均衡。
  • PreferLocalPlacement:优先将Grain对象放置在发起调用的本地节点上,以减少跨节点通信的延迟。
  • CustomPlacement:允许用户根据特定需求自定义Grain放置策略。

配置默认放置策略

Orleans 默认将使用随机放置。 可以通过在配置期间注册实现 PlacementStrategy 来重写默认放置策略:

siloBuilder.ConfigureServices(services =>
    services.AddSingleton<PlacementStrategy, MyPlacementStrategy>());

自定义标记属性以节省网络开销

如果希望将不同Client的Grain对象放置在同一个Silo上,以节省网络开销,可以使用自定义标记属性和自定义放置策略来实现。

下面的代码是个例子,在一个游戏中,可以为每个玩家定义一个唯一的标记属性,然后使用自定义放置策略确保具有相同标记属性的Grain对象被放置在同一个Silo上。

这样,同一游戏中不同玩家的Grain对象就可以在同一个Silo上处理,减少了跨网络的通信开销。

public interface IPlayerGrain : IGrainWithStringKey
{
    Task<string> GetPlayerInfo();
}

[SameGamePlacementStrategy]
public class PlayerGrain : Grain, IPlayerGrain
{
    public Task<string> GetPlayerInfo()
    {
        return Task.FromResult($"Player ID: {this.GetPrimaryKeyString()}");
    }
}

// 自定义 IPlacementDirector,用于指定将相同游戏中的不同玩家放置在同一个 Silo 上
public class SameGamePlacementDirector : IPlacementDirector
{
    public Task<SiloAddress> OnAddActivation(
        PlacementStrategy strategy,
        PlacementTarget target,
        IPlacementContext context)
    {
        // 获取游戏 ID,这里简单假设游戏 ID 是整数类型
        int gameId = int.Parse(target.GrainIdentity.Key.ToString().Split('#')[0]);
        // 将游戏 ID 映射到 Silo 的哈希值
        int hashCode = gameId.GetHashCode();
        // 获取 Silo 集群中的 Silo 列表
        var silos = context.GetCompatibleSilos(target).ToArray();
        // 计算 Silo 的索引
        int index = Math.Abs(hashCode % silos.Length);
        // 返回被选中的 Silo 地址
        return Task.FromResult(silos[index]);
    }
}
// 自定义 PlacementStrategy,用于指定使用自定义的 IPlacementDirector
[Serializable]
public sealed class SameGamePlacementStrategy : PlacementStrategy
{

}

[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public sealed class SameGamePlacementStrategyAttribute : PlacementAttribute
{
    public SameGamePlacementStrategyAttribute() : base(new SameGamePlacementStrategy())
    {
    }
}
class Program
{
    static async Task Main(string[] args)
    {
        var host = Host.CreateDefaultBuilder()
            .ConfigureServices((context, services) =>
            {
                services.AddOrleans(builder =>
                {
                    builder
                        .UseLocalhostClustering()
                        .Configure<ClusterOptions>(options =>
                        {
                            options.ClusterId = "dev";
                            options.ServiceId = "OrleansExample";
                        })
                        .AddMemoryGrainStorage("playerGrainStorage")
                        .AddPlacementDirector<SameGamePlacementStrategy>(sp => new SameGamePlacementDirector()); ;
                }); ;

            })
            .ConfigureLogging(l => l.AddConsole())
            .Build();

        await host.StartAsync();

        var client = host.Services.GetRequiredService<IClusterClient>();
        var gameId = "123";
        var pId = gameId + "#" + Guid.NewGuid().ToString("N");
        var a = await client.GetGrain<IPlayerGrain>(pId).GetPlayerInfo();

        Console.ReadKey();

        await host.StopAsync();
    }
}

标签:Orleans,自定义,Grain,放置,NET,节点,Silo
From: https://www.cnblogs.com/chenyishi/p/18091682

相关文章

  • java telnet 远程修改配置文件
    在Java中使用Telnet来远程修改Linux服务器上的配置文件,通常需要编写一个Java程序实现Telnet客户端功能,并结合标准的Linux命令行工具(如vi、sed或cat等)来编辑和替换文件内容。以下是一个简化的概念性示例,实际应用中可能需要更复杂的错误处理和交互逻辑:javaimportjava.io.Inpu......
  • 微软的Redis替代项目——Garnet
    微软研究院最近开源了一个新的C#项目,叫Garnet,它实现了Redis协议,基本可以看做redis的替代品了。文档地址:https://microsoft.github.io/garnet/简单的看了下,它居然是以nuget包发布的,通过它我们可以直接快速实现一个自己的redisserver。usingGarnet;try{usingvarserve......
  • Kubernetes Antipatterns
    InKubernetes,identifyingandavoidinganti-patternsiscrucialformaintainingarobustcontainerorchestrationenvironment.Thesemisleadingpracticesmayinitiallyappeareffectivebutcanleadtocomplications.ThisreadingexplorestenprevalentKub......
  • net core API 后台系统操作日志的实现思路
    netcoreAPI后台系统操作日志的实现思路系统操作日志的实现思路主要问题不在于写日志和表结构设计上。主要问题在识别出哪些数据做了修改。并生成日志。表中数据列众多,且要监控多个表。如果要监控的每个表都去写代码去监控和转换这样的工作量就会比较大。如,用户表【Name,......
  • Kubernetes一文上手【手把手系列】
    目录Kubernetes前言部署方式的演变K8S概述K8S架构Master节点1.APIServer2.Etcd3.ControllerManager4.SchedulerNode节点1.kubelet2.kube-proxy3.容器运行时组件与插件1.KubernetesDNS2.Dashboard3.Heapster4.IngressControllerK8S核心概念PodSerivce......
  • 止损:如何克服贪婪和恐惧 - 三余书屋 3ysw.net
    精读文稿我们今天解读《止损》这本书。它以其独特的视角引导我们重新审视投资中的风险与损失。作为交易心理学的里程碑之作,它早已在投资界享有盛名,被众多投资者视为必读经典。更值得一提的是,这本书的灵感来源于纳西姆·塔勒布的代表作《黑天鹅》,被塔勒布本人誉为投资理财书中......
  • 《我们内心的冲突》安顿好内心的冲突,才能安顿好这一生 - 三余书屋 3ysw.net
    精读文稿今天我们解读《我们内心的冲突》,你听过一个小故事吗?关于小男孩与小女孩的交换游戏。小男孩用最漂亮的石头换糖果,却把最漂亮的石头藏了起来;小女孩则把自己的糖果全给了小男孩。夜晚,小女孩因为得到漂亮的石头而安然入睡,而小男孩却因为怀疑小女孩是否也藏起了糖果而无法......
  • netfilter与iptables的基本原理
    一、netfilter与iptables简介1.netfilter是什么Netfilter自1998年开发,2000年合并到LinuxKernelv2.4版本,是Linux内核提供的一个流量处理框架,用于实现对IP数据包的控制和过滤等功能。即:netfilter是Linux内核自带的防火墙架构。2.iptables是什么ip......
  • EANet:用于医学图像分割的迭代边缘注意网络
    EANet:用于医学图像分割的迭代边缘注意网络摘要引言相关工作方法看一下的论文EANet:Iterativeedgeattentionnetworkformedicalimagesegmentation–2022摘要医学图像的精确自动分割对临床诊断和分析有着重要的帮助。然而,由于(1)医学图像目标的尺度多样性和(2)医......
  • YoloV5、ShuffleNetV2、YoloV5-Lite网络概述
    前言前段时间需要在树莓派上部署一个深度学习环境,先试了YoloV5,fs基本才0.3,远远达不到要求,于是就尝试了一下轻量化网络,试过mobileNet系列+YoloV4,fps有所提升,大概能达到0.9左右,但还是比较慢,于是就发现了YoloV5-Lite这个轻量化网络,极大地加速了fps,基本能达到3左右,因此详细了解了......