RPOPLPUSH (已弃用)
截至Redis版本6.2.0,此命令被视为已弃用。
在迁移或编写新代码时,可以使用带有RIGHT
和LEFT
参数的LMOVE
来替换它。
RPOPLPUSH source destination
- Available since:
- 1.2.0
- Time complexity:
- O(1)
- ACL categories:
-
@write
,@list
,@slow
,
原子性地返回并移除存储在source
列表中的最后一个元素(尾部),并将该元素推入存储在destination
列表中的第一个元素(头部)。
例如:考虑source
持有列表a,b,c
,而destination
持有列表x,y,z
。
执行RPOPLPUSH
后,source
将持有a,b
,而destination
将持有c,x,y,z
。
如果source
不存在,则返回nil
值并且不执行任何操作。
如果source
和destination
相同,则该操作相当于从列表中移除最后一个元素并将其作为列表的第一个元素推入,因此可以将其视为列表旋转命令。
示例
模式:可靠队列
Redis 通常被用作消息服务器来实现后台作业或其他类型的消息任务的处理。
一种简单的队列形式通常是在生产者端将值推入列表中,然后在消费者端使用 RPOP
(使用轮询)或 BRPOP
(如果客户端更适合阻塞操作)来等待这些值。
然而,在这种情况下,获取的队列并不可靠,因为消息可能会丢失,例如在网络问题或消费者在收到消息后但在处理之前崩溃的情况下。
RPOPLPUSH
(或阻塞变体的BRPOPLPUSH
)提供了一种避免此问题的方法:消费者获取消息的同时将其推入一个处理列表中。一旦消息被处理,它将使用LREM
命令从处理列表中移除消息。
额外的客户端可以监控处理列表中停留时间过长的项目,并在需要时将超时的项目重新推入队列。
模式:循环列表
使用RPOPLPUSH
与相同的源和目标键,客户端可以依次访问N元素列表的所有元素,在O(N)时间内,而无需使用单个LRANGE
操作将整个列表从服务器传输到客户端。
即使出现以下一个或两个条件,上述模式仍然有效:
- 有多个客户端在轮询列表:它们将获取不同的元素,直到列表中的所有元素都被访问过,然后这个过程重新开始。
- 其他客户端正在列表末尾积极推送新项目。
上述内容使得实现一个系统变得非常简单,在这个系统中,一组项目必须由N个工作者尽可能快地连续处理。一个例子是监控系统,它必须使用多个并行工作者检查一组网站是否可访问,并尽可能减少延迟。
请注意,这种工作者的实现是简单可扩展且可靠的,因为即使消息丢失,项目仍然在队列中,并将在下一次迭代中处理。
RESP2 回复
以下之一:
- Bulk string reply: 被弹出和推入的元素。
- Nil reply: 如果源列表为空。
RESP3 回复
以下之一:
- Bulk string reply: 被弹出和推入的元素。
- Null reply: 如果源列表为空。