Redis Pub/Subの「甘い罠」と、現場で生き残るためのアーキテクチャ設計
RedisのPub/Sub機能は、あまりにシンプルだ。`PUBLISH`して`SUBSCRIBE`する。数行のコードでリアルタイムなメッセージングが完成する。
だが、勘違いしないでほしい。「手軽に動く」ことと「プロダクション環境で信頼できるシステムである」ことは、銀河系ほども離れた距離にある。
今日は、Redis Pub/Subを安易に採用して地獄を見たエンジニアを救うため、そしてこれから設計する君たちが泥沼に足を踏み入れないために、アーキテクトの視点から「真実」を叩き込む。
—
1. Pub/Subの「本質」を見極める
RedisのPub/Subは、「火を放って終わり(Fire and Forget)」の仕組みだ。これには決定的なトレードオフがある。
- 永続性ゼロ: メッセージはどこにも保存されない。受信者が接続していなければ、そのメッセージは永遠に消滅する。
- バッファリングなし: 送信側の速度が受信側の処理能力を超えた場合、Redisはメモリを圧迫し、最終的にはバッファ溢れ(`client-output-buffer-limit`)でコネクションを切断する。
つまり、Pub/Subは「データが欠落しても、システム全体が崩壊しない」という前提条件がある場所でしか使ってはいけない。例えば、ダッシュボードのライブ更新や、チャットの「入力中…」通知などが適任だ。逆に、決済処理や注文の確定通知にこれを使ってはいけない。その瞬間、君のキャリアは終わる。
—
2. 堅牢な設計のために知るべき「3つの鉄則」
現場で運用するなら、以下の3点は設計レビューの通過点だ。
① 「プッシュ型」の限界とクライアントの状態管理
クライアント(受信者)が一時的に切断された際、復帰後に「見逃したメッセージ」を再取得する仕組みはRedis標準には存在しない。
もし「取りこぼしが許されない」要件があるなら、Redis Streams(`XADD`/`XREADGROUP`)を選択せよ。Streamsはオフセット管理が可能で、永続化もできる。Pub/Subはあくまで「リアルタイム性重視」の用途に限定する。
② メモリとネットワーク帯域の制約
高頻度で膨大なメッセージを流すと、RedisのネットワークI/Oが飽和する。Pub/SubはRedisのメインスレッドを占有しないが、出力バッファを埋め尽くすと他のクライアントまで巻き添えを食う。
- 対策: 送信するデータは最小限のIDやポインタのみに留め、詳細データは別途データベースやRedisのハッシュ型から取得させる「アンチ・パターン」を避けろ。
③ クライアント側の実装(接続断のケア)
Redisのクライアントライブラリは、Pub/Subモードに入ると他のコマンドを受け付けなくなる。
悪い例: 接続が切れたらそのまま放置
pubsub = redis.pubsub()
pubsub.subscribe(‘chat_channel’)
良い例: 切断を検知し、即座に再サブスクライブするループを構築する
while True:
try:
for message in pubsub.listen():
process(message)
except redis.ConnectionError:
# 再接続ロジックを必ず実装すること
reconnect()
この「再接続時のチャネル再購読」を忘れると、深夜の障害対応で泣くことになる。
—
3. 実務で「Pub/Sub」を正しく使うための構成例
マイクロサービス間通信での利用を想定した場合、以下のようなパターンが推奨される。
- イベント通知の集約:
サービスAで起きたイベントをRedis Pub/Subに投げ、複数のワーカーが購読してキャッシュのクリアやログ収集を行う。
- 「Pub/Sub + キャッシュ」のハイブリッド:
「通知はPub/Subで行うが、状態の整合性は常にDBを正とする」という設計だ。
送信側(Publisher)
重要なのは、ペイロードを軽量に保つこと
PUBLISH user:123:updates ‘{“action”: “profile_updated”, “timestamp”: 1678901234}’
受信側(Subscriber)
クライアントは受信したJSONからIDを抽出し、
必要なデータのみをDBやメインキャッシュからフェッチする
—
最後に:エンジニアとしての矜持
RedisのPub/Subを設計する際、自分にこう問いかけてみてほしい。
「もし今、このメッセージが消えても、システムは明日には自己修復できるか?」
Yesと言えるなら、Redis Pub/Subは君にとって最高の武器になる。
Noなら、即座にRedis Streamsに切り替えるか、Kafkaのような本格的なメッセージキューの導入を検討すべきだ。
ツールに愛されるのではなく、ツールを支配せよ。アーキテクチャの選択に「なんとなく」は許されない。君たちの設計が、堅牢で美しいものであることを期待している。
コメント