弹出极值是什么
从有序集合中弹出分数最小或最大的成员,并把它从集合中移除,一次可弹多个。它是「到期任务消费」与「榜单淘汰」的原子操作:取走与删除在同一步完成,不会出现两个消费者拿到同一条任务的竞态。
基本信息
| 弹最小 | ZPOPMIN 键 [数量],按分数从小到大 |
|---|---|
| 弹最大 | ZPOPMAX 键 [数量],按分数从大到小 |
| 返回结构 | 成员与分数交替出现的数组 |
| 阻塞版本 | BZPOPMIN 与 BZPOPMAX 在没有元素时等待指定秒数 |
| 版本要求 | 弹出多个成员需 Redis 6.2 及以上 |
典型使用场景
- 延时队列消费:分数存到期时间戳,到期时间最小的任务先被弹出执行
- 榜单淘汰:分数最低的成员达到淘汰条件时批量弹出
- 超时任务回收:把超时时间作为分数,定期弹出已超时的任务
- 限时优惠到期:到点后批量弹出失效条目
- 竞争消费:多个消费者同时弹出,天然不会重复取到同一条
示例
示例
ZADD delay:jobs 1700000001 job1 1700000002 job2
ZPOPMIN delay:jobs # 弹出分数最小的 job1 及其分数
ZPOPMAX delay:jobs 2 # 一次弹出分数最大的两个成员
ZRANGE delay:jobs 0 -1 WITHSCORES # 查看剩余成员
# 阻塞式消费:没有元素时最多等 5 秒
BZPOPMIN delay:jobs 5
# 只弹到期的任务(用 Lua 保证判断与弹出原子)
EVAL "local t = redis.call('ZRANGEBYSCORE', KEYS[1], '-inf', ARGV[1], 'LIMIT', 0, 1); if #t > 0 then redis.call('ZREM', KEYS[1], t[1]); return t[1] end; return false" 1 delay:jobs 1700000005输出逐列读法
| 返回 | 含义 | 注意 |
|---|---|---|
| 成员与分数交替数组 | 弹出的成员及其分数 | 客户端解析时按两两一组处理 |
| 空数组 | 集合为空或键不存在 | 阻塞版本会转为等待 |
| 阻塞超时 | 超时返回空值 | 消费循环要处理这种情况并继续等待 |
延时队列的常见实现:分数存到期时间戳,弹出前先用区间查询确认分数已到期,再把判断与弹出合并到一个脚本里保证原子。
弹出即从集合移除:任务被弹出后处理失败就彻底丢失,关键任务需要额外保留副本或改用带确认机制的消息结构。