Redis クラスターの複数キーコマンドにおける「CROSSSLOT Keys in request don't hash to the same slot」エラーの修正

intermediate🔴 Redis2026-03-26| Redis Cluster (バージョン 3.0 以降)、任意のモダンなOS (例: Linux, macOS, Windows Subsystem for Linux) で動作し、さまざまな言語のクライアントライブラリ (例: redis-py, StackExchange.Redis, jedis) を使用。

Error Message

CROSSSLOT Keys in request don't hash to the same slot
#redis#クラスター#複数キー#ハッシュスロット#パイプライン

「CROSSSLOT Keys in request don't hash to the same slot」が表示された場合

Redis Cluster を使用していると、突然、複数のキーを扱うコマンドでこのエラーが発生することがあります。


CROSSSLOT Keys in request don't hash to the same slot

このメッセージは通常、複数のキーを対象とする操作を実行しようとしたときに表示されます。MSETMGET、複数の引数を持つ DEL、あるいは MULTI/EXEC トランザクションブロックのようなコマンドは、指定されたキーがすべて同じ Redis Cluster ノード上に存在しない場合に、このエラーを発生させます。これは Redis Cluster の設計における重要な制約であり、正当な理由があって存在します。

何が起きているのか? Redis Cluster のシャーディングを理解する

Redis Cluster は、データを複数のノードにシャーディングすることで、スケーラビリティと高可用性を実現します。これは、キー空間全体を16,384のハッシュスロットに分割することで行われます。キーを保存する際、RedisはCRC16アルゴリズムを使用してそれをハッシュ化します。その結果生成されるハッシュによって、キーがこれら16,384のスロットのどれに属するかが決定されます。クラスター内の各ノードは、これらのハッシュスロットの個別のサブセットを管理します。

問題は、Redis Cluster が複数のキーを扱うコマンドをアトミックかつ効率的に実行する必要があるために発生します。単一のマルチキーコマンド内のキーが異なるノードに分散している場合、クラスターは複数のサーバー間で連携する必要が生じます。

この連携は、レイテンシと複雑さを増大させ、アトミック性の保証を破綻させます。シンプルさと速度を維持するため、Redis Cluster はあるルールを強制します。それは、マルチキーコマンドに関与するすべてのキーは、同じハッシュスロットに属している必要があり、つまり同じノード上に存在する必要がある、というものです。

したがって、たとえ user:1:profileuser:1:settings のように論理的に関連しているように見えるキーであっても、Redis はキー文字列全体をハッシュ化します。それらが偶然同じスロットにハッシュされない限り、それらを対象とするマルチキーコマンドは CROSSSLOT エラーで失敗します。

解決策:ハッシュタグを使用してキーを共存させる

CROSSSLOT エラーは、主にRedisのハッシュタグを使用することで解決できます。ハッシュタグは、キー内の特定の部分文字列で、波括弧 {} で囲まれます。Redis はハッシュタグを含むキーを検出すると、キーのハッシュスロットを決定するために、その波括弧 のコンテンツのみをハッシュ化します。このメカニズムにより、論理的に関連するキーが同じスロットに強制的に配置されます。

例1:問題のあるシナリオ

ユーザーに関する2つのキーがあるとします。


127.0.0.1:6379> SET user:1:profile "John Doe"
OK
127.0.0.1:6379> SET user:1:settings "theme:dark"
OK

次に、MGET でそれらを取得しようとします。


127.0.0.1:6379> MGET user:1:profile user:1:settings
(error) CROSSSLOT Keys in request don't hash to the same slot

これは、user:1:profileuser:1:settings が異なるスロットにハッシュされる可能性が高いため、失敗します。CLUSTER KEYSLOT コマンドを使用してこれを確認できます。


127.0.0.1:6379> CLUSTER KEYSLOT user:1:profile
(integer) 15720
127.0.0.1:6379> CLUSTER KEYSLOT user:1:settings
(integer) 4410

ご覧のとおり、これらは完全に異なるスロットにあります。

例2:ハッシュタグによる修正の適用

これを修正するために、ハッシュタグを使用します。user:1 に関連するすべてのデータを同じスロットに配置したいので、{user:1} が良いハッシュタグになります。


127.0.0.1:6379> SET {user:1}:profile "John Doe"
OK
127.0.0.1:6379> SET {user:1}:settings "theme:dark"
OK

次に、それらのスロットを確認してみましょう。


127.0.0.1:6379> CLUSTER KEYSLOT {user:1}:profile
(integer) 12345
127.0.0.1:6379> CLUSTER KEYSLOT {user:1}:settings
(integer) 12345

素晴らしい!両方のキーが同じスロット(この例ではスロット12345)にハッシュされるようになりました。これで MGET コマンドが機能します。


127.0.0.1:6379> MGET {user:1}:profile {user:1}:settings
1) "John Doe"
2) "theme:dark"

成功です!これは、Redisがハッシュアルゴリズムのために user:1 のみを考慮し、両方のキーが同じノードに配置されることを保証するためです。

ハッシュタグを超えて:その他の考慮事項

- **トランザクション (MULTI/EXEC):** `MULTI/EXEC` を使用してコマンドをグループ化する場合、そのトランザクションブロック内のすべてのキーも同じハッシュスロットを共有する必要があることを忘れないでください。このコンテキストでもハッシュタグは非常に重要です。
- **パイプライン vs. トランザクション:** パイプラインとトランザクションの違いを理解することが重要です。パイプラインは、個々の応答を待たずに、複数のコマンドを一度にRedisに送信するために単にバッチ処理するものです。異なるスロットをターゲットとするコマンドをパイプライン処理することは *可能* です。ただし、そのパイプライン内の *単一のコマンド* がマルチキーコマンドである場合、それらのキーは引き続きハッシュタグを使用して共存させる必要があります。
- **クライアントライブラリ:** ほとんどのスマートな Redis Cluster クライアントは、単一キーコマンドを自動的に正しいノードにリダイレクトします。しかし、マルチキーコマンドの場合、開発者は通常、ハッシュタグを使用してキーが共存していることを確認する責任があります。クライアントライブラリが `CROSSSLOT` エラーを自動的に解決することはありません。

確認手順

修正を確認するには:

- **ハッシュスロットの確認:** まず、`CLUSTER KEYSLOT <key>` を使用して、マルチキーコマンドに関わるすべてのキーのハッシュスロットを確認します。すべてが同じ整数を返すことを確認してください。
- **コマンドの実行:** 次に、新しく構造化されたキーで実際のマルチキーコマンド(例:`MGET`、`MSET`、`DEL`)を実行します。`CROSSSLOT` エラーなしで実行されれば、キーの共存に成功しています。

予防とベストプラクティス(ヒント)

CROSSSLOT エラーを防ぐには、優れたキー設計から始まります。

- **一貫した命名規則:** 最初から明確なキー命名戦略を確立します。ユーザーID、注文ID、セッションIDなど、一般的なエンティティを特定します。これらは、関連するデータの効果的なハッシュタグとして機能します。
- **関連データのグループ化:** 論理的に一緒に属し、マルチキーコマンドやトランザクションによってアクセスされる可能性のあるデータをグループ化するために、常にハッシュタグを使用します。たとえば、`ID=123` のユーザーの場合、`{user:123}:profile`、`{user:123}:cart`、または `{user:123}:last_login` のようなキーを使用できます。
- **過剰なタグ付けの回避:** 無差別に波括弧を追加する衝動に抵抗してください。特定のキーグループに対してマルチキー操作やトランザクションを真に実行する必要がある場合にのみ、ハッシュタグを使用してください。あまりにも多くのキーが限られた数のスロットに強制されると、過剰なタグ付けは不均一なデータ分散につながる可能性があります。
- **早期テスト:** Redis Cluster の新しいデータモデルを設計する際は、開発サイクルの早い段階で `CLUSTER KEYSLOT` とマルチキーコマンドを使用してキーパターンをテストするようにしてください。
- **一般的なハッシュの理解:** Redis はキーの分散に CRC16 ハッシュアルゴリズムを使用しますが、分散システムで作業する際には、ハッシュの概念を広く理解しておくことが常に役立ちます。

Related Error Notes