BZPOPMAX、BZPOPMIN:阻塞式最大/最小元素弹出操作

BZPOPMAX 命令和 BZPOPMIN 命令分别是 ZPOPMAX 命令以及 ZPOPMIN 命令的阻塞版本,这两个阻塞命令都接受任意多个有序集合和一个秒级精度的超时时限作为参数:

BZPOPMAX sorted_set [sorted_set ...] timeout
BZPOPMIN sorted_set [sorted_set ...] timeout

接收到参数的 BZPOPMAX 命令和 BZPOPMIN 命令会依次检查用户给定的有序集合,并从它遇到的第一个非空有序集合中弹出指定的元素。如果命令在检查了所有给定有序集合之后都没有发现可弹出的元素,那么它将阻塞执行命令的客户端,并在给定的时限之内等待可弹出的元素出现,直到等待时间超过给定时限为止。用户可以通过将超时时限设置为 0 来让命令一直阻塞,直到可弹出的元素出现为止。

BZPOPMAX 命令和 BZPOPMIN 命令在成功弹出元素时将返回一个包含 3 个项的列表,这 3 个项分别为被弹出元素所在的有序集合、被弹出元素的成员以及被弹出元素的分值。与此相反,如果这两个命令因为等待超时而未能弹出任何元素,那么它们将返回一个空值作为结果。

举个例子,对于以下 3 个有序集合来说:

redis> ZRANGE ss1 0 -1 WITHSCORES
(empty list or set)
redis> ZRANGE ss2 0 -1 WITHSCORES
1) "a"
2) "1"
3) "b"
4) "2"
redis> ZRANGE ss3 0 -1 WITHSCORES
1) "c"
2) "3"

如果我们对它们执行以下 BZPOPMAX 命令,那么命令将跳过空集 ss1,并弹出第一个非空有序集合 ss2 的最大元素:

redis> BZPOPMAX ss1 ss2 ss3 10
1) "ss2" -- 被弹出元素所在的有序集合
2) "b" -- 被弹出元素的成员
3) "2" -- 被弹出元素的分值

与此类似,如果我们继续执行 BZPOPMAX 命令,那么命令将继续弹出第一个非空有序集合 ss2 的最大元素:

redis> BZPOPMAX ss1 ss2 ss3 10
1) "ss2"
2) "a"
3) "1"

现在,当 ss1 和 ss2 都变成空集之后,如果我们再次执行 BZPOPMAX 命令,那么命令将跳过空集 ss1 和 ss2,弹出第一个非空有序集合 ss3 的最大元素:

redis> BZPOPMAX ss1 ss2 ss3 10
1) "ss3"
2) "c"
3) "3"

最后,因为此时 3 个有序集合均已变成空集,所以如果我们再次执行 BZPOPMAX 命令,那么命令将在阻塞 10s 之后返回空值:

redis> BZPOPMAX ss1 ss2 ss3 10
(nil)
(10.05s)

除了 BZPOPMAX 命令弹出的是最大元素而 BZPOPMIN 命令弹出的是最小元素之外,这两个命令接受参数的方式以及返回值的方式完全相同。

其他信息

  • 复杂度:O(N),其中 N 为用户给定的有序集合数量。

  • 版本要求:BZPOPMAX 命令和 BZPOPMIN 命令从 Redis 5.0.0 版本开始可用。