クラスターモードが有効な、Amazon ElastiCache の独自設計クラスターでマルチキー操作を使用したいのですが、「CROSSSLOT Keys in request don’t hash to the same slot」というエラーが発生します。
簡単な説明
キーが同じノードに保存されているものの、同じハッシュスロットに配置されていない場合、次のエラーが発生します。
「CROSSSLOT Keys in request don't hash to the same slot」
シャーディングされた、クラスターモードが有効な ElastiCache (Redis OSS) クラスターでマルチキー操作を実装するには、キーを同じハッシュスロットにハッシュ化します。
次のセット例では、myset2 と myset は同じノードにあります。
172.31.62.135:6379> scan 0
1) "0"
2) 1) "myset"
2) "myset2"
ただし、マルチキー操作はサポートされていません。
172.31.62.135:6379> SUNION myset myset2(error) CROSSSLOT Keys in request don't hash to the same slot
キーが同じハッシュスロットにないため、この操作はサポートされていません。これら 2 つのセットは、560 と 7967 という別々のスロットにあります。
172.31.62.135:6379> CLUSTER KEYSLOT myset(integer) 560
172.31.62.135:6379> CLUSTER KEYSLOT myset2(integer) 7967
解決策
方法 1
クラスターモードが有効な Redis クラスターをサポートする Redis クライアントライブラリを使用します。詳細については、Redis のウェブサイトで「Redis クラスターの仕様」を参照してください。
次の例では redis-cli を使用して、別々のシャードにあるスロットからキーを取得します。この場合、CROSSSLOT エラーが発生します。
redis-cli -c -h RedisclusterCfgEndpointRedisclusterCfgEndpoint:6379> mget key1 key2
(error) CROSSSLOT Keys in request don't hash to the same slot
redis-py-cluster を使用して別々のシャードにあるスロットからキーを取得した場合は、正しい出力が得られます。
>>> from rediscluster import RedisCluster>>> startup_nodes = [{"host": "RedisclusterCfgEndpoint", "port": "6379"}]
>>> rc = RedisCluster(startup_nodes=startup_nodes, decode_responses=True,skip_full_coverage_check=True)
>>> print(rc.mget("key1","key2"))
方法 2
クラスターモードが有効なクラスターでマルチキー操作用のキーを作成する際、キーを強制的に同じハッシュスロットに入れます。ハッシュタグを使用すると、キーを強制的に同じハッシュスロットに入れることができます。キーに {...} パターンが含まれる場合、中括弧 { および } に囲まれた部分文字列のみがハッシュ化され、ハッシュスロットを計算します。
同じハッシュスロットにハッシュ化された複数のセットの例を次に示します。{user1}:myset および {user1}:myset2 というキーは、同じハッシュスロットにハッシュ化されます。ハッシュスロットの計算には user1 のみを使用します。
172.31.62.135:6379> CLUSTER KEYSLOT {user1}:myset(integer) 8106
172.31.62.135:6379> CLUSTER KEYSLOT {user1}:myset2
(integer) 8106
172.31.62.135:6379> SUNION {user1}:myset {user1}:myset2
1) "some data for myset"
2) "some data for myset2"
両方のセットを同じハッシュスロットにハッシュ化すると、マルチキー操作を実行できるようになります。