*Redis BLMOVE 命令

BLMOVE 以阻塞方式从源列表弹出元素并推入目标列表,是 LMOVE 的阻塞版本。当源列表为空时会阻塞等待,直到元素可用或超时。


*语法

BLMOVE source destination LEFT | RIGHT LEFT | RIGHT timeout

*参数说明

参数 类型 必填 说明
source String 源列表键名
destination String 目标列表键名
LEFT / RIGHT Keyword 从源列表的哪一端弹出(LEFT = 头部,RIGHT = 尾部)
LEFT / RIGHT Keyword 推入目标列表的哪一端
timeout Double 阻塞超时时间(秒),0 表示无限阻塞

*返回值

  • Array / Nil
    • 成功时返回被移动的元素
    • 超时返回 nil(Redis 中显示为 (nil)

*时间复杂度

  • 源列表非空时:O(1) - 需要阻塞时:O(1) + 阻塞等待时间

*示例

*基本用法(列表间移动)

> RPUSH source "a" "b" "c"
3
> BLMOVE source dest LEFT RIGHT 5
"a"
> LRANGE dest 0 -1
1) "a"
> LRANGE source 0 -1
1) "b"
2) "c"

*阻塞等待(源列表为空)

# 客户端 A
> BLMOVE queue processing LEFT RIGHT 30
# (阻塞中...)

# 客户端 B(在 30 秒内)
> LPUSH queue "task1"
1

# 客户端 A 收到
"task1"

*无限阻塞

> BLMOVE queue done LEFT RIGHT 0
# 会一直阻塞直到有元素

*常见错误

错误 原因 解决
WRONGTYPE source 或 destination 不是 List 类型 检查 key 类型
ERR timeout is negative timeout 为负数 timeout 必须 ≥ 0
ERR wrong number of arguments 缺少方向参数 必须指定 LEFT/RIGHT 两次

*最佳实践

  • 可靠队列的核心命令:配合 BRPOPLPUSH(BLMOVE 的前身语义)实现安全队列
  • 从 processing 列表移回队列实现任务重试
  • timeout 设为 0 作为常驻消费者,注意处理连接断开重连
  • 超时后客户端应继续循环调用 BLMOVE,不要退出
  • 多个消费者竞争时,BLMOVE 保证每个元素只被一个消费者获取

*FAQ

Q1: BLMOVE 和 BRPOPLPUSH 有什么区别? A: BLMOVE 是 Redis 6.2+ 引入的,支持两端选择(LEFT/RIGHT 组合更灵活);BRPOPLPUSH 固定从 RIGHT 弹出、LEFT 推入。BLMOVE 已取代 BRPOPLPUSH

Q2: BLMOVE 是原子的吗? A: 是。弹出和推入在一个原子操作中完成,不会出现元素丢失。

Q3: 超时后应该做什么? A: 通常客户端应该重新调用 BLMOVE(循环)。timeout 的意义是避免连接永久阻塞,允许定期检查其他事件或重连。