2

以下のようなセットアップがある場合、3 つのノードをクラスターに参加させ、ラウンド ロビン プールを使用するとします。

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

「ワーカー」は、以下のように処理したメッセージの数を単純に覚えています

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

異なるクラスタ ノード上の異なるアクター間で「処理済みリスト」を同期する方法はありますか? これは akka.net.cluster.sharding が最終的に行うことですか? それとも、まったく意味のないことをしていますか?

4

1 に答える 1

4

一般的に、あなたの問題は、JVM akka eventuateおよびddataプラグインが提供するものに最も近いようです。アクターが同じデータで作業している場合のすべての場合の一般的な副作用は結果整合性です。状態は複数のマシンで作業している多くのアクター間で「共有」されるため、特定の時点での実際の状態がぼやける可能性がありますどの俳優の視点を取るかによって異なります。

現時点では、あなたの場合の .NET ランドでの運用準備完了のオプションについて聞いたことがありませんが、現在開発中のAkka.DistributedDataを使用すると、タスクを完了することができます。CRDTの Akka 実装です。

CRDT が提供するのは、アプリケーション全体で全体の状態が簡潔になる瞬間まで、分散クラスター内のさまざまなノードで複製できる最終的に一貫性のあるデータ型へのアクセスです。その場合、processedリストを置き換えてGSet、要素を1つのデータセットに分散方式で添付できるようにすることができます。

待ちたくない、リスクを冒したくない、または自分で CRDT を構築したくない場合は、Riakなどのサードパーティのソリューションを使用できます

PS: Akka.Cluster.Sharding には別の目的があります。これは、ノードの数が変更された場合でも、クラスター上でアクターを自動的に均等に分散し、特定のアクターのインスタンスが現在のクラスター スコープに 1 つだけ存在するようにすることです。

于 2015-11-09T07:56:35.017 に答える