LMOVE

从一个列表中弹出一个元素并将其推送到另一个列表后返回该元素。如果移动了最后一个元素,则删除列表。

语法

LMOVE source destination

引入版本:6.2.0

复杂度摘要:O(1)

[!NOTE] 此命令的行为在集群 Redis 环境中有所不同。请参阅 多键操作 页面了解更多信息。

原子地返回并删除存储在 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 是等效的。

必需参数

source

源列表的key。

destination

目的地列表键。

LEFT | RIGHT

source 的末尾,用于弹出元素:LEFT(头)或 RIGHT(尾)。

LEFT | RIGHT

destination 的末尾将元素推送到:LEFT(头)或 RIGHT(尾)。

示例

redis> RPUSH mylist "one"
(integer) 1
redis> RPUSH mylist "two"
(integer) 2
redis> RPUSH mylist "three"
(integer) 3
redis> LMOVE mylist myotherlist RIGHT LEFT
"three"
redis> LMOVE mylist myotherlist LEFT RIGHT
"one"
redis> LRANGE mylist 0 -1
1) "two"
redis> LRANGE myotherlist 0 -1
1) "three"
2) "one"

详细说明

模式:可靠队列

Redis经常被用作消息服务器来实现后台作业或其他类型的消息任务的处理。通常会获得一种简单的队列形式,将值推送到生产者端的列表中,并使用 RPOP(使用轮询)在消费者端等待该值,如果通过阻塞操作更好地为客户端提供服务,则使用 BRPOP 等待该值。

然而,在这种情况下,获得的队列不是 可靠,因为消息可能会丢失,例如,在出现网络问题的情况下,或者消费者在收到消息但仍在处理消息后立即崩溃。

LMOVE(或阻塞变体的 BLMOVE)提供了一种避免此问题的方法:消费者获取消息,同时将其推送到 加工 列表中。一旦消息被处理,它将使用 LREM 命令从 加工 列表中删除该消息。

另一个客户端可以监视 加工 列表中保留时间过长的项目,并在需要时将这些超时的项目再次推入队列。

图案:循环列表

使用具有相同源键和目标键的 LMOVE,客户端可以在 O(N) 内一个接一个地访问 N 元素列表的所有元素,而无需使用单个 LRANGE 操作将完整列表从服务器传输到客户端。

上述模式即使在以下条件下也能工作:

  • 有多个客户端轮换列表:它们将获取不同的元素,直到列表中的所有元素都被访问,并且该过程重新启动。
  • 即使其他客户正在积极地在列表末尾推送新项目。

上面的内容使得实现一个系统变得非常简单,其中一组项目必须由 N 个工作人员尽可能快地连续处理。一个示例是监控系统,它必须使用多个并行工作线程以尽可能小的延迟来检查一组网站是否可访问。

请注意,workers 的这种实现具有良好的可扩展性和可靠性,因为即使消息丢失,该项目仍在队列中,并将在下一次迭代中进行处理。

Redis Software 与 Redis Cloud 兼容性

Redis
软件
Redis
Cloud
说明
✅ 标准
✅ 主动-主动
✅ 标准
✅ 主动-主动

返回值

RESP2

批量字符串回复:正在弹出和压入的元素。

RESP3

批量字符串回复:正在弹出和压入的元素。

资料来源:Redis 官方 LMOVE 文档;中文内容参考 Redis 文档许可。