Why am I getting the "CROSSSLOT Keys in request don't hash to the same slot" error while doing multi-key operations on a Redis (cluster mode enabled) ElastiCache cluster?

Last updated: 2020-02-13

Why am I getting "CROSSSLOT Keys in request don't hash to the same slot" error while doing multi-key operations on an Amazon ElastiCache for Redis (cluster mode enabled) cluster even though the keys are stored on the same node?

Short Description

This error occurs because keys must be in the same hash slot and not just the same node. To implement multi-key operations in a sharded Redis (cluster mode enabled) ElastiCache cluster, the keys must be hashed to the same hash slot. You can force keys into the same hash slot by using hashtags.

In this example, the following sets, "myset2" and "myset," are in the same node:

172.31.62.135:6379> scan 0
1) "0"
2)  1) "myset"
    2) "myset2"

But a multi-key operation isn't supported:

172.31.62.135:6379> SUNION myset myset2
(error) CROSSSLOT Keys in request don't hash to the same slot

This is because the keys aren't in the same hash slot. In this example, the two sets are in two different slots, 560 and 7967:

172.31.62.135:6379> CLUSTER KEYSLOT myset
(integer) 560
172.31.62.135:6379> CLUSTER KEYSLOT myset2
(integer) 7967

Resolution

Method 1

You can use a Redis client library that provides support for Redis (cluster mode enabled) clusters. For more information about Redis clusters, see the redis-py-cluster website.

For example, using redis-cli returns the CROSSSLOT error when used to get keys from slots located in different shards:

redis-cli -c -h RedisclusterCfgEndpoint
RedisclusterCfgEndpoint:6379> mget key1 key2
(error) CROSSSLOT Keys in request don't hash to the same slot

Using the redis-py-cluster to get keys from slots located in different shards returns the correct output:

>>> 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"))

Method 2

When creating keys that are used by multi-key operations on a cluster mode enabled cluster, use hashtags to force the keys into the same hash slot. When the key contains a "{...}" pattern, only the substring between the braces, "{" and "}," is hashed to obtain the hash slot.

For example, the keys {user1}:myset and {user1}:myset2 are hashed to the same hash slot, because only the string inside the braces "{" and "}", that is, "user1", is used to compute the hash slot.

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"

Now that both sets are hashed to the same hash slot, you can perform a multi-key operation.


Did this article help you?

Anything we could improve?


Need more help?