2つ以上のノードが完全に同期しているシステムを作成することは、定義上不可能です。ただし、実際には、特定の問題に対して機能するように十分に近づく可能性があります。
2つのノードで実行する理由を正確に言うことはできないので、スケーラビリティのためであると想定します。多くのノードがある場合、システムを正しく使用すれば、システムの可用性とフォールトトレラントも向上します。ただし、単一ノードでのみ実行することがわかっていて、マスターが使用できない場合に引き継ぐために他のノードをホットスレーブとして必要とする場合は、問題を単純化できます。
2つの異なるノード上の2つのプロセス間の接続を確立するには、グローバルアドレス指定が必要です(ユーザーID123はpid<123,456,0>です)。一度に実行されているユーザーAに対して実行されているプロセスが1つだけである場合は、ロックが必要であるか、アドレス指定の一意の登録のみを許可する必要があります。また、成長させたい場合は、システムの実行中または停止時に、ノードを追加する方法が必要です。
現在、さまざまなトレードオフを使用して、問題の解決に役立ついくつかのソリューションがすでに存在します。
グローバルモードのgprocを使用すると、特定のキーでプロセスを登録できます(これにより、アドレス指定とロックが可能になります)。これはクラスター全体に分散され、単一障害点はありませんが、リーダー選出(少なくとも最後に確認したとき)は、システムの起動時に使用可能だったノードに対してのみ機能します。新しいノードを追加するには、gen_leaderの実験的なバージョンを使用するか、システムを停止する必要があります。独自のコード内で、2人のプレーヤーが互いに話すだけであることがわかっている場合は、同じノードでそれらを開始できます。
riak_coreを使用すると、riakKVおよびriak検索で使用される十分にテストされ実証されたアーキテクチャの上に構築できます。これは、新しいノードを追加してキーを再配布できるように、キーをバケットにマップします。このメカニズムに接続して、プロセスを移動できます。このアプローチでは、プロセスをどこから開始するかを決定できないため、プロセス間で多くの通信がある場合、これはネットワークを介して行われます。
分散トランザクションでmnesiaを使用すると、トランザクションがコミットされる前にすべてのノードにデータがあることを保証できます。これにより、アドレス指定とロックが分散されますが、これに加えて他のすべてのことを行う必要があります(ロックの解放など)。 )。注:私は本番環境で分散トランザクションを使用したことがないため、それらがどれほど信頼できるかはわかりません。また、分散されているため、遅延が予想されます。注2:たとえば、mnesiaを停止せずに可能である場合は、ノードを追加してテーブルをレプリケートする方法を正確に確認する必要があります。
Zookeper / doozer / roll your ownは、アドレス指定を保存するために使用できる一元化された高可用性データベースを提供します。この場合、自分で登録解除を処理する必要があります。システムの実行中にノードを追加することは、アドレス指定の観点からは簡単ですが、アプリケーションに新しいノードについて学習させ、そこで生成プロセスを開始させるための何らかの方法が必要です。
また、pidにはメッセージを正しいノードに直接送信するのに十分な情報が含まれているため、ノードを保存する必要はありません。
すでに知っているかもしれないクールなトリックとして、pidは( VM内のすべてのデータと同様に)バイナリにシリアル化される場合があります。term_to_binary/1
およびを使用しbinary_to_term/1
て、VM内の実際のpidと、バイナリデータを受け入れるものなら何でも格納できるバイナリとの間で変換します。