redis集群中set的nx/xx不跨节点原子,需用{xxx}确保key同slot;mset等批量命令要求key同slot,否则报crossslot;锁需lua校验value;incr须单key无pipeline干扰;大value(>10kb)应压缩;key命名须散列控制防热点。

集群中 SET 命令的 NX/XX 选项不能跨节点保证原子性
在 Redis 单机模式下,SET key value NX 能可靠实现分布式锁或“仅新建”语义;但在集群模式下,如果 key 的 slot 分布在不同节点,客户端重定向后实际执行可能落在多个节点上,NX 的判断只在目标节点生效——这意味着两个客户端同时对同一个逻辑 key 执行 NX,仍可能都成功(只要它们被路由到不同节点且该节点上 key 不存在)。这不是 bug,而是集群分片模型的固有限制。
- 必须确保锁 key 或需原子判断的 key 属于同一 slot:可通过在 key 名末尾加
{xxx}强制哈希到同一节点,例如lock:user:123{user:123} -
MSET、MGET等批量命令要求所有 key 在同一 slot,否则直接报错CROSSSLOT Keys in request don't hash to the same slot - 避免用
SET key value NX EX 10直接做带过期的锁;应配合DEL+ Lua 脚本校验 value 一致性,否则释放时可能误删他人持有的锁
INCR/DECR 类数值操作在集群里必须单 key 且无 pipeline 干扰
Redis 的 INCR 是原子操作,但前提是它不跨节点。集群中若 key 被哈希到某个主节点,操作就只在该节点执行——这本身没问题;问题出在客户端误用 pipeline 或多 key 操作时。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 不要在一个 pipeline 里混用多个不同 slot 的
INCR请求:Lettuce 或 Jedis 可能自动拆包并并发发往不同节点,导致无法保证顺序或原子性语义 - 不要对非数字字符串执行
INCR:集群节点返回的错误是ERR value is not an integer or out of range,但不同节点报错时机可能不一致,增加排障难度 - 计数器类 key 建议统一加前缀如
counter:pageview:{id},利用{id}确保同业务数据落在同一 slot
大 string 值(>10KB)在集群中加剧网络与内存压力
单个 string value 超过 10KB 后,在集群环境下会显著放大问题:不仅占用更多内存,序列化/反序列化开销上升,跨节点迁移(如故障转移、reshard)时更易超时或失败。
- Redis 官方建议 string value 控制在 10KB 以内;超过 100KB 就要警惕,512MB 是硬上限但完全不实用
- 集群中
GET大 value 会阻塞对应节点的单线程处理,影响同 slot 其他请求响应时间 - 若必须存二进制内容(如小图、token payload),优先考虑压缩(如 gzip)后再写入,读取时再解压
- 避免用
SETEX写入大 value + 过期时间:TTL 设置本身不增加传输成本,但过期清理时大对象回收更耗 CPU
Key 命名不规范导致 slot 热点和运维困难
集群中 key 的分布由 CRC16(key) % 16384 决定,如果大量 key 共享相同前缀(如 user:1:*、cache:prod:),极易打到同一个 slot,造成该 slot 所在节点 CPU、内存、连接数飙升。
- 禁止使用无散列控制的固定前缀,例如
user:1:name、user:1:email应改为user:{1}:name、user:{1}:email - 业务 key 长度尽量 ≤30 字符,避免冗余字段;空格、换行、双引号等字符会导致客户端解析异常或命令截断
- 不同业务模块的 key 必须用不同一级前缀隔离,如
auth:token:、order:seq:,方便监控、清理和权限控制 - 集群运维时,
redis-cli --cluster check只能发现 slot 分配不均,无法识别语义热点——得靠业务侧主动埋点或 slowlog 分析










