590 字
3 分钟
Redis Cluster 为什么会报 CROSSSLOT?Hash Tag 怎么用?
Redis Cluster 将 Key 映射到 16384 个槽位。多 Key 原子命令、事务和 Lua 脚本通常要求相关 Key 位于同一槽;跨槽时可能收到 CROSSSLOT。在同一主节点上不等于在同一槽,槽位才是这类检查的边界。
Hash Tag 怎样影响槽位?
通常整个 Key 参与槽位计算;存在符合规则的非空花括号片段时,只对其中内容计算。例如:
SET order:{1001}:status createdSET order:{1001}:stock 10MGET order:{1001}:status order:{1001}:stock两个 Key 的 Tag 都是 1001,因此属于同一槽。其他字符仍使 Key 名不同,Tag 只是决定分片位置。只有符合规则的括号内容才作为 Tag;空的 {} 或复杂的多对括号不能凭视觉随意判断,应通过 CLUSTER KEYSLOT key 验证。
在 Cluster 中运行 Lua,应显式通过 KEYS 参数传入所需 Key,并确保它们同槽,避免根据数据动态拼接并访问其他槽位。客户端即使支持跨节点批量读取,也通常只是拆分请求并汇总结果,不能因此获得跨槽原子性。
同槽设计有什么代价?
把同一订单的小范围数据放在同槽,方便进行原子操作;把所有用户都标记为 {user},则会把大量数据和流量压到同一槽,破坏分片均衡。Hash Tag 应体现需要共同操作的业务实体,而不是把整个系统强行放到一个位置。
常见追问
两个 Key 在同一节点,可以一起执行事务吗?
仍需检查是否同槽。节点负责多个槽,但多 Key 操作的限制不只看节点地址。
Pipeline 能绕过 CROSSSLOT 吗?
它可以由集群客户端把独立命令发到不同节点,但不能让本来要求同槽的一条命令获得跨槽原子性。
为什么 Redis Cluster 常见只有 DB 0?
Cluster 不支持像单节点那样切换多个逻辑数据库。业务隔离通常依靠 Key 命名或独立集群,不能靠 SELECT 把跨槽问题解决。
同槽是否代表迁移过程永远不出错?
不是。迁移中相关 Key 可能暂时分散于源与目标节点,多 Key 请求仍可能需要重试。客户端要处理迁移状态和重定向。
Redis Cluster 为什么会报 CROSSSLOT?Hash Tag 怎么用?
https://blog.xqcherry.top/posts/interview/redis/redis-cluster-hash-tags/ 目录