ZeroMQ: 複数のEndpointに接続する
ちゃんとドキュメントを読めという話かもしれないが、ZeroMQ のソケットが 複数のEndpointにbind/connectできることを最近知った。そこで、複数のEndpointに対してのbind/connectを 使ったメッセージングのパターンをいくつか考えてみた。
1. ローカル/リモート共用ソケット
同じプロセス内でのソケット間通信をするなら、inproc
を使ったほうが
ローカルループバックに対するtcp
を使うよりも圧倒的に速い。このパターンでは、
一つのソケットに同一プロセスからの接続用のアドレス(ローカル: inproc
)と、
別マシンからの接続用のアドレス(リモート: tcp
)の二つをbindし、接続するソケットの位置
によってconnectするアドレスを使い分ける。これにより、ローカルのソケット間通信はより高速に行われ、また、
受信する側では、ローカルから来たメッセージとリモートから来たメッセージを区別することなく処理を行うことができる。
2. ブロードキャストクラスタ
各ノードでZMQ_PUB
とZMQ_SUB
を一つずつ用意します。
ZMQ_PUB
はbindしてZMQ_SUB
は各ノードのZMQ_PUB
にconnectすると(逆でもたぶんOK)、
ZMQ_PUB
にsendすることで他の全ノードにメッセージが送信されるようになります。
複数のソケットを用意すれば同じことが実現できますが、一つのソケットで複数のEndpointにconnectした方が、
recv/pollするのが一つのソケットで済むので楽になるかと思います。
このパターンを実装するときはZMQ_SUBSCRIBE
を設定するのを忘れずに。
3. P2Pクラスタ
bindとconnectを併用することもできます。このパターンでは、各ノードにZMQ_ROUTER
を一つ用意し、
一つのアドレスに対してbindするのと同時に、他のノードのZMQ_ROUTER
にconnectします。
このように繋ぐことで、ZMQ_ROUTER
のルーティング機能を使えばクラスタ内のどのノードへも
メッセージを送信することができます。ZMQ_ROUTER
同士を繋ぐときはidentityの設定が厄介ですが、
bindする前にZMQ_IDENTITY
を設定し、connectする際にZMQ_CONNECT_RID
を設定しておけば問題ないでしょう。
以上、複数のEndpointへのbind/connectを用いたメッセージングパターンでした。