简体   繁体   中英

How do I persist states between two same actors deployed on different cluster node? (akka.net)

If I have a setup like below, let's say I'll have 3 nodes joined to a cluster, and I use round robin pool.

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

The "worker" simply remembers how many messages it has processed like below

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);
}

Is there anyway to synchronize the "processed List" between different actors on different cluster nodes? Is this something that akka.net.cluster.sharding will eventually do? Or am I doing something which totally makes no sense?

In general your problem seems to be the closest to what JVM akka eventuate and ddata plugins offer. General side effect in every case when you have actors working on it on the same piece of data is eventual consistency - since your state is 'shared' between many actors working on the multiple machines, the actual state at particular point it time may be blurred and will differ depending on which actor's point of view will you take.

At the moment I haven't heard about any finished production ready options on .NET land for your case, but Akka.DistributedData - which is currently under development - will allow you to complete your task. It's a Akka implementation of CRDTs .

What CRDTs will give you, is the access to an eventually consistent data types that can be replicated over different nodes in distributed cluster up to the moment, when total state is concise in whole application. In that case you could replace your processed list to GSet which would allow you to attach your elements to one data set in distributed fashion.

If you don't want to wait, take a risk or build CRDT on your own, you could use third-party solutions like Riak .

PS: Akka.Cluster.Sharding has a different purpose, which is to automatically distribute your actors evenly on your cluster - even when number of nodes changes - so that the only one instance of specific actor will be present in the current cluster scope.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM