Redisによるパブリッシュ・サブスクライブとタスクキューの実装

Redisのパブリッシュ・サブスクライブ(pub/sub)は、メッセージ送信者(publisher)がチャンネルにメッセージを送信し、そのチャンネルを購読している受信者(subscriber)がリアルタイムでメッセージを受け取る通信モデルです。クライアントは複数のチャンネルを同時に購読可能です。

例えば、チャンネル redisChat を購読するには以下のようにします:

redis 127.0.0.1:6379> SUBSCRIBE redisChat

Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "redisChat"
3) (integer) 1

別のクライアントからこのチャンネルにメッセージを送信すると、購読中のクライアントに即座に配信されます:

redis 127.0.0.1:6379> PUBLISH redisChat "Redis is a great caching technique"
(integer) 1

redis 127.0.0.1:6379> PUBLISH redisChat "Learn redis by example"
(integer) 1

購読側の出力例:

1) "message"
2) "redisChat"
3) "Redis is a great caching technique"

1) "message"
2) "redisChat"
3) "Learn redis by example"

主なパブリッシュ・サブスクライブコマンド

コマンド説明
PSUBSCRIBE pattern [...]パターンにマッチする複数のチャンネルを購読
PUBSUB subcommand [...]パブリッシュ/サブスクライブシステムの状態を確認
PUBLISH channel message指定チャンネルにメッセージを送信
PUNSUBSCRIBE [pattern [...]]パターンベースの購読を解除
SUBSCRIBE channel [...]1つ以上のチャンネルを購読
UNSUBSCRIBE [channel [...]]指定チャンネルの購読を解除

Redis pub/sub と ActiveMQ の比較

  • ActiveMQ は AMQP、MQTT、Stomp などのプロトコルおよび JMS 仕様をサポートするが、Redis はこれらの標準プロトコルをサポートしない。
  • ActiveMQ はメッセージの永続化を提供するが、Redis の pub/sub はメッセージを保持せず、購読者がいない場合や接続中にのみ配信され、それ以外は破棄される。
  • ActiveMQ はトランザクションや再送機能によりメッセージの信頼性を保証するが、Redis にはそのような保証機構がない。

したがって、高度なメッセージング機能が必要ない場合は、既存の Redis インフラ上でシンプルな pub/sub を利用する方が効率的である。

リストを使ったタスクキューの実装

Redis のリスト型(双方向リンクリストで実装)を利用して、シンプルなタスクキューを構築できる。プロデューサーは LPUSH でキューにタスクを追加し、コンシューマーは RPOP(または LPOP)でタスクを取り出す。

127.0.0.1:6379> LPUSH job_queue "process_order_123"
(integer) 1

127.0.0.1:6379> LPOP job_queue
"process_order_123"

空のキューに対してポーリングを避けるため、BLPOP を使用してブロッキング待ちが可能:

127.0.0.1:6379> BLPOP job_queue 0
# → キューに要素が追加されるまでブロック

# 別セッションで:
127.0.0.1:6379> LPUSH job_queue "urgent_task"
(integer) 1

# 元のセッションが即座に返す:
1) "job_queue"
2) "urgent_task"

優先度付きキューの実現

BLPOP(または BRPOP)は複数のキーを引数に取ることができ、いずれかのリストに要素がある場合、左から最初に見つかったリストから要素を取得する。この特性を利用して、優先度の高いキューを左側に配置することで、優先度付き処理を実現できる。

127.0.0.1:6379> LPUSH high_priority "critical_alert"
(integer) 1
127.0.0.1:6379> LPUSH normal_queue "routine_job"
(integer) 1

127.0.0.1:6379> BRPOP high_priority normal_queue 0
1) "high_priority"
2) "critical_alert"

127.0.0.1:6379> BRPOP high_priority normal_queue 0
1) "normal_queue"
2) "routine_job"

タグ: redis pubsub task-queue message-queue BLPOP

8月28日 01:40 投稿