Redis クラスタとレプリケーション(複製)に関するガイダンスです。複数キーの操作用ハッシュタグ(キーをグループ化するための記号)、CROSSSLOT エラーの回避、レプリカからの読み取りによる読み込み負荷の分散について説明します。 次のような場合に使用: シャード化された Redis クラスタ用のキー設計、MGET・SDIFF・パイプライン処理での CROSSSLOT エラーのトラブルシューティング、クラスタ内でのマルチキートランザクション設定、キャッシュ・分析・ダッシュボード用途でレプリカへの読み取りルーティング。
Redis Cluster and replication guidance covering hash tags for multi-key operations, avoiding CROSSSLOT errors, and reading from replicas to scale read-heavy workloads. Use when designing keys for a sharded Redis Cluster, debugging CROSSSLOT errors on MGET / SDIFF / pipelines, configuring a multi-key transaction in a cluster, or routing reads to replicas for caches, analytics, or dashboards.
シャード化された Redis クラスタ(および スタンドアロンのプライマリ/レプリカ構成)における、キーの設計とリード(読み取り)トラフィックのルーティングに関するガイダンスです。クラスタを初めて使うユーザーが陥りやすい 2 つの問題をカバーします。複数キーの操作で発生する CROSSSLOT エラーと、プライマリへの読み取りトラフィック過負荷です。
MGET、SDIFF、トランザクション、またはパイプラインで CROSSSLOT エラーが発生するのをデバッグするRedis クラスタは、キー名をハッシュすることで、キーを 16,384 個のスロット(データの保存場所の分類単位)に分散させます。複数のキーに対する操作(MGET、SDIFF、SUNIONSTORE、トランザクション、パイプライン、複数の KEYS[] を含む Lua スクリプト)では、すべてのキーが同じスロットに存在する必要があります。そうでないと、サーバーが CROSSSLOT エラーを返します。
ハッシュタグはこの問題を解決します。{ と } の間の部分だけがスロット割り当てのハッシュ対象となるため、同じハッシュタグを共有する 2 つのキーは常に同じ場所に配置されます。
# 同じスロット — 複数キー操作が機能
redis.set("{user:1001}:profile", "...")
redis.set("{user:1001}:settings", "...")
redis.lmove("{user:1001}:pending", "{user:1001}:processed", "LEFT", "RIGHT")
# 異なるキー、ハッシュタグなし — クラスタモードで複数キーコマンドが CROSSSLOT エラー
redis.set("user:1001:profile", "...")
redis.set("user:1001:settings", "...")
pipe = redis.pipeline()
pipe.get("user:1001:profile")
pipe.get("user:1001:settings")
pipe.execute() # クラスタで CROSSSLOT エラー
設計のポイント:
{user:1001} など。 {1001} のような単純なタグは避けてください。関連のない複数の領域(purchase:{1001}、employee:{1001} など)が同じスロットに衝突してしまいます。詳しくは references/hash-tags.md を参照してください。
読み取りが書き込みを大きく上回る場合は、読み取りをレプリカにルーティングして、プライマリの処理能力を確保します。これは Redis クラスタ(各シャードが 1 個以上のレプリカを持つ)とスタンドアロン構成(プライマリ/レプリカ)の両方で機能します。
# Redis クラスタ: クライアント側でレプリカからの読み取りを有効化
from redis.cluster import RedisCluster
rc = RedisCluster(host="localhost", port=6379, read_from_replicas=True)
rc.set("key", "value") # → プライマリに書き込み
value = rc.get("key") # → レプリカから読み取られる可能性
クラスタ以外の構成では、2 つのクライアントを各ノードに向けます:
primary = Redis(host="primary-host", port=6379)
replica = Redis(host="replica-host", port=6379)
primary.set("key", "value")
value = replica.get("key")
トレードオフは一貫性です。レプリカは結果整合性(遅延して一貫性が保証される)です。 自分で書き込んだデータを直後にレプリカから読まないでください。また、最新性が必須な用途(残高照会、べき等性の状態管理)にはレプリカ読み取りを使わないでください。キャッシュレイヤー、分析、ダッシュボード、推奨フィードなどが適切な使用例です。
詳しくは references/read-replicas.md を参照してください。
Guidance for designing keys and routing reads in a sharded Redis Cluster (and in standalone primary/replica replication). Covers the two failure modes that bite most new cluster users: CROSSSLOT errors on multi-key operations, and overloading primaries with read traffic.
CROSSSLOT error on MGET, SDIFF, transactions, or pipelines.Redis Cluster distributes keys across 16,384 slots by hashing the key name. Any command that touches multiple keys (MGET, SDIFF, SUNIONSTORE, transactions, pipelines, Lua scripts with multiple KEYS[]) requires all keys to live on the same slot — otherwise the server returns a CROSSSLOT error.
Hash tags force this: the part between { and } is the only thing hashed for slot assignment, so two keys sharing a hash tag always land together.
# Same slot — multi-key ops work
redis.set("{user:1001}:profile", "...")
redis.set("{user:1001}:settings", "...")
redis.lmove("{user:1001}:pending", "{user:1001}:processed", "LEFT", "RIGHT")
# Different keys, no hash tag — CROSSSLOT on multi-key commands in cluster mode
redis.set("user:1001:profile", "...")
redis.set("user:1001:settings", "...")
pipe = redis.pipeline()
pipe.get("user:1001:profile")
pipe.get("user:1001:settings")
pipe.execute() # CROSSSLOT error in cluster
Rules of thumb:
{user:1001}. Avoid bare {1001} — unrelated namespaces (purchase:{1001}, employee:{1001}) would all collide on the same slot.If reads dominate writes, route them to replicas to free primary capacity. Works both in Redis Cluster (each shard has 1+ replica) and in standalone primary/replica replication.
# Redis Cluster: enable replica reads on the client
from redis.cluster import RedisCluster
rc = RedisCluster(host="localhost", port=6379, read_from_replicas=True)
rc.set("key", "value") # → primary
value = rc.get("key") # → may be served by a replica
For non-cluster setups, point two clients at the right nodes:
primary = Redis(host="primary-host", port=6379)
replica = Redis(host="replica-host", port=6379)
primary.set("key", "value")
value = replica.get("key")
The trade-off is consistency: replicas are eventually consistent. Don't read your own writes from a replica; don't use replica reads for anything that requires strict freshness (financial balances, idempotency state). Good fits: cache layers, analytics, dashboards, recommendation feeds.
See references/read-replicas.md.
原文・著作権は Anthropic および各プラグイン作者に帰属します。日本語訳は Claude API による自動翻訳です。