我想在開啟了叢集模式的Amazon ElastiCache (Redis OSS) 自行設計的叢集上使用多金鑰作業。但我收到「請求中的 CROSSLOT 金鑰未根據雜湊值對應到相同插槽」錯誤。
簡短描述
當您的金鑰不在同一個雜湊槽中時,即使它們儲存在同一個節點中,您也會收到以下錯誤:
「請求中的 CROSSLOT 金鑰未根據雜湊值對應到相同插槽」
若要在已開啟叢集模式的碎片 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 叢集規範。
以下範例使用 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"
將兩個集合根據雜湊值對應到相同雜湊槽,即可執行多金鑰作業。