エラーメッセージRedis ClusterでシンプルなSETやGETコマンドを実行しようとした際、以下のような不可解なレスポンスが表示されたことはないでしょうか。
(error) MOVED 7638 127.0.0.1:7001
アプリケーションのログでは、Redis.Exceptions.ClusterExceptionとして表示されることもあります。これは通常、クラスターの分散アーキテクチャを理解する接続方法ではなく、クラスター内の一つのノードにスタンドアロンインスタンスであるかのように接続した場合に発生します。
なぜこのエラーが発生するのか?Redis Clusterは、すべてのデータを全ノードに保存するわけではありません。代わりに、データをちょうど16,384個のハッシュスロットに分割して保持します。クラスター内の各ノードは、これらのスロットの特定の範囲を担当します。例えば、ノードAがスロット0から5460を担当し、ノードBが5461から10922を担当するといった具合です。
MOVED 7638 127.0.0.1:7001という表示は、Redisによる親切な案内です。これは、*「リクエストされたキーはハッシュスロット7638に属していますが、私はそのスロットを保持していません。127.0.0.1:7001のノードが保持しているので、そちらに問い合わせてください」*と伝えています。
技術的には、これは失敗ではなくリダイレクトの仕組みです。しかし、クライアントがそのマップ(トポロジ)に従う方法を知らない場合、この提案をエラーとして扱ってしまいます。
ステップバイステップの解決策### 1. コマンドライン (redis-cli) での修正デフォルトでは、redis-cliはスタンドアロンモードで動作します。リダイレクトエラーを修正するには、-cフラグを使用して明示的にクラスターモードを有効にする必要があります。
誤った方法:
redis-cli -h 127.0.0.1 -p 7000
127.0.0.1:7000> SET user:101 "John"
(error) MOVED 7638 127.0.0.1:7001
正しい方法:
redis-cli -c -h 127.0.0.1 -p 7000
127.0.0.1:7000> SET user:101 "John"
-> Redirected to slot [7638] located at 127.0.0.1:7001
OK
-cフラグを指定すると、CLIはMOVEDレスポンスに基づいて自動的に正しいノードにジャンプします。これにより、リダイレクトがシームレスに行われます。
2. アプリケーションコードでの修正アプリでこのエラーが発生している場合、スタンドアロン用のRedisクライアントを使用している可能性があります。接続時にクラスターのスロットマップ(トポロジ)を取得できる「クラスター対応(Cluster-aware)」クライアントに切り替える必要があります。
- Python:
redis.Redisからredis.cluster.RedisClusterに切り替えます。- Node.js: 標準クライアントの代わりに、クラスターモード(new Redis.Cluster([...]))でioredisを使用します。- Java: 基本的なJedisクラスではなく、JedisClusterを使用します。- Go: 人気のあるgo-redisパッケージのredis.NewClusterClientを使用します。クラスター対応クライアントは、リダイレクトを内部で処理します。リクエストを送信する前にキーのCRC16ハッシュを計算してスロットを特定するため、最初から正しいノードにアクセスできるようになります。
3. クラスターの健全性を確認する正しいクライアントを使用しているにもかかわらずエラーが解消されない場合は、クラスターのトポロジが同期されていない可能性があります。次のコマンドでスロットの状態を確認してください。
redis-cli -p 7000 cluster nodes
エラーに表示されているノード(例:127.0.0.1:7001)がconnected(接続済み)かつmaster(マスター)とマークされていることを確認してください。ノードが故障し、レプリカが昇格していない場合、そのスロットにアクセスできなくなることがあります。
検証方法以下の手順で修正を確認してください。
redis-cli -cを使用して接続します。-CLUSTER KEYSLOT <あなたのキー>を実行し、キーに割り当てられた特定のスロットを特定します。-SETまたはGETコマンドを実行します。--> Redirected to slot...というメッセージが表示されるか確認します。操作が正常に完了すれば、環境は正しくRedis Clusterプロトコルを処理できています。## エキスパートのアドバイス- シードノード (Seed Nodes): アプリの設定でIPを一つだけ指定するのではなく、少なくとも3つのノードを「シード」ノードとしてリストしてください。起動時に一つのノードがダウンしていても、他のノードからクラスターマップを取得できます。- Docker & NAT: Dockerで実行しており、MOVEDが到達不能な内部IP(172.17.x.xなど)を指している場合は、redis.confのcluster-announce-ipをホストのパブリックIPに設定する必要があります。- CROSSSLOTエラー:MSETなどのマルチキー操作を使用する場合、すべてのキーが同じスロットに存在する必要があります。{user123}:profileや{user123}:settingsのようにハッシュタグを使用して、関連するキーを強制的に同じノードに配置するようにしてください。

