跳至内容

如何解决在 ElastiCache (Redis OSS) 自行设计的集群上使用多键操作时收到的 CROSSSLOT 错误?

1 分钟阅读
0

我想在开启集群模式的 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"

将两个集合哈希到同一个哈希槽后,您可以执行多键操作。

AWS 官方已更新 2 年前