Edited at

Redisのpub/sub機能

More than 1 year has passed since last update.

RedisはNoSQLのデータストアとして有名ですが、もう1つの機能として、「pub/sub機能」を持っています。もはやSQLと比較するような機能ですらないのですが、軽くまとめてみます。


pub/subとは

JavaScriptをやっているとイメージしやすいと思うのですが、onclickに直接イベントを書いてしまうとイベントが1つしか設定できなくなってしまいます。

一方で、addEventListenerを使えば複数イベントをセットできますし、イベントをトリガする側ではイベントがいくつついているかも気にせずに、まとめて発生させることができます。このようにして、「イベントを起こす側」と「イベント処理を行う側」を分離するのがpub/subモデルです。


Redisでのpub/sub

まず、受信側がSUBSCRIBE チャンネル名というコマンドをRedisに投げます。ふつうのRedisコマンドは、繋いで結果が帰ってきたらそれで終わりですが、SUBSCRIBEコマンドは一度発行するとRedisにつながったままとなります(この状態ではSUBSCRIBEと関係ない他のコマンドを投げるべきではない、とのことです)。

このままの状態で、別のクライアントからPUBLISH チャンネル名 内容とすると、SUBSCRIBEしているクライアントにデータが届きます。例えばnode-redisでは.on('message')で届いたものを受け取ることができます。

もちろん、おなじRedisサーバにつなげればpub/subはプロセスや言語の壁を超えて自由に行なえますので、多言語・プロセスな環境下で要素をつなぐのにもピッタリです。


注意点



  • SUBSCRIBE側では他の命令を流すのが適当でないという都合上、接続プールに巻き込まれないように注意する必要があります(PUBLISH側は特に問題ありません)。


  • SUBSCRIBE側は非同期で来るメッセージを受け取れる構造である必要があります(Node.jsや別スレッドで処理するなど)。PHPで処理するのはややこしいかもしれません。

  • 即時のメッセージ配信のため、誰もSUBSCRIBEしていなければPUBLISHは闇に消えてしまいます(送ること自体は可能です)。

  • Redisのデータベースにある、(SELECTで選ぶ)データベース番号は、pub/subには影響しません。同じサーバで複数のpub/subを行う場合、(データベース番号ではなく)チャンネル名を変える必要があります。