Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Concurrent priority queue in redis?

I would like to implement a concurrent priority queue in Redis, with multiple processes on different machines adding items (with scores) and multiple other processes popping these items, lowest score first.

A simple queue can be implemented with LPUSH and RPOP.

Using a ZSET, I can add the items using ZADD and pop them with ZRANGE and ZREM, as long as there is only one reader.

For multiple readers I think I need something like ZPOP which combines ZRANGE and ZREM in a single atomic operation. Otherwise two readers may get the same item from ZRANGE before either can ZREM it. Retrying if ZREM returns 0 would work but is not desirable.

Is there some way I can do this using the current Redis commands? Is there any reason this hasn't been added to Redis already? It seems like it would be a pretty simple command to implement.

like image 303
Wayne Christopher Avatar asked Mar 18 '23 05:03

Wayne Christopher


2 Answers

You can guarantee atomicity if you use a Lua script that does the ZRANGE & ZREM or with a MULTI/EXEC block. This will prevent multiple workers from interfering with each other.

I assume that ZPOP wasn't put in in the first place because it isn't a common use case and, when needed, it can be easily scripted.

like image 56
Itamar Haber Avatar answered Mar 29 '23 23:03

Itamar Haber


you can use redis command: watch

WATCH zset
element = ZRANGE zset 0 0
MULTI
ZREM zset element
EXEC

if exec fails (return a null reply), just repeat those commands.

like image 36
Feiyu Zhou Avatar answered Mar 29 '23 23:03

Feiyu Zhou