BLPOP

语法
BLPOP key [key ...] timeout
从以下位置开始可用:
2.0.0
时间复杂度:
O(N),其中 N 是提供的键数。
ACL 类别:
@write, @list, @slow, @blocking,

BLPOP是阻止列表弹出基元。 它是LPOP因为它在 都不是要从任何给定列表中弹出的元素。 从第一个非空列表的头部弹出一个元素,其中 given keys 按照给定的顺序进行检查。

非阻塞行为

什么时候BLPOP调用时,如果至少有一个指定的键包含 非空列表,则从列表头部弹出一个元素并返回到 调用方与key它是从中弹出的。

键按照给定的顺序进行检查。 假设密钥list1不存在,并且list2list3拿 非空列表。 请考虑以下命令:

BLPOP list1 list2 list3 0

BLPOP保证从存储在list2(由于 它是检查时的第一个非空列表list1,list2list3在 那个顺序)。

阻塞行为

如果指定的键都不存在,则BLPOP阻止连接,直到另一个 客户端执行LPUSHRPUSH作。

一旦其中一个列表中出现新数据,客户端将返回名称 的键取消阻塞它和 popped 值。

什么时候BLPOP导致客户端阻塞并指定非零超时, 客户端将取消阻止返回nilmulti-bulk 值(如果指定了 timeout 已过期,但未对至少一个 指定的键。

timeout 参数被解释为一个 double 值,用于指定要阻止的最大秒数。超时 0 可用于无限期阻止。

首先提供哪个密钥?什么客户?什么元素?优先订购详情。

  • 如果客户端尝试阻止多个键,但至少有一个键包含元素,则返回的键/元素对是从左到右具有一个或多个元素的第一个键。在这种情况下,客户端不会被阻止。例如,BLPOP key1 key2 key3 key4 0,假设两者key2key4非空,则始终返回key2.
  • 如果多个客户端因同一密钥而被阻止,则第一个要服务的客户端是等待更多时间的客户端(第一个阻止密钥的客户端)。一旦客户端被取消阻塞,它就不会保留任何优先级,当它再次阻塞时,下一次调用BLPOP它将根据已为同一 key 阻塞的 Client 端数量提供,这些 Client 端都将在它之前提供(从第一个到最后一个被阻塞的 Client 端)。
  • 当客户端同时阻塞多个 key,并且元素同时在多个 key 中可用时(由于事务或 Lua 脚本将元素添加到多个列表),客户端将使用收到 push作的第一个 key 解除阻塞(假设它有足够的元素来为我们的客户端服务, 因为可能还有其他客户端也在等待此密钥)。基本上,在执行每个命令之后,Redis 将运行一个列表,其中包含接收数据的所有键,并且至少有一个客户端被阻止。该列表按新元素到达时间排序,从接收数据的第一个键到最后一个键。对于处理的每个密钥,Redis 将以 FIFO 方式为所有等待该密钥的客户端提供服务,只要此密钥中有元素。当 key 为空或不再有客户端等待此 key 时,将处理在上一个命令/交易/脚本中接收新数据的下一个 key,依此类推。

的行为BLPOP当多个元素被推送到一个列表内时。

有时,列表可以在同一概念命令的上下文中接收多个元素:

  • 可变参数推送作,例如LPUSH mylist a b c.
  • EXECMULTIblock 对同一列表执行多个推送作。
  • 使用 Redis 2.6 或更高版本执行 Lua 脚本。

当多个元素被推送到存在客户端阻塞的列表中时,Redis 2.4 和 Redis 2.6 或更高版本的行为会有所不同。

对于 Redis 2.6,发生的情况是执行执行多个推送的命令,并且仅在执行命令后,才会为被阻止的客户端提供服务。考虑以下命令序列。

Client A:   BLPOP foo 0
Client B:   LPUSH foo a b c

如果使用 Redis 2.6 或更高版本的服务器发生上述情况,则客户端 A 将获得c元素,因为在LPUSH命令,该列表包含c,b,a,因此从左侧获取元素意味着返回c.

相反,Redis 2.4 以不同的方式工作:客户端在推送作的上下文中提供服务,因此只要LPUSH foo a b c开始将第一个元素推送到列表中,它将被传送给客户端 A,客户端 A 将接收a(第一个元素被推送)。

在将数据复制或持久化到 AOF 文件时,Redis 2.4 的行为会产生很多问题,因此在 Redis 2.6 中引入了更通用且语义更简单的行为,以防止出现问题。

请注意,出于同样的原因,Lua 脚本或MULTI/EXECblock 可能会将元素推送到列表中,然后删除该列表。在这种情况下,被阻止的客户端将根本不被提供服务,只要在执行单个命令、事务或脚本后列表中不存在数据,就会继续被阻止。

BLPOPMULTI / EXEC交易

BLPOP可以与流水线一起使用(发送多个命令和 批量读取回复),但是这种设置几乎完全有意义 当它是管道的最后一个命令时。

BLPOPMULTI / EXEC阻止没有多大意义 因为它需要阻止整个服务器才能执行块 原子方式,这反过来又不允许其他客户端执行推送 操作。因此,其BLPOP里面MULTI / EXEC当列表为空时,将返回一个nilmulti-bulk 回复,这与 达到超时时发生的事情。

如果你喜欢科幻小说,想想时间在MULTI / EXEC块。。。

例子

redis> DEL list1 list2
(integer) 0
redis> RPUSH list1 a b c
(integer) 3
redis> BLPOP list1 list2 0
1) "list1"
2) "a"

可靠的队列

什么时候BLPOP将一个元素返回给客户端,它还会从列表中删除该元素。这意味着该元素仅存在于客户端的上下文中:如果客户端在处理返回的元素时崩溃,它将永远丢失。

对于某些应用程序来说,这可能是一个问题,而我们需要一个更可靠的消息传递系统。在这种情况下,请检查BRPOPLPUSHcommand 的BLPOP这会在将返回的元素返回给客户端之前将其添加到 Target List。

模式:事件通知

使用阻止列表作,可以挂载不同的阻止 原。 例如,对于某些应用程序,您可能需要阻止等待元素 添加到 Redis Set 中,因此只要将新元素添加到 Set 中,它就会 可以在不求助于轮询的情况下检索它。 这将需要SPOP不可用,但使用 blocking list作我们可以轻松完成此任务。

消费者将执行以下作:

LOOP forever
    WHILE SPOP(key) returns elements
        ... process elements ...
    END
    BRPOP helper_key
END

在 producer 端,我们将简单地使用:

MULTI
SADD key element
LPUSH helper_key x
EXEC

RESP2 回复

以下选项之一:

  • Nil 回复:无法弹出任何元素,超时已过期
  • 数组回复:从中弹出元素的键和弹出的元素的值。

RESP3 回复

以下选项之一:

  • 空回复:无法弹出任何元素,超时已过期
  • 数组回复:从中弹出元素的键和弹出的元素的值。

历史

  • 从 Redis 版本 6.0.0 开始:timeout被解释为 double 而不是整数。
为本页评分
返回顶部 ↑