BRPOPLPUSH:阻塞式弹出并推入操作
BRPOPLPUSH
命令是 RPOPLPUSH
命令的阻塞版本,它接受一个源列表、一个目标列表以及一个秒级精度的超时时限作为参数:
- BRPOPLPUSH source target timeout
根据源列表是否为空,BRPOPLPUSH
命令会产生以下两种行为:
如果源列表非空,那么
BRPOPLPUSH
命令的行为就和RPOPLPUSH
命令的行为一样:BRPOPLPUSH
命令会弹出位于源列表最右端的元素,并将该元素推入到目标列表的左端,最后向客户端返回被推入的元素。如果源列表为空,那么
BRPOPLPUSH
命令将阻塞执行该命令的客户端,然后在给定的时限内等待可弹出的元素出现,又或者等待时间超过给定时限为止。
举个例子,假设现在有 list3
、 list4
两个列表如下:
- client-1> LRANGE list3 0 -1
- 1) "hello"
- client-1> LRANGE list4 0 -1
- 1) "a"
- 2) "b"
- 3) "c"
如果我们以这两个列表作为输入执行 BRPOPLPUSH
命令,由于源列表 list3
非空,所以 BRPOPLPUSH
命令将不阻塞直接执行,就像 RPOPLPUSH
命令一样:
- client-1> BRPOPLPUSH list3 list4 10
- "hello"
- client-1> LRANGE list3 0 -1
- (empty list or set)
- client-1> LRANGE list4 0 -1
- 1) "hello"
- 2) "a"
- 3) "b"
- 4) "c"
现在,由于 list3
为空,如果我们再次执行相同的 BRPOPLPUSH
命令,那么客户端 client-1
将被阻塞,直到我们从另一个客户端 client-2
向 list3
推入新元素为止:
- client-1> BRPOPLPUSH list3 list4 10
- "world"
- (1.42s) -- 被阻塞了 1.42 秒
- client-1> LRANGE list3 0 -1
- (empty list or set)
- client-1> LRANGE list4 0 -1
- 1) "world"
- 2) "hello"
- 3) "a"
- 4) "b"
- 5) "c"
- client-2> RPUSH list3 "world"
- (integer) 1
表 4-3 展示了客户端从被阻塞到解除阻塞的整个过程。
表 4-3 阻塞 BRPOPLPUSH
命令的执行过程
时间 | 客户端 client-1 | 客户端 client-2 |
---|---|---|
T1 | 尝试执行 BRPOPLPUSH list3 list4 10 并被阻塞。 | |
T2 | 执行 RPUSH list3 "world" ,向列表 list3 推入新元素。 | |
T3 | 服务器执行 BRPOPLPUSH 命令,并将元素 "world" 返回给客户端。 |
处理源列表为空的情况
如果源列表在用户给定的时限内一直没有元素可供弹出,那么 BRPOPLPUSH
命令将向客户端返回一个空值,以此来表示此次操作没有弹出和推入任何元素:
- redis> BRPOPLPUSH empty-list another-list 5
- (nil)
- (5.05s) -- 客户端被阻塞了 5.05 秒
跟 BLPOP
命令和 BRPOP
命令一样,redis-cli
客户端也会显示 BRPOPLPUSH
命令的阻塞时长。
其他信息
属性 | 值 |
---|---|
复杂度 | O(1) |
版本要求 | BRPOPLPUSH 命令从 Redis 2.2.0 版本开始可用。 |