如何在部署在不同群集节点上的两个相同actor之间保持状态? (akka.net)

时间:2015-11-09 05:43:46

标签: c# akka.net akka.net-cluster

如果我有如下设置,请说我将3个节点连接到群集,并且我使用循环池。

var worker = cluster.ActorOf(Props.Create<Worker>().WithRouter(
                 new ClusterRouterPool(
                     new RoundRobinPool(5),
                     new ClusterRouterPoolSettings(30, true, 1))), "worker");

&#34;工人&#34;只需记住它处理过的消息数量如下所示

public class Worker : TypedActor, IHandle<int> {
readonly List<int> processed;

public Worker()
{
    processed = new List<int>();
}

public void Handle(int message)
{
    System.Threading.Thread.Sleep(new Random().Next(1000, 2000));
    processed.Add(message);
    Console.WriteLine("WORKER ({0}) [{1}:{2}], processed: {3}", message, Context.Self.Path, Cluster.Get(Context.System).SelfUniqueAddress.Address.Port, processed.Count);
}

无论如何都要同步&#34;处理过的List&#34;不同群集节点上的不同actor之间?这是akka.net.cluster.sharding最终会做的事吗?或者我在做一些完全没有意义的事情?

1 个答案:

答案 0 :(得分:4)

一般来说,您的问题似乎最接近JVM akka eventuateddata插件提供的内容。当你有演员在同一条数据上工作时,每种情况下的一般副作用是最终的一致性 - 因为你的状态是共享的#39;在多台机器上工作的许多演员之间,特定时刻的实际状态可能会模糊不清,具体取决于你将采取哪种演员的观点。

目前我还没有听说过.NET上已经完成的生产就绪选项,但Akka.DistributedData - 目前正在开发中 - 将允许您完成任务。它是CRDTs的Akka实现。

CRDT将为您提供的是访问最终一致的数据类型,这些数据类型可以在分布式集群中的不同节点上复制,直到整个应用程序中的总状态简洁为止。在这种情况下,您可以将processed列表替换为GSet,这样您就可以以分布式方式将元素附加到一个数据集。

如果您不想等待,冒险或自行构建CRDT,您可以使用第三方解决方案,例如Riak

PS: Akka.Cluster.Sharding有不同的目的,即自动将你的演员分布在你的集群上 - 即使节点数量发生变化 - 这样特定演员的唯一一个实例就会出现在当前的群集范围。