*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 的意义是避免连接永久阻塞,允许定期检查其他事件或重连。