Redis BLMOVE 阻塞队列时如何设计超时后的回滚
Redis BLMOVE 的阻塞超时本身不需要回滚:当 source 列表为空并且 timeout 到期时,命令返回 nil(RESP2)或 null(RESP3),既没有从源列表弹出元素,也没有向目标列表压入元素。真正要设计补偿的,是任务已经从 queue:ready 原子转移到 queue:processing,但 worker 在业务处理或确认前失败的情况。
官方地址:https://redis.io/docs/latest/commands/blmove/
- BLMOVE 超时代表“这次没有拿到任务”,不要对空返回再次入队。
- 用 ready 与 processing 两个列表保留已领取但未确认的任务。
- 业务成功后再 ack;失败、断线或崩溃才走 requeue 或死信处理。
判断回滚的关键不是看 BLMOVE 是否设置了超时,而是看它有没有返回任务。没有返回任务就没有状态变化;返回任务后未完成业务,才需要补偿。
先把 BLMOVE 的返回语义分清
BLMOVE 的语法是 BLMOVE source destination wherefrom whereto timeout,在 source 有元素时会以 O(1) 复杂度完成列表间移动;source 为空时才进入阻塞等待。timeout 使用秒,可以是小数,设为 0 表示持续等待。
因此 worker 至少要区分三类结果:
| 结果 | 数据状态 | 处理动作 |
|---|---|---|
| 返回任务 ID | 任务已进入 processing | 执行业务,成功后确认 |
| 返回 nil/null | 没有发生移动 | 记录空闲或继续等待,不回滚 |
| 客户端/连接错误 | 服务端状态不能仅凭错误推断 | 按幂等策略查询或重试,不能盲目补一条 |

用两个列表保留“已领取但未确认”
如果直接用 RPOP queue:ready,worker 一旦在业务调用前崩溃,任务就只剩客户端内存中的副本。更稳妥的最小模型是生产者用 LPUSH 写入 ready,消费者用 BLMOVE 从右侧取出,再把任务放入 processing 的左侧:
# 生产者把任务放到左侧,消费者从右侧取出以保持 FIFO redis-cli LPUSH queue:ready job-1001 # 最多等待 3 秒;返回空值表示本次没有任务,不做回滚 redis-cli BLMOVE queue:ready queue:processing RIGHT LEFT 3
这一步的价值是“领取”和“登记处理中”由 Redis 的一个命令完成。任务 ID 要保持唯一,processing 中不要只放可能重复的业务名称,否则后续 LREM 可能确认错元素。
把 ack 放在业务成功之后
BLMOVE 返回任务只代表领取成功,不代表订单写入、邮件发送或外部 API 调用已经成功。worker 应先完成业务动作,再从 processing 删除对应的唯一任务 ID:
# 只有业务副作用成功后才确认,count=1 避免误删多个同值任务 redis-cli LREM queue:processing 1 job-1001
业务动作可能重试,所以“至少一次”队列必须配合幂等键,例如把 job-1001 作为业务流水号。不要把 LREM 提前到业务调用之前,那会把 worker 崩溃窗口变成任务丢失窗口。

真正失败时如何回滚或转死信
当 worker 明确拿到 job-1001,但业务失败或主动放弃时,才把它重新放回 ready。若 ready 采用 LPUSH/RPOP 的 FIFO 约定,回滚可用 RPUSH 把任务放回右侧:
# 业务失败后再入队;实际生产环境还应递增重试次数 redis-cli RPUSH queue:ready job-1001 # 重新入队成功后,从处理中列表删掉旧记录 redis-cli LREM queue:processing 1 job-1001
更严格的实现会把 payload 放在 Hash,把 processing 列表只存唯一 ID,并记录领取时间、重试次数和最后错误。巡检程序发现 processing 中长时间未确认的 ID 后,可以先做幂等查询,再选择 RPUSH 重试;超过上限则移入 queue:dead,避免无限循环。
需要注意,客户端在 BLMOVE 返回附近断线时,应用可能不知道服务端到底返回了什么。此时不能因为“我没收到回复”就直接补发;应依靠唯一任务 ID、业务幂等记录或改用 Redis Streams 的消费组确认与 pending 机制。
上线前的四项检查
- 超时空返回是否只记录“暂无任务”,没有额外 RPUSH。
- processing 是否能保存领取后未确认的唯一 ID。
- ack 是否发生在业务成功之后,重试是否具备幂等保护。
- Redis Cluster 下 source 和 destination 是否满足多 key 操作的部署约束;否则应调整键设计或选择 Streams。
常见问题
timeout 设置为 0 会不会自动回滚?
不会。0 只表示无限等待;BLMOVE 成功移动后也不会替你处理业务失败。
BLMOVE 超时后需要执行 LREM 吗?
不需要。超时没有返回任务,processing 中不存在由这次调用产生的记录。
为什么不直接使用 BRPOPLPUSH?
BLMOVE 是它的可配置替代,可以明确源端和目标端方向;旧命令迁移时要重新核对左右端语义。
MySQL ONLY_FULL_GROUP_BY 遇到函数依赖时如何改写查询
- 上一篇
- MySQL ONLY_FULL_GROUP_BY 遇到函数依赖时如何改写查询
- 下一篇
- 电商卖家选SkildArt前怎么测试商品颜色准确性?
-
- 数据库 · Redis | 20小时前 | Redis · 缓存一致性 · 失效通知 · redis CLIENT TRACKING 客户端缓存
- Client Tracking 失效通知怎么配置或排查
- 439浏览 收藏
-
- 数据库 · Redis | 21小时前 | Redis · cluster · redis Redis Cluster Hash Tag hash slot
- Cluster hash tag 同槽怎么配置或排查
- 358浏览 收藏
-
- 数据库 · Redis | 22小时前 |
- WATCH 事务重试怎么配置或排查
- 230浏览 收藏
-
- 数据库 · Redis | 1天前 | Redis · Sorted Set · ZRANGE · ZRANGEBYLEX ·
- Sorted Set 字典序范围怎么配置或排查
- 461浏览 收藏
-
- 数据库 · Redis | 1天前 | Redis · Redis Streams · XAUTOCLAIM ·
- XAUTOCLAIM 接管超时消息怎么配置或排查
- 287浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 125次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 48次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 16次使用
-
- OpenCompass
- OpenCompass是上海AI实验室推出的开源大模型评测平台,提供CompassKit、CompassHub和CompassRank三大核心组件,支持LLM及多模态模型的一站式标准化评估与排行榜查询。
- 67次使用
-
- AGI-Eval
- AGI-Eval是由上海交大等高校联合发布的大模型评测社区,提供公正透明的LLM能力榜单、多领域评测集及Data Studio数据服务,助力AI模型性能评估与NLP科研开发。
- 44次使用
-
- Redis教程(十三):管线详解
- 2023-01-08 294浏览
-
- Redis教程(十):持久化详解
- 2023-01-08 487浏览
-
- Redis ZSet 延迟任务如何处理:ZRANGEBYSCORE 取出与 ZREM 抢占的竞态
- 2026-08-29 192浏览
-
- Redis MSETNX 如何保证多键初始化:全成全败语义与已存在键核验
- 2026-08-29 189浏览
-
- Redis XNACK 如何快速交回 Pending 消息:消费者退出与重投优先级
- 2026-09-04 332浏览

