首页/数据/数据库速查/LMOVE / RPOPLPUSH 可靠队列转移
Redis 命令96 条

LMOVE / RPOPLPUSH 可靠队列转移

原子地把元素从源列表弹出并推入目标列表(可跨两端指定方向);消费者崩溃前进程在,元素仍在备份列表里,可重放。

数据库速查数据更新于 2026-10-13

LMOVE 是什么

LMOVE 原子地把元素从源列表弹出并推入目标列表,两个方向参数分别控制从源列表的哪一端弹出、推入目标列表的哪一端;RPOPLPUSH 是它在「左弹右推」方向上的旧写法。用它可以把元素搬到「处理中」列表:消费者崩溃时元素还留在备份列表里,事后可以重放,这就是常说的可靠队列。

基本信息

语法LMOVE source destination LEFT|RIGHT LEFT|RIGHT
旧命令RPOPLPUSH source destination,固定左弹右推
原子性弹出与推入在一次操作中完成,不会丢元素
返回值被移动的元素;源列表为空时返回 nil
典型结构pending 到 processing,处理成功后从 processing 删除

典型使用场景

  • 实现至少一次投递的可靠队列
  • 任务处理失败后仍能重放
  • 在多个列表之间搬运元素,构建流水线
  • 搭建「待处理、处理中、已完成」的三列表结构
  • 避免取出元素后进程崩溃导致任务凭空丢失

可靠队列示例

可靠队列示例
RPUSH pending job1 job2
LMOVE pending processing LEFT RIGHT   # 取出 job1 并移入 processing
LRANGE processing 0 -1                # 处理中列表里能看到 job1(备份)
LREM processing 1 job1                # 处理成功后从备份列表删除
RPOPLPUSH pending processing          # 旧写法:固定左弹右推
LMOVE pending processing RIGHT LEFT   # 轮询取出(源为空时返回 nil)

参数与返回值

参数含义说明
source源列表元素从这里弹出
destination目标列表元素推入此处
第一个方向参数从源列表哪一端弹出LEFT 表示头部,RIGHT 表示尾部
第二个方向参数推入目标列表哪一端同样用 LEFT 与 RIGHT 指定
返回值被移动的元素源列表为空时返回 nil
这是「安全队列」的经典方案:pending 到 processing 再到确认删除,任何一步失败都能从 processing 里找回原始任务,必要时用另一个线程把滞留元素搬回 pending 重试。
忘记消费确认这一步,处理失败的元素会永远留在 processing 列表里无人回收,时间久了既占内存,又让人误以为这些任务已经处理完成。
用 LMOVE 做环形自移来实现轮询检测是经典反模式:没有任何任务时它也会持续空转,白白消耗 CPU 与网络,应该改用阻塞式命令或定时轮询。

易错点

  • 忘记从 processing 列表删除已处理的元素:列表无限增长并占用内存
  • 处理失败没有重试机制:任务滞留在处理中列表里,实际已经丢失
  • 用环形自移做轮询:空转消耗资源却什么问题都不解决
  • 把 LMOVE 当事务使用:它只保证单次搬移原子,不提供跨命令的原子性

数据来源与参考

  • Redis 官方文档: LMOVE
  • Redis 官方文档: RPOPLPUSH

相关工具

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌