ZADD 的条件更新修饰符
ZADD 从 Redis 6.2 起支持 GT、LT 两个修饰符,用来表达条件更新:GT 表示只有新分数大于当前分数才写入,LT 表示只有新分数小于当前分数才写入。它把「读分数、比较、再写回」三步压缩成一条原子命令,去掉了读改写之间的竞态窗口和一次往返。成员不存在时,单独使用 GT 或 LT 依然会把成员新增进去。
基本信息
| 适用版本 | Redis 6.2 及以上 |
|---|---|
| 语法 | ZADD key [NX|XX] [GT|LT] [CH] [INCR] score member ... |
| GT 语义 | 新分数更大才更新 |
| LT 语义 | 新分数更小才更新 |
| 互斥规则 | NX 与 GT/LT 不能同时出现,同用直接报错 |
| 返回值 | 默认返回新增成员数,加 CH 后返回被修改成员数 |
典型使用场景
- 排行榜只保留历史最高分,用 GT 避免人工比较与覆盖
- 最短耗时榜、最优价格榜,用 LT 只记录更小值
- 进度、水位类指标只在前进时更新,防止乱序请求把值写回退
- 多写入方并发更新同一成员,用条件语义替代读改写避免竞态
- 配合 XX 限定只更新已有成员,防止脏成员被意外创建
常用写法
常用写法
redis-cli ZADD rank GT 1200 player:1 # 只有新高分才覆盖
redis-cli ZADD rank LT 800 player:2 # 记录更小值:耗时榜
redis-cli ZADD rank XX GT CH 1300 player:1 # 只改已存在成员,返回被修改数
redis-cli ZADD rank GT 1200 player:new # 成员不存在时直接新增
redis-cli ZSCORE rank player:1 # 校验最终分数
redis-cli ZADD rank NX GT 100 player:3 # 错误用法:NX 与 GT 互斥修饰符组合对照
| 组合 | 含义 | 注意事项 |
|---|---|---|
| GT | 新分数更大才更新 | 成员不存在时仍会新增 |
| LT | 新分数更小才更新 | 成员不存在时仍会新增 |
| XX 加 GT | 仅更新已有成员且要求更大 | 不会创建新成员 |
| CH | 返回被修改成员数 | 含新增与分数变化两类 |
分数相等时不构成「更大」或「更小」,不会产生更新;需要幂等写回的场景要确认业务能接受这一点。
GT/LT 与 EXISTS 分支判断属于同一类需求,但后者需要两次往返,把条件交给 ZADD 处理更省事,代价是业务语义必须能表达成单条比较。