TL;DR: クイック修正
NOGROUPエラーが発生している場合、まだ作成されていないコンシューマーグループから読み取ろうとしていることを意味します。Redisは、XREADGROUPを呼び出した際にコンシューマーグループを自動的に作成しません。
Redis CLIで以下のコマンドを実行して、ストリームとグループを同時に作成してください:
XGROUP CREATE mystream mygroup $ MKSTREAM
mystream: ストリームの名前です。mygroup: 作成したいコンシューマーグループの名前です。$: これ以降に到着する新しいメッセージのみを読み取るようRedisに指示します(最初から読み取る場合は0を使用します)。MKSTREAM: ストリームがまだ存在しない場合に作成する、オプションですが強く推奨されるフラグです。
根本原因
Redis Streamsを扱う際、データの読み取りには2つの方法があります。XREAD(シンプル、ステートレス)とXREADGROUP(管理型、ステートフル)です。XREADとは異なり、XREADGROUPはどのメッセージが配信され、確認(acknowledge)されたかを追跡するために**コンシューマーグループ(Consumer Group)**を必要とします。
NOGROUP No such consumer group 'mygroup' for key name 'mystream'エラーは、コンシューマーが参加しようとする前に、Redisがグループの明示的な定義を期待しているために発生します。アプリケーションコードがXGROUP CREATEコマンドを正常に実行する前にXREADGROUPを実行しようとすると、操作は失敗します。
このエラーにつながる一般的なシナリオ:
- ストリームは存在するが、グループが作成されていなかった。
- ストリームが削除または期限切れになり、コンシューマーグループのメタデータも一緒に消えた。
- アプリケーションのデプロイスクリプトで初期化ステップが漏れていた。
- 移行やフラッシュの後など、グループが存在しない新しいRedisデータベースを指している。
ステップバイステップの修正方法
1. Redis CLIによる手動作成
ローカル環境やステージング環境でデバッグしている場合、最も早い方法はグループを手動で作成することです。インスタンスに接続して以下を実行します:
# ストリーム 'mystream' に対してグループ 'mygroup' を作成
# '$' はストリームの最後から読み取りを開始することを意味します
XGROUP CREATE mystream mygroup $
ストリーム自体がまだ存在しない場合、上記のコマンドはERR no such keyで失敗します。両方を一度に処理するには、Redis 6.2で導入されたMKSTREAMサブコマンドを使用します:
XGROUP CREATE mystream mygroup $ MKSTREAM
2. プログラムによる実装(冪等なセットアップ)
本番環境では、アプリケーションコード内でこれを処理する必要があります。複数のワーカーが同時に起動する可能性があるため、別のワーカーによって既に作成されている場合にクラッシュすることなく、グループが確実に存在するようにする方法が必要です。
以下は、try-catchブロックを使用した一般的なパターンです(Python/redis-pyの例):
import redis
r = redis.Redis(host='localhost', port=6379, decode_responses=True)
stream_name = "mystream"
group_name = "mygroup"
try:
# グループの作成を試行
r.xgroup_create(stream_name, group_name, id="$", mkstream=True)
except redis.exceptions.ResponseError as e:
if "BUSYGROUP" in str(e):
print("Group already exists, skipping creation.")
else:
raise e
# これで安全に読み取り可能
messages = r.xreadgroup(group_name, "consumer-1", {stream_name: ">"})
BUSYGROUPエラーをキャッチすることで、コードは冪等(べきとう)になり、複数回安全に実行できるようになります。
修正の確認
コンシューマーグループが正しく設定されているか確認するには、XINFOコマンドを使用します。これはストリームのメタデータを検査するための標準的な方法です。
特定のストリームのすべてのグループを確認します:
XINFO GROUPS mystream
以下のような出力が表示されるはずです:
1) 1) "name"
2) "mygroup"
3) "consumers"
4) (integer) 1
5) "pending"
6) (integer) 0
7) "last-delivered-id"
8) "1714550000000-0"
リストが空であるか、グループ名が見当たらない場合、XREADGROUPコマンドは引き続き失敗します。
避けるべき一般的な落とし穴
- 大文字と小文字の区別: Redisのキーとグループ名は、大文字と小文字を区別します。'MyGroup' は 'mygroup' とは異なります。
- データベースインデックス: 複数のデータベース(例:
SELECT 1)を使用している場合は、作成コマンドと読み取りコマンドが同じデータベースインデックスをターゲットにしていることを確認してください。 - ストリームの削除:
DEL mystreamを使用すると、ストリームおよび関連するすべてのコンシューマーグループが削除されます。データをクリアしつつグループを保持する必要がある場合は、代わりにXTRIMまたはXDELを使用してください。

