我想在开启集群模式的 Amazon ElastiCache (Redis OSS) 自行设计的集群上使用多键操作。但我收到“请求中的 CROSSSLOT 键无法哈希到同一个槽”错误。
简短描述
当您的键不在同一个哈希槽中时,即使它们存储在同一个节点中,您也会收到以下错误:
“请求中的 CROSSSLOT 键无法哈希到同一个槽”
要在开启集群模式的分片 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
不支持此操作,因为键不在同一个哈希槽中。这两个集合在两个不同的槽中,分别是 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 cluster specification。
以下示例使用 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"
将两个集合哈希到同一个哈希槽后,您可以执行多键操作。