【実務・中級編】 Redis Clusterアーキテクチャ – Redis

Redis Clusterの深淵:ハッシュスロットが導く「スケールの設計思想」

Redisを単なる「高速なKVS」として使っているうちは、まだ初級者だ。
真のエンジニアがRedisを語る時、それは「分散データストアとしての極限の可用性と線形スケーラビリティ」を指す。

今日は、Redis Clusterの心臓部である「ハッシュスロット」の仕組みから、実務で絶対に陥ってはならない落とし穴まで、現場の知見を叩き込む。

—

1. ハッシュスロット:分散の「最適解」

Redis Clusterが16,384個という固定されたスロットを持つ理由は、単なる気まぐれではない。

  • なぜ 16,384 なのか?
  • ノード間通信(Gossipプロトコル)のオーバーヘッドと、データ分散のバランスが最も取れる数値だからだ。1,000ノード程度までなら、ビットマップのサイズも通信量も許容範囲内に収まる。
  • 数学的な美しさ
  • `CRC16(key) mod 16384`。この単純な計算が、クラスタ内のどこにデータがあるかを決定づける。この決定論的なルーティングこそが、中央集権的なプロキシを不要にし、クライアントサイドでの直接アクセスを可能にしている。

【設計の勘所】
「ハッシュタグ `{}` 」を使いこなせ。`user:{100}:profile` と `user:{100}:settings` は、ハッシュタグを使うことで確実に同じスロットに配置される。トランザクションやマルチキー操作が必要なデータは、この仕組みで「論理的な局所性」を強制せよ。

—

2. リシャーディング:止まらない拡張の裏側

「負荷が増えたからノードを追加しよう」――この時、Redis Clusterで行われるのはデータの移動(リシャーディング)だ。

ここでの鉄則は一つ:「移行中も読み書きを止めない」こと。
移行中のキーには `MIGRATING` や `IMPORTING` という状態が付与され、クライアントには `-ASK` リダイレクトが返る。

【実務上の鉄則】
リシャーディングは、ネットワーク帯域とCPUリソースを食う。ピークタイムにリシャーディングを走らせるような愚行は避けろ。ノード追加は、事前に監視ツールで「負荷の低い時間帯」を特定した上で行うのがプロの所作だ。

—

3. 可用性の神話と、実務的な設計パターン

Redis Clusterは「マスター・スレーブ構成」を内包している。自動フェイルオーバーは魔法ではない。

  • Failoverのロジック
  • 半数以上のマスターがノードのダウンを合意(`PFAIL` → `FAIL`)した瞬間に、スレーブがマスターに昇格する。
  • ここで重要なのは、「ネットワーク分断(Split-Brain)」の回避だ。最低でも3マスター、各マスターに1スレーブの計6ノードが、可用性を担保するための最低限の「スタートライン」である。

【堅牢な設計への提言】
「Redis単体で永続化を完璧にしようとするな」。
Redisはあくまで高速なデータストアだ。重要なビジネスデータは必ずRDB(MySQL/PostgreSQL)をSource of Truthとし、Redisには「TTL付きのキャッシュ」あるいは「最新状態の投影」を置く。フェイルオーバーでデータが数ミリ秒飛ぶ可能性を許容できない設計は、Redis以前の問題だ。

—

4. パフォーマンスを殺す「悪手」

コードレビューでよく見かける、システムを崩壊させるアンチパターンを挙げる。

① `KEYS` や `SCAN` の乱用

クラスタ環境で全ノードを横断して `KEYS ` を叩くのは自殺行為だ。`SCAN` を使う場合も、ハッシュスロットを意識してノードごとに叩く必要がある。基本は「インデックス用のキーを別途持つ」のが正解だ。

② クライアントの再接続コスト

悪い例: リクエストごとに接続を確立する
def get_data(key):
r = redis.RedisCluster(startup_nodes=nodes) # 毎回インスタンス生成
return r.get(key)

これでは、接続確立のオーバーヘッドでRedisの高速性は打ち消される。
「コネクションプール」を使い、接続を維持せよ。 クライアントライブラリは、クラスタのトポロジー(スロットマップ)をキャッシュしているはずだ。これを頻繁に再構築させる設計はパフォーマンスを著しく低下させる。

—

最後に:アーキテクトとしての助言

Redis Clusterは非常に強力だが、「複雑性」というコストを支払うことになる。
あなたが開発しているシステムが、本当に「単一Redisのメモリ上限」を超えるのか? 「書き込み負荷が単一マスターの限界を超える」のか?

もし答えが No なら、まずはシンプルな「レプリケーション構成」や「プロキシを用いた構成(TwemproxyやEnvoy)」を検討すべきだ。「必要のない分散」は、システムの障害ポイントを増やすだけの最大の足枷になる。

それでもスケールが必要な時、Redis Clusterはその要求を最高レベルで応えてくれるはずだ。その時、この記事で語った「スロット」と「リシャーディング」の挙動を思い出してほしい。

設計は、妥協ではなく選択の連続だ。健闘を祈る。

コメント

タイトルとURLをコピーしました