首页/数据/Redis 进阶速查/ZADD 的 GT/LT:条件更新分数
数据结构与选型42 条

ZADD 的 GT/LT:条件更新分数

ZADD 支持 GT、LT 修饰符:仅当新分数更大(或更小)时才更新;与 NX/XX 组合可表达「只更新且只在更优时」的语义。

Redis 进阶速查数据更新于 2026-10-13

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 处理更省事,代价是业务语义必须能表达成单条比较。

易错点

  • 把 GT 误解为「只更新不新增」,成员不存在时数据仍被写入
  • NX 与 GT/LT 写在一起导致命令直接报错,条件语义需改用 Lua 或 WATCH 实现
  • 以为返回值是变更数,实际默认只统计新增成员,误判更新未生效
  • 分数使用浮点时比较受精度限制,期望的等值更新不会发生

数据来源与参考

  • Redis 官方文档:ZADD 修饰符
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌