Redis 集群批量删除key报错 CROSSSLOT Keys in request don‘t hash to the same slot

Redis 集群报错 CROSSSLOT Keys in request don't hash to the same slot 的原因及解决方案

1. 错误原因

在 Redis 集群模式下,数据根据 哈希槽(Slot) 分散存储在不同的节点上(默认 16384 个槽)。当执行涉及多个 key 的命令(如 DEL key1 key2MGETMSET 等)时,这些 key 必须属于同一个哈希槽,否则会触发此错误。

示例场景

bash 复制代码
# 错误:key1 和 key2 属于不同槽
127.0.0.1:6379> DEL key1 key2
(error) CROSSSLOT Keys in request don't hash to the same slot

2. 根本原因
  • Redis 集群要求跨 key 操作的原子性,而不同槽的 key 可能位于不同节点,无法保证原子性。
  • 影响命令:DELMGETMSETSUNION 等多 key 操作。

3. 解决方案
方案 1:强制所有 key 使用相同哈希槽(推荐)

通过 哈希标签(Hash Tag) 强制让多个 key 分配到同一个槽。
方法 :用 {} 包裹 key 的相同部分,Redis 仅根据 {} 内的内容计算槽。

示例

bash 复制代码
# 正确:key1 和 key2 使用相同的哈希标签
127.0.0.1:6379> DEL user:{100}:name user:{100}:age
(integer) 2  # 成功删除
方案 2:单 key 操作替代多 key 操作

将批量操作拆分为单个命令:

bash 复制代码
# 原始错误命令
DEL key1 key2

# 改为单 key 操作
DEL key1
DEL key2
方案 3:使用 -c 参数让 redis-cli 自动重定向

redis-cli 中启用集群模式(-c),自动重定向到正确节点:

bash 复制代码
redis-cli -c -h <host> -p <port> DEL key1 key2

但此方法仍可能因跨槽失败,仅适用于 key 巧合在同一节点的情况。

方案 4:Lua 脚本保证原子性

Lua 脚本在集群中会被整体发送到同一个节点执行:

lua 复制代码
-- delete_keys.lua
redis.call('DEL', KEYS[1])
redis.call('DEL', KEYS[2])

执行:

bash 复制代码
redis-cli -h <host> -p <port> --eval delete_keys.lua key1 key2
方案 5:遍历所有节点删除(适用于模糊匹配)

若需删除通配符匹配的 key(如 index_kline*),需遍历所有节点:

bash 复制代码
# 获取集群所有主节点
NODES=$(redis-cli -h <host> -p <port> cluster nodes | grep master | awk '{print $2}' | cut -d '@' -f1)

# 逐个节点执行 SCAN + DEL
for node in $NODES; do
    redis-cli -h ${node%:*} -p ${node#*:} --scan --pattern "index_kline*" | xargs -n 100 redis-cli -h ${node%:*} -p ${node#*:} DEL
done

4. 如何避免此问题?
  1. 设计 key 时使用哈希标签
    例如 order:{123}:itemsorder:{123}:status 保证相同订单的 key 在同一个槽。

  2. 避免跨槽的多 key 操作
    优先使用单 key 命令或事务(MULTI/EXEC)。

  3. 查询 key 的槽分布

    bash 复制代码
    redis-cli -h <host> -p <port> CLUSTER KEYSLOT "your_key"

5. 总结
场景 解决方案
批量删除固定 key 使用哈希标签({}
模糊删除通配符 key 遍历所有节点 + SCAN
需要原子性操作 Lua 脚本
临时修复 单 key 操作或 -c 模式

关键点 :Redis 集群的多 key 操作必须满足 同槽规则,设计 key 时提前规划哈希标签可彻底避免此问题。

相关推荐
rannn_111几秒前
【MySQL学习|黑马笔记|Day3】多表查询(多表关系、内连接、外连接、自连接、联合查询、子查询),事务(简介、操作、四大体系、并发事务问题、事务隔离级别)
数据库·笔记·后端·学习·mysql
小云数据库服务专线33 分钟前
GaussDB 约束的语法
数据库·sql·gaussdb
IT邦德39 分钟前
少林寺用什么数据库?
数据库
姜不吃葱1 小时前
【力扣热题100】哈希——最长连续序列
算法·leetcode·哈希算法
Fireworkitte2 小时前
Couchbase 详解
数据库
涛思数据(TDengine)2 小时前
时序数据库厂商 TDengine 发布 AI 原生的工业数据管理平台 IDMP,“无问智推”改变数据消费范式
大数据·运维·数据库·人工智能·tdengine
想你依然心痛2 小时前
Spark大数据分与实践笔记(第五章 HBase分布式数据库-04)
大数据·数据库·分布式
小王子10242 小时前
Django模型迁移指南:从命令用法到最佳实践
数据库·mysql·django·迁移回滚
l_c-l-o-u-d_22 小时前
第十九周-文档数据库MongoDB、消息队列和微服务
数据库·redis·mongodb
数据狐(DataFox)2 小时前
大数据集分页优化:LIMIT OFFSET的替代方案
数据库·sql·oracle