有序集合写入
有序集合是「成员加分数」的结构:成员唯一、按分数自动排序,因此既能去重又能排序。写入命令支持多种条件选项——只在成员不存在时新增、只在已存在时更新、按分数大小决定是否更新、返回变动数量,以及增量模式。要注意默认行为是直接覆盖分数,想要「只在分数更大时才更新」必须显式指定条件。
基本信息
| 用途 | 添加成员并设置分数 |
|---|---|
| 语法 | 写入命令 键 [NX|XX] [GT|LT] [CH] [INCR] 分数 成员 [分数 成员 ...] |
| 返回值 | 普通模式为新增成员数,带变动选项为变动数,增量模式为新分数 |
| 条件选项 | NX 只新增、XX 只更新、GT/LT 按分数比较 |
| 排序性质 | 按分数升序排列,同分按成员字典序 |
| 常见用途 | 排行榜、延时任务、加权队列 |
典型使用场景
- 排行榜:分数为热度或销量,读取时按排名取区间
- 延时任务:分数为执行时间戳,按时取到期任务
- 加权队列:分数表示优先级
- 去重且有序的集合:成员唯一并自带顺序
- 热点统计:用分数累加表示访问次数
- 排名查询:查某成员的名次与分数
常用组合
常用组合
ZADD rank 100 u1 200 u2 # 返回 2,两个成员都是新增
ZADD rank XX 150 u1 # 只更新已存在的成员,不存在则不写
ZADD rank NX 300 u3 # 只新增,成员已存在则不动
ZADD rank GT CH 180 u1 # 仅当新分数更大才更新,返回变动数量
ZADD rank INCR 10 u1 # 分数加 10,返回新分数选项与返回读法
| 选项 | 作用 | 返回与注意 |
|---|---|---|
| NX | 成员不存在才写入 | 已存在则不写,返回 0 |
| XX | 成员存在才写入 | 不存在则不新建,适合只更新 |
| GT | 新分数更大才更新 | 与只新增选项互斥 |
| LT | 新分数更小才更新 | 适合保留最小值语义 |
| CH | 返回变动数量 | 包含新增与被修改的成员 |
| INCR | 增量模式 | 只能带一个成员,返回新分数 |
| 无选项 | 默认直接覆盖分数 | 最容易误以为会保留旧值 |
条件选项之间互斥:按分数比较的选项不能与只新增选项同时使用,增量模式也不能带多个成员,写错会直接报语法错误。
同一分数下多个成员按字典序排列,分页取榜要注意并列的处理方式,必要时把成员标识设计成可排序的格式。
热门榜单的分数会随每次访问更新,写放大明显;写频次极高的计数场景应先在前端或应用层聚合,再批量写入,避免更新集中在单个键上。
有序集合使用清单
- 明确分数含义与更新条件,避免误覆盖
- 需要保留极值时使用分数比较选项
- 读取用排名或分数区间,避免全量读取
- 大集合的排名查询要关注复杂度与响应规模
- 热键按维度拆分,避免单键写放大
- 利用成员唯一性做天然的重复校验
有序集合既存成员也存分数,内存占用高于同规模的集合:成员数量大时要评估内存水位,必要时只保留窗口期数据并定期清理过期成员。
延时任务这类场景用时间戳作分数时,记得配合定期清理:已执行完的成员如果不删除,集合会持续增长,最终既占内存又拖慢范围查询。