在 Redis(已启用集群模式)ElastiCache 集群上进行多密钥操作时,为什么会出现“CROSSSLOT Keys in request don't hash to the same slot”的错误?

上次更新时间:2020 年 2 月 13 日

在 Amazon ElastiCache for Redis(已启用集群模式)集群上进行多密钥操作时,为什么即使密钥存储在相同节点中,还会出现“CROSSSLOT Keys in request don't hash to the same slot”的错误?

简短描述

发生此错误是因为密钥不仅仅要位于同一节点中,还必须位于相同的哈希槽中。要在分片 Redis(已启用集群模式)ElastiCache 集群上进行多密钥操作,必须将密钥哈希到相同的哈希槽。您可以使用哈希标签将密钥强制放入相同的哈希槽。

在此示例中,下面的“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-py-cluster 网站。

例如,使用 redis-cli 从位于不同分片的槽中获取密钥时,返回 CROSSSLOT 错误:

redis-cli -c -h RedisclusterCfgEndpoint
RedisclusterCfgEndpoint: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"

现在两个集都被哈希到了相同的哈希槽,您可以执行多密钥操作了。


这篇文章对您是否有帮助?

我们可以改进什么?


需要更多帮助?