エラーの理解
単純なコマンドを実行しようとした際に (error) CLUSTERDOWN と表示されることほど、もどかしいことはありません。このエラーは、Redis クラスターがデータの整合性を保証できるほど健全ではないと判断し、読み書きの受け付けを停止したことを意味します。
主な原因
Redis が CLUSTERDOWN 状態になる理由は、主に2つの特定の原因によります。
- クォーラム喪失: マスターノードの過半数がダウンした場合に発生します。例えば、6ノード構成(マスター3、レプリカ3)で2つのマスターが同時にオフラインになると、残りのマスターは過半数に達することができず、データの不整合を防ぐために操作を停止します。
- 未割り当てのハッシュスロット: Redis はデータを正確に 16,384 個のハッシュスロットに分割します。マスターとそのレプリカの両方が故障したことが原因で、1つでもスロットがアクティブなノードにホストされていない場合、デフォルトでクラスター全体がシャットダウンします。
これらの障害は、ネットワーク分断、複数のラックにまたがる突然の停電、または可用性ゾーン全体に影響を与えるクラウドプロバイダーの障害が原因で発生することがよくあります。
ステップバイステップ復旧ガイド
ステップ 1: クラスターの状態を確認する
まず、疎通確認ができる任意のノードに接続します。クラスター側から見た障害の状況を把握する必要があります。以下のコマンドを実行してください。
redis-cli -h <node-ip> -p 6379 CLUSTER NODES | grep fail
これにより、fail または fail? とマークされたノードが抽出されます。リストにマスターノードの半分以上が含まれている場合、クォーラム喪失が確認されたことになります。
ステップ 2: 欠落したノードをオンラインに戻す
最も早い解決策は、単に元のプロセスを復活させることです。サーバーが再起動した、あるいはサービスがクラッシュした場合は、故障したマシンで Redis を再起動してください。
# 停止したサーバー上で実行
sudo systemctl start redis-server
# またはカスタム設定を使用している場合
redis-server /etc/redis/redis.conf
ノードが再参加すると、自動的に同期が始まります。ノード間のハンドシェイクが完了してから数秒以内に CLUSTERDOWN 状態は解消されるはずです。
ステップ 3: CLI によるクラスターの修復
クラウドインスタンスが削除されたり、ディスクが故障したりして、ノードが完全に失われることがあります。古いノードを復旧できない場合は、そのスロットを生存しているノードに再割り当てする必要があります。健全なノードから修復ユーティリティを実行します。
redis-cli --cluster fix <healthy-node-ip>:6379
このツールは 16,384 個のスロットをスキャンし、孤立したスロットを特定します。残りのマスターへの再バインドを許可するか尋ねられるので、yes と入力して進めてください。これにより、ダウンしたノードを無視してクラスターが修復されます。
ステップ 4: 「最終手段」のリセット
クラスターのメタデータが修復不可能なほど破損し、--cluster fix が失敗する場合は、ノードをリセットする必要があるかもしれません。警告: これによりクラスター構成が消去され、データ損失につながる可能性があります。
到達可能なすべてのノードで以下を実行し、スタンドアロンインスタンスに戻します。
redis-cli CLUSTER RESET HARD
この操作の後、環境を初めて構築するときと同様に、再度 --cluster create コマンドを実行する必要があります。
ステップ 5: 可用性設定の調整
一部のデータが欠落していてもクラスターをオンラインに保ちたい場合は、スロットカバー率の厳格さを変更できます。これは、100% のデータ整合性よりも可用性が重要なキャッシュシナリオなどで有効です。
redis-cli CONFIG SET cluster-require-full-coverage no
この変更を再起動後も維持するには、redis.conf ファイルに cluster-require-full-coverage no を追加してください。
修正の確認
エラーが止まったからといって、修復されたと思い込まないでください。以下の3つのチェックを実行してください。
- ステータスの確認:
redis-cli CLUSTER INFO | grep cluster_state(okと表示されること) - カバー率の確認:
redis-cli --cluster check <ip>:6379(All 16384 slots coveredと表示されること) - トラフィックのテスト:
redis-cli SET health_check 1を実行
予防策
- 10000番ポートのルール: ファイアウォールで基本ポート (6379) とクラスターバスポート (16379) の両方の通信を許可してください。バスポートが使えないと、ノード間での「投票」ができず、誤ったクォーラム失敗を引き起こします。
- タイムアウトの延長: 高負荷時に
CLUSTERDOWNが頻発する場合は、設定のcluster-node-timeoutを 30000ms (30秒) に増やして、一時的なネットワーク遅延に対応できるようにします。 - 奇数台のマスター: 常に少なくとも3台のマスターノードを使用してください。これにより、スプリットブレイン発生時に明確な過半数を確保できます。

