In Redis, the BZMPOP
command is the blocking variant of the ZMPOP
command.
The BZMPOP
command works exactly like ZMPOP
when any of the sorted sets contain elements. It also works exactly like ZMPOP
when used inside a MULTI/EXEC
block. That is, it pops one or more elements from the first non-empty sorted set in the provided list of keys.
However, if all of the specified sorted sets are empty, then BZMPOP
will block the connection until another client adds members to one of the keys or until the specified timeout elapses. It’s possible to block the connection indefinitely by using a timeout of zero.
The BZMPOP
command was introduced in Redis 7.0.0.
Syntax
The syntax goes like this:
BZMPOP timeout numkeys key [key ...] <MIN | MAX> [COUNT count]
It’s basically the same as ZMPOP
except that BZMPOP
requires the timeout
argument.
Example
Here’s an example of what happens when all keys we pass to the BZMPOP
command contain empty sorted sets:
BZMPOP 1 2 birds cats MIN
Result:
(nil) (1.02s)
Here, I provided a timeout of 1
, which means that it waits for one second if all sorted sets are empty. We can see by the result that it took 1.02 seconds to run, and the result of the operation is nil
.
Passing a timeout
argument of 0
(zero) blocks the connection indefinitely.
This blocking feature is what distinguishes BZMPOP
from ZMPOP
. The ZMPOP
command would simply return nil
without waiting. To demonstrate this, here it is using ZMPOP
:
ZMPOP 2 birds cats MIN
Result:
(nil)
When I ran that code, the result was returned immediately.
When the Key is Not Empty
When there’s a key that contains a non-empty sorted set, BZMPOP
works exactly like ZMPOP
. In the above example, both the birds
and the cats
keys didn’t exist. Let’s create one called cats
:
ZADD cats 1 Meow 2 Fluffy 3 Scratch 4 Purr 5 Bite 6 Bunting
Now let’s run BZMPOP
again:
BZMPOP 1 2 birds cats MIN
Result:
1) "cats" 2) 1) 1) "Meow" 2) "1"
This time my results were returned immediately. There was no waiting period like in the previous example.
Here I provided two sorted sets; birds
and cats
. The birds
key didn’t exist and so it was treated as an empty sorted set. The cats
key did exist with a sorted set, and so the operation was performed against that key.
In this case I specified MIN
, which means that the elements with the lowest scores are popped. By default, only one element is popped and so the element with the lowest score was popped. Using MAX
would’ve popped the element with the highest score.
Let’s take a look at the cats
sorted set now:
ZRANGE cats 0 -1
Result:
1) "Fluffy" 2) "Scratch" 3) "Purr" 4) "Bite" 5) "Bunting"
We can see that Meow
no longer exists in the sorted set.
Pop Multiple Elements
We can use the optional COUNT
argument to pop multiple elements. By default, this is set to 1
but we can specify a different number.
Here’s an example of using the COUNT
argument:
BZMPOP 1 1 cats MIN COUNT 2
Result:
1) "cats" 2) 1) 1) "Fluffy" 2) "2" 2) 1) "Scratch" 2) "3"
This time two elements were popped because I specified a count of 2
.
I also removed the birds
key from the list of keys and so I changed the first argument to 1
instead of 2
.
Let’s take a look at the cats
sorted set now:
ZRANGE cats 0 -1
Result:
1) "Purr" 2) "Bite" 3) "Bunting"
Now there’s only three elements left, because the others have been popped.
When COUNT
is Greater than the Sorted Set’s Cardinality
If the COUNT
argument is a larger number than the number of elements in the sorted set, then all elements are popped.
Example:
BZMPOP 1 1 cats MAX COUNT 10
Result:
1) "cats" 2) 1) 1) "Bunting" 2) "6" 2) 1) "Bite" 2) "5" 3) 1) "Purr" 2) "4"
We can see that all elements were popped from our sorted set. In this case I used the MAX
argument and so it popped the elements with the highest scores. However, given we used a COUNT
that was greater than the sorted set’s cardinality, all elements were popped.
Wrong Data Type
When the key contains the wrong data type, an error is returned:
BZMPOP 1 1 countries MIN
Result:
(error) WRONGTYPE Operation against a key holding the wrong kind of value
In this case, the countries
key contains a set (not a sorted set), and so we got an error.
We can use the TYPE
command to check the key’s data type:
TYPE countries
Result:
set
As suspected, it’s a set.
Non-Blocking Variant
As mentioned, the BZMPOP
command is the blocking variant of ZMPOP
. Therefore, if you need a non-blocking variant, use the ZMPOP
command instead.