Redis Streams:なぜ「ただのメッセージキュー」として使うと地獄を見るのか
Redisを単なるキャッシュやKVSとしてしか見ていないエンジニアが多すぎる。特に`Streams`が登場して以降、Redisは本格的な分散メッセージングの基盤へと進化した。だが、多くの現場で「なぜかデータが消える」「処理が二重に行われる」「メモリが爆発する」という惨状を目にする。
今日は、Redis Streamsを使いこなすための「現場の鉄則」を叩き込む。リファレンスをなぞるだけの解説は不要だろう。アーキテクチャの急所を突く。
—
1. Streamsの正体:順序性と永続性を両立させる「Append-only Log」
Redis Streamsは、単なるキューではない。各エントリが「ID(タイムスタンプ-シーケンス)」を持つAppend-only Logだ。このIDが重要だ。クライアントがIDを指定しない場合、Redisが内部で生成する。
ストリームにログを投入する
MAXLEN ~ 1000 は「約1000件にトリミングしろ」という命令。これがないとメモリを食いつぶす
XADD sensor_logs MAXLEN ~ 1000 temp 25.5 status ok
【設計の急所】
`MAXLEN`を軽視するな。ストリームはメモリに乗る。無制限に追加すれば、遅かれ早かれOOM(Out of Memory)でRedisは停止する。`~`(近似トリミング)はパフォーマンスを優先しつつメモリを保護する現代的な解だ。
—
2. コンシューマーグループの「真の役割」
単一の`XREAD`でデータを読み続けるのは、玩具のようなシステムだけだ。実戦では`XREADGROUP`によるコンシューマーグループが必須となる。
堅牢な処理フローの原則
1. XREADGROUPでメッセージを取得(ACK未完了リストであるPELに入る)
2. ビジネスロジックを実行
3. XACKで処理完了をRedisに報告
この「ACK」の仕組みがあるからこそ、ワーカーが死んでもメッセージが消失しない。
グループ作成($は「これから来るデータのみ対象」という意味)
XGROUP CREATE sensor_logs my_group $ MKSTREAM
読み込み(>は「まだどのコンシューマーにも配送されていない新着」を意味する)
XREADGROUP GROUP my_group consumer_1 COUNT 10 STREAMS sensor_logs >
—
3. 「処理中」の闇:XPENDINGとリカバリ
システム開発で最も恐ろしいのは、「処理途中でワーカーがクラッシュする」ことだ。ここで、`XPENDING`コマンドが救世主となる。
復旧のロジック
「処理完了通知(XACK)が届かないメッセージ」を定期的にチェックし、タイムアウトしたものを別のワーカーに再割り当てする(`XCLAIM`)必要がある。
30秒以上未処理のメッセージを調査
XPENDING sensor_logs my_group – + 10
タイムアウトしたものを強制的に自分のものにする
XCLAIM sensor_logs my_group new_worker 30000
【アーキテクチャの格言】
「メッセージキューに投げたら終わり」ではない。「処理が完了するまでがメッセージキューの責務」だ。`XPENDING`と`XCLAIM`を組み込んだ監視プロセスがないシステムは、いずれ必ず不整合を起こす。
—
4. パフォーマンスを最大化する設計の勘所
- XDELは「削除」ではない:
`XDEL`は物理削除だが、メモリの断片化を招く可能性がある。基本的には`XTRIM`による範囲削除を活用し、物理的なメモリ解放をRedisのメモリ管理に任せるべきだ。
- IDの設計:
IDを外部から指定する場合、単調増加を保証せよ。乱数を入れるとRedis内部のインデックス効率が落ちる。
- 通信のバッチ化:
`XREADGROUP`は可能な限りバッチサイズを調整しろ。ネットワークRRT(往復遅延)は、Redisの処理性能を最も殺す要因だ。
—
5. 最後に:Redisを「信頼できる」基盤にするために
Redis Streamsは強力だが、Kafkaのような「巨大なログの長期保管」には向かない。メモリ容量には物理的な限界があるからだ。
- 短期的な高スループット、低レイテンシが必要ならRedis Streams。
- 数TBのデータを永続化して分析したいならKafka。
この使い分けができないエンジニアは、アーキテクトとして失格だ。Redis Streamsを導入する際は、「このデータはいつ消えるのか」「誰がACKを保証するのか」という問いに対し、設計書に1行の迷いもなく答えられるようになってほしい。
コードは嘘をつかない。だが、設計の甘さは必ずシステム全体を裏切る。次のレビューでは、この辺りの堅牢性を追求した設計を見せてくれ。期待している。
コメント