Redis命令 - rpoplpush & brpoplpush
RPOPLPUSH source destination
版本: 2.2.0及以上
时间复杂度:O(1)
原子性地返回并删除存储在source列表的最后一个元素(尾),并将该元素推入并存储为destination列表的第一个元素(头)。
如果source不存在,则返回值nil,并且不执行任何操作。如果source和destination相同,则操作等同于从列表中移除最后一个元素,并将其作为列表的第一个元素推入,因此可以将其视为列表回转命令(rotation command)。
返回值
Bulk string reply:获取并推入的元素
示例
127.0.0.1:6379> rpush mylist a b c
(integer) 3
127.0.0.1:6379> lrange mylist 0 -1
1) "a"
2) "b"
3) "c"
127.0.0.1:6379> rpoplpush mylist myotherlist
"c"
127.0.0.1:6379> lrange mylist 0 -1
1) "a"
2) "b"
127.0.0.1:6379> lrange myotherlist 0 -1
1) "c"
模式:可靠队列 (Reliable queue)
Redis经常用作消息通知服务器,用于处理后台任务或其他类型的消息任务。一种简单的队列形式通常是在生产者端将值推送到列表中,然后等待消费者端使用RPOP(使用轮询)等待这个值,或者如果客户端通过阻塞操作得到更好的服务,则使用BRPOP。
但是,在这种情况下,获得的队列是不可靠的,因为消息可能会丢失,例如在出现网络问题的时候,或者在收到消息之后消费者端崩溃了,但是仍然需要处理。
RPOPLPUSH(或BRPOPLPUSH 阻塞变体)提供了一种避免此问题的方法:消费者获取消息,同时将其推入处理列表。然后使用LREM命令,以便在处理消息之后将消息从处理列表中删除。
另一个客户端可以监视在处理列表中停留太长时间的条目,并在需要时将那些超时的条目再次推入队列。
模式:循环队列 (Circular queue)
RPOPLPUSH的source和destination的键值相同时,客户端可以一个接一个地访问含有N个元素的列表中的每个元素,而无需使用单个LRANGE操作将整个列表从服务端传到到客户端。
这个模式即使在以下两种条件下也可以工作:
- 多个客户端同时查询一个列表:它们将获取到不同的元素,直到列表的所有元素都被访问,周而复始。
- 即使有其他客户继续在列表末尾推入新元素。
以上使得实现一个由N个worker连续的快速处理一组元素的系统变得非常简单。一个例子是监视系统,它必须使用一些并行的worker,以尽可能小的延迟检查一组web站点是否可访问。
workers的这种实现具有简单的可伸缩性和可靠性,因为即使消息没有处理成功,他仍然在队列中,并将在下一次迭代中进行处理。
BRPOPLPUSH source destination timeout
BRPOPLPUSH是RPOPLPUSH的阻塞变体。当source包含元素时,该命令的行为与RPOPLPUSH完全相同。当在MULTI/EXEC块中使用时,该命令的行为与RPOPLPUSH完全相同。当source为空时,Redis将阻塞连接,直到另一个客户端推入元素进来或超时为止。超时为0可用于无限期地阻塞。
超时返回NULL