BLPOP 命令是 LPOP 命令的阻塞版本,当指定列表内没有任何元素可供获取时,连接将被 BLPOP 命令阻塞,直到等待超时或存在可获取元素为止。
命令格式
BLPOP key [key ...] timeout
可用版本:2.0.0
时间复杂度:O(1)
BLPOP是列表的阻塞式弹出的原语(primitive)。
命令参数
- key:指定的列表 key,当指定多个 key 参数时,按照参数 key 的先后顺序依次检查各个列表,并弹出第一个非空列表的头元素。
- timeout:超时参数,接受一个以秒为单位的数字作为值。若超时参数设为0,其表示无超时时间限制(即无限期阻塞等待数据的到来)。
命令返回值
BLPOP命令返回的数据形式为数组形式,主要有2种情况:
- 返回 nil,当指定的列表为空且已经超时。
- 返回元素列表,当指定的列表中存在可返回的元素时,其中第一个元素是被弹出元素所属的 key,第二个元素是被弹出元素的值。
非阻塞行为
当 BLPOP 被调用时,如果指定 key 内至少有一个非空列表,那么弹出第一个非空列表的头元素,并和被弹出元素所属的列表的名字一起,组成结果返回给调用者。
当存在多个指定的 key 时,BLPOP 按指定 key 参数排列的先后顺序,依次检查各个列表。
阻塞行为
如果所有指定的 key 都不存在元素,那么 BLPOP 命令将阻塞连接,直到等待超时,或有另一个客户端对指定 key 的任意一个执行 LPUSH 或 RPUSH 命令为止。
注意,BLPOP 命令实际不会阻塞 Redis 服务,不会影响其他命令服务,具体的实现原理可参考Redis BLPOP实现原理。
其他
相同的 key 被多个客户端同时阻塞
相同的 key 可以被多个客户端同时阻塞。
不同的客户端被放进一个队列中,按“先阻塞先服务”原则,顺序地为 key 执行 BLPOP 命令。
在 MULTI/EXEC 事务中的 BLPOP
BLPOP 命令可以用于 pipline 中,但把它用在 MULTI/EXEC 块当中没有意义。因为这要求整个服务器被阻塞以保证块执行时的原子性,该行为阻止了其他客户端执行 LPUSH 或 RPUSH 命令。
因此,一个被包裹在 MULTI/EXEC 块内的 BLPOP 命令,行为表现得就像 LPOP 一样,对空列表返回 nil,对非空列表弹出列表元素,不进行任何阻塞操作。
示例
redis> BLPOP list1 1
(nil)
(1.04s)
redis> LPUSH list1 1
(integer) 1
redis> LPUSH list2 2
(integer) 1
redis> LPUSH list3 3
(integer) 1
redis> BLPOP list1 list2 list3 1
1) "list1"
2) "1"