ØMQを復習
- この名前よく聞くがよく理解もしていない
- ChangeLogを見ると2013年にやっていたらしい。例によって。
- jupyter notebook でも使われているらしい
というわけでちゃんと理解しなおしてみようといつものごとくsafaribooksを立ち上げて見た。
使う本はこちら
https://www.safaribooksonline.com/library/view/zeromq/9781782161042/
スタート
we are living in a connected world だそうな。low-levelでは面倒だが、high-levelではスピードが得られにくい。ちょうど中間が欲しい。そればzmqなのさ、という話。savior (救世主)
とか書いてある。ケンシロウめ。
メッセージキューの話
FIFO queue のこと。priority queue てなんだっけ。あれか、レジカウンターでは時間かかる人を後回しにしたほうが平均待ち時間がってやつ。
キューは大規模な分散システムを実現するためのキーファクターだって書いてある。さらに非同期通信(AIO)。リアルタイムでは必須。シングルスレッド上に複数のタスクをマップできる。JavaScriptっぽい。
よくある例としてWebappの話が次に続く。多量のアクセスに対して、シングルスレッドでは捌き切れず、マルチスレッドではDDoSされるとスレッド爆発してしまう。メッセージキューによるAIOならば(キューマシンを分ければ)これらの問題とともに対故障性にもすぐれるとか。
んでZeroMQ
このメッセージキューを実現する仕組みZeroMQ.sockets on steroids.
分散/平行アプリケーションのためのメッセージングライブラリ.
- 単純さ
- 性能
- Brokerlessデザイン
中央集権でないらしい。(という事は対故障生の話は嘘なんでは…)
というわけで 僕らの友達 HelloWorld
サーバ側:
zmqでは全てはコンテキストから生成されるので、まずはこれを作ってソケットを生成する。
まずは準備して、
#include <zmq.h> int main(int arc, char const *argv[]) { void* context = zmq_ctx_new(); void* respond = zmq_socket(context, ZMQ_REP);
ソケットにアドレスをバインドして、
zmq_bind(respond, "tcp://*:4040"); printf("Starting waiting...\n");
メッセージループに。
for (;;) { wait_for_hello(respond); printf("Received: hello\n"); sleep(1); send_world(respond); printf("send: world\n"); }
終わったら(終わらないけど)後始末。
zmq_close(respond); zmq_ctx_destroy(context); return 0; }
んで肝心の受信の方はこんな感じになる(ちゃんと"hello"か確認してないだろう、というツッコミはちと置いておいて)
void wait_for_hello(void* respond) { zmq_msg_t request; zmq_msg_init(&request); zmq_msg_recv(&request, respond, 0); zmq_msg_close(&request); }
単純にメッセージを作って、ソケットからrecvするだけ。んで終わったらメッセージは捨てる。
んで送信。
void send_world(void* respond) { zmq_msg_t reply; zmq_msg_init_size(&reply, strlen("world")); memcpy(zmq_msg_data(&reply), "world", 5); zmq_msg_send(&reply, respond, 0); zmq_msg_close(&reply); }
同じように、基本的にメッセージを作ってソケットに投げつけるイメージ。メンバ変数というかメッセージのバッファを指定してmemcpyすんのがちとめんどいがそれはCだから
基本こんだけ。
https://github.com/tkuro11/zmqtutorial
まとめ
zmqはソケットを直に使うよりは相当に楽に非同期メッセージキューを実現するライブラリで、基本的に高レベルな操作を使ってかけるが、考え方はこれまでのモデルと大差ないので覚えやすい。ソケットの種類がすごいいっぱいあるけど、これはマルチキャストとかの対Nに対応しているから、といったところかなー。まだぼんやりしている。
次回はその機能てんこ盛りなソケットタイプから request reply の仕組みあたりかな。