LMOVE
LMOVE source destination <LEFT | RIGHT> <LEFT | RIGHT>
- 可用版本
- Redis 开源版 6.2.0
- 时间复杂度
- O(1)
- ACL 分类
-
@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
等同于 RPOPLPUSH
。
示例
模式:可靠队列
Redis 常被用作消息服务器,用于实现后台任务处理或其他类型的消息传递任务。一种简单的队列形式通常是通过生产者端将值推入列表,并在消费者端使用 RPOP
(轮询方式)或 BRPOP
(如果客户端更适合阻塞操作)等待这些值。
然而,在这种情况下获得的队列并不可靠,因为消息可能会丢失,例如在网络出现问题或消费者在接收到消息后(但在处理之前)崩溃的情况下。
LMOVE
(或阻塞变体 BLMOVE
)提供了一种避免此问题的方法:消费者获取消息并同时将其推入一个 *处理中* 列表。一旦消息被处理,它将使用 LREM
命令从 *处理中* 列表中移除该消息。
另一个客户端可以监控 *处理中* 列表,查找长时间停留在其中的条目,并在需要时将这些超时的条目再次推回队列。
模式:循环列表
使用 LMOVE
对同一个 source 和 destination 键操作,客户端可以在 O(N) 的时间复杂度内逐个访问 N 个元素的列表的所有元素,而无需使用单个 LRANGE
操作将整个列表从服务器传输到客户端。
上述模式在以下条件下也适用
- 有多个客户端在旋转列表:它们将获取不同的元素,直到列表中的所有元素都被访问,然后该过程重新开始。
- 即使其他客户端正在列表末尾积极地推入新项。
上述方法使得实现一个系统变得非常简单,在该系统中,一组项目必须由 N 个工作者持续尽可能快地处理。一个例子是一个监控系统,它必须使用多个并行工作者,以尽可能小的延迟检查一组网站是否可访问。
请注意,这种工作者实现是易于扩展和可靠的,因为即使消息丢失,该项仍会在队列中,并在下一次迭代中得到处理。