やあ。Redisの世界へようこそ。
Redisを「ただの高速なキーバリューストア」だと思っているなら、それは非常にもったいない。今日は、Redisが持つ「メッセージングの魔術」、特にストリーム(Streams)とコンシューマーグループの本質について話をしよう。
初心者には少し複雑に見えるかもしれないが、大丈夫。日常の風景に例えて解説するから、肩の力を抜いて読んでほしい。
—
1. 「タスクの割り振り」で考えてみよう
例えば、君がカフェの店長だと想像してほしい。
注文が次々と入ってくる(これがストリームだ)。でも、店員が一人だとパンクしてしまうよね。だから、3人の店員(コンシューマー)を雇って、注文を分担してさばいてもらうことにした。
ここで重要なのは、「同じ注文を二人が同時に作ってしまわないこと」と「誰がどの注文を処理中か把握すること」だ。これをRedisで完璧に実現するのが「コンシューマーグループ」という仕組みなんだ。
—
2. コンシューマーグループを作る(XGROUP)
まずは、注文を管理する「グループ」を作る。店長として「キッチンチーム」というグループを結成するイメージだ。
‘mystream’ という注文リストに対して、’kitchen’ というグループを作成
‘0’ は、これまでの過去の注文もすべて対象にするという意味
XGROUP CREATE mystream kitchen 0 MKSTREAM
- `MKSTREAM`: もしリストがまだ存在しなかったら、自動で作ってあげるという親切なオプションだ。
—
3. 分担して注文を受け取る(XREADGROUP)
次に、店員が注文を取りに行く。ここでは「店員Aさん」が動くとする。
kitchenグループのAさんが、新しい注文(’>’)を1つだけ取得する
XREADGROUP GROUP kitchen A-san COUNT 1 STREAMS mystream >
- `>`: 「まだ誰にも割り当てられていない、新しい注文をちょうだい!」という合図。
- ここが重要: Aさんがこの注文を受け取った瞬間、Redisは「この注文は現在Aさんが処理中だ」とメモを取る(これをPEL: Pending Entries Listと呼ぶ)。
—
4. 処理が終わったら報告する(ACK)
Aさんが無事にコーヒーを作り終えたら、Redisに「完了しました!」と報告する必要がある。これがACK(確認応答)だ。
注文ID(例えば 16788888-0)の処理が終わったことを伝える
XACK mystream kitchen 16788888-0
これを行うと、Redisは「あ、この注文は無事に終わったんだな」と判断して、PELからその注文を削除する。もしACKを忘れると、Redisは「あれ?Aさん、あの注文どうなったの?」とずっと気にし続けることになる。
—
5. なぜこの仕組みが「伝説的」なのか?
Redisのこのアーキテクチャが優れている理由は、「不測の事態への強さ」にある。
もし注文を処理している最中に、店員Aさんが急に倒れてしまったらどうなるか?
Redisには「処理中だけど完了報告が来ていない注文」がリストに残っている。これを利用して、別の店員Bさんが「Aさんの代わりに、期限が過ぎた未完了タスクを僕が引き継ぐよ(XPENDINGやXCLAIM)」といった運用が可能になるんだ。
これを自前でデータベースに実装しようとすると地獄のようなコード量になるが、Redisはコマンドを叩くだけでこれを実現してくれる。
—
まとめ:ここをマスターすれば君はもうRedisの入り口に立っている
今回のポイントを整理しよう。
1. XGROUP: チームを結成する。
2. XREADGROUP: 注文を分担して取り出す(重複は起きない)。
3. XACK: 処理完了を報告してリストから消す。
この3ステップを理解するだけで、君は高負荷なシステムでも「確実にタスクを処理し、誰一人として取りこぼさない」堅牢なバックエンドアーキテクチャを手に入れたことになる。
「Redisは速いから使う」という次元から、「Redisでデータと処理の整合性を守る」という次元へ。ここまでくれば、君も立派なエンジニアだ。
次は、もし店員全員が同時にオフラインになった場合、どうやってタスクを復旧させるか……そんな深い話もいつかできればいいね。何か詰まったら、いつでも聞きに来てくれ。応援しているよ。
コメント