Redis BRPOP 命令是 RPOP 命令的阻塞版本,当指定列表内没有任何元素可供获取时,连接将被 BRPOP 命令阻塞,直到等待超时或存在可获取元素为止。BRPOP 是列表的阻塞式弹出的原语(primitive),可以用于消息队列场景,可以指定监测多个消息队列,直到有任意一个消息队列中有待处理消息时,阻塞返回。
命令格式
BRPOP key [key ...] timeout
可用版本:2.0.0
时间复杂度:O(1)
命令参数
- key:指定的列表 key,当指定多个 key 参数时,按照参数 key 的先后顺序依次检查各个列表,并弹出第一个非空列表的尾元素。
- timeout:超时参数,接受一个以秒为单位的数字作为值。若超时参数设为 0,其表示无超时时间限制(即无限期阻塞等待数据的到来)。
命令返回值
BRPOP 命令返回的数据形式为数组形式,主要有 3 种情况:
- 当指定的列表为空且已经超时,返回 nil。
- 返回元素列表,当指定的列表中存在可返回的元素时,其中第一个元素是被弹出元素所属的 key,第二个元素是被弹出元素的值。
- 当指定的 key 为非列表时,返回命令与类型不匹配的信息。
非阻塞行为
当 BRPOP 被调用时,如果指定 key 内至少有一个非空列表,那么弹出第一个非空列表的头元素,并和被弹出元素所属的列表的名字一起,组成结果返回给调用者。
当存在多个指定的 key 时,BRPOP 按指定 key 参数排列的先后顺序,依次检查各个列表。
阻塞行为
如果所有指定的 key 都不存在元素,那么 BRPOP 命令将阻塞连接,直到等待超时,或有另一个客户端对指定 key 的任意一个执行 LPUSH 或 RPUSH 命令为止。
其他
相同的 key 被多个客户端同时阻塞
相同的 key 可以被多个客户端同时阻塞。
不同的客户端被放进一个队列中,按“先阻塞先服务”原则,顺序地为 key 执行 BRPOP命令。
在 MULTI/EXEC 事务中的 BRPOP
BRPOP 命令可以用于 pipline 中,但把它用在 MULTI/EXEC 块当中没有意义。因为这要求整个服务器被阻塞以保证块执行时的原子性,该行为阻止了其他客户端执行 LPUSH 或 RPUSH 命令。
因此,一个被包裹在 MULTI/EXEC 块内的 BRPOP 命令,行为表现得就像 RPOP 一样,对空列表返回 nil,对非空列表弹出列表元素,不进行任何阻塞操作。
示例
redis> BRPOP mylist 1 # 当指定 key 不存在时
(nil)
(1.05s)
redis> LPUSH mylist1 storm
(integer) 1
redis> LPUSH mylist2 spark
(integer) 1
redis> LPUSH mylist3 flink
(integer) 1
redis> BRPOP mylist1 mylist2 mylist3 1 # 当指定 key 存在且列表类型时
1) "mylist1"
2) "storm"
redis> SET knowledge dict
OK
redis> BRPOP knowledge 1 # 当指定 key 为非列表类型时
(error) WRONGTYPE Operation against a key holding the wrong kind of value
redis>