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