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 与网络,应该改用阻塞式命令或定时轮询。