2017-05-04 5 views
2

シードとクライアントプロセスを持つakka.netクラスタを作成する2つのコマンドラインプロジェクトを持つソリューションがあります。シードはクラスタを開始し、次に、インターフェイス "IHasRouting"を実装するすべてのメッセージに対してハッシュマッピングを実行する整合性のあるハッシュクラスタルータをインスタンス化します。したがって、(シードまたはクライアントからの)IHasRoutingメッセージは、そのメッセージのハッシュのルート上のシードに終わるはずです。クラスタ化された一貫性のあるハッシュプールで同じマッピングの新しいルートを作成

プロジェクトは正常に開始され、クラスタはエラーなしで形成されます。シードとクライアントの両方がルータをインスタンス化します。シードとクライアントからのすべてのメッセージは同じ「VolumeId」を持つため、シードの同じルートに移動する必要があります。 BUTクライアントノードからのメッセージは、シードのメッセージの新しいルートになります。

  • アンIActorRefが、それは、そのノード内の俳優がルータにメッセージを送信する各ノードで終了する必要がありますrepresting:一貫性のあるハッシュクラスタ・ルータの

    私の理解では、ということです。

  • ルータのインプレッションは、各ノードで同じで、同じアクター名を持つ必要があります。
  • ルータへのすべてのメッセージは、IConsistentHashまたはルータインスタンスが同じハッシュを持つすべてのメッセージは一つだけrouteeに到着すると、それは常に同じroutee
  • Aになります「WithHashMapping()」
  • を持っている必要があります実装する必要がありますルートは複数のハッシュを取るかもしれない

私は一貫性のあるハッシュクラスタルータがどのように動作すべきか、そして多くのデバイスがルータタイプを正しく使用しているように見えると信じています。 。 助けてください!そうすれば、私は完全なソリューションを提供することができます。

ルータを作成するコード:

system.ActorOf(
    new ClusterRouterPool(
     local: new ConsistentHashingPool(nrOfInstances: 1) 
      .WithHashMapping(m => (m as IHasRouting)?.Company?.VolumeId ?? throw new Exception("no routing!")), 
       settings: new ClusterRouterPoolSettings(
        100, 
        100, 
        allowLocalRoutees: allowLocalRoutees, //true if the node role is a Seed 
        useRole: "Seed")) 
        .Props(Props.Create(() => new CompanyDeliveryActor())), "company-router"); 

私はルータへのメッセージのために必要とされる、「当社」クラスを持っています。すべてのVolumeIdはこのテストで同じです。

public class Company 
{ 
    public readonly Guid CompanyId; 
    public readonly Guid VolumeId; 
    public readonly string CompanyName; 
    public Company(Guid companyId, Guid volumeId, string companyName) 
    { 
     this.CompanyId = companyId; 
     this.VolumeId = volumeId; 
     this.CompanyName = companyName; 
    } 
} 

ルータマッピングによって使用さIHasRoutingインタフェース:ルータに送信することができる

public interface IHasRouting 
{ 
    Company Company { get; } 
} 

例えばメッセージクラス:

public class GetTripsMessage : IHasRouting 
{ 
    public Company Company { get; private set; } 
    public GetTripsMessage(Company company) 
    { 
     this.Company = company; 
    } 
} 

そして最後にあるCompanyDeliverActorルータのルートごとにインスタンス化されます。

public class CompanyDeliveryActor : ReceiveActor 
{ 
    private readonly Dictionary<Guid, IActorRef> companyManagers = new Dictionary<Guid, IActorRef>(); 
    private readonly Guid instanceid = Guid.NewGuid(); 

    public CompanyDeliveryActor() 
    { 
     this.Receive<GetTripsMessage>(m => this.RouteCompanyMessage(m, m.Company)); 
     this.Receive<SetTripsMessage>(m => this.RouteCompanyMessage(m, m.Company)); 
    } 

    private void RouteCompanyMessage(object m, Company company) 
    { 
     //placing a watch here shows that this.instanceid is different for messages from the client. 

     if (!this.companyManagers.TryGetValue(company.CompanyId, out var manager)) 
     { 
      manager = Context.ActorOf(Props.Create(() => new CompanyManagerActor())); 
      this.companyManagers[company.CompanyId] = manager;     
     } 

     manager.Tell(m, Context.Sender); 
    } 
} 

ありがとうございました。

答えて

0

ActorOfを呼び出すと、実際に現在のクラスタノードに新しいアクターインスタンスが作成されています。プールルーターの場合、新しいルーターを作成すると、ルートアクターの新しいプールも作成されます。これは他のノードを介してディスパッチされる可能性があります。つまり、ActorOfを2回(クライアントノードに1つ、シードノードに1つ)呼び出すと、2つの別々のアクタープールが表示されます。

  1. これを解決する最も簡単な方法は、単純に、ルータのプールは一度だけインスタンス化することです - それは、クラスタノード間でrouteesのプールを派遣しましょう - とノードを介して、あなたのすべての要求を転送し、クラスタへのエントリ・ポイントとして機能します。他のノードをフェールオーバーとして構成して、エントリノード内のそのタスクを再試行することができます。
  2. また、クラスタメッセージルーティングを使用しているかどうかによって、Distributed Pub/Subまたはcluster shardingのいずれかを使用することもできます。
+0

ありがとうございます - 私の理解は間違っています。 IActorRefが1つしか存在していないことと、分散のためにクラスタ一貫性のあるhash-pool-routerにメッセージを送信したい他のすべてのアクター(おそらく他のノード上)に渡されるべきであることは分かりませんでした。 –

+0

これはあなたに他のより高度なオプションがある理由です。なぜあなたの正確なユースケースがわからないのですが、間違って一貫してハッシュルータを選ぶことが多いのですが、実際に必要なのはクラスタシャーディングです(私が回答したブログ記事を読んでください)。 – Horusiath

0

調査の結果、clustered-consistent-hash-routerに関する私の理解が間違っていることに同意します。私は今、ルータを表すIActorRefをクラスタの他の部分に伝える必要があることを理解しています。これは、ClusterSingltonまたは(場合によっては)分散pubサブメカニズムを介して達成されるかもしれません。メカニズムは、ノードまたはアクタが「失われ」、新しいアクタ(新しいルートを含む)がインスタンス化され、新しいアクタが以前の参照を持つクラスタ内のすべてのアクタに通信される状況を処理する必要があります。

私はクラスタシャーディングのアプローチを検討しており、そのアプローチで得られている技術的な問題点についてもう1つ質問します。

+0

新しい質問は[cluster-sharding-client-with-host-with-host]です(http://stackoverflow.com/questions/43829788/cluster-sharding-client-not-connecting-with-host) –

関連する問題