Amanullah Tanweer
Amanullah Tanweer

Reputation: 39

Redis zrangebyscore and zincrby under high concurrency

I am facing concurrency problem with redis, my API is build on Nodejs Fastify and i am using fastify-redis in my API call.

I am using two simple methods of redis ZRANGEBYSCORE and ZINCRBY

The problem is under high concurrency ZINCRBY is executed late which results into giving me same value on multiple request.

How can i prevent this under high concurrency is there any method to lock the KEY which was previously executed.

Here is the example of my code

numbers = await redis.zrangebyscore(
            `user:${req.query.key}:${state}`, //key
            0, // min value
            50, // max value
            "LIMIT",
            0, // offset
            1 // limit
        );

if (numbers.length > 0) {
        await redis.zincrby(`user:${req.query.key}:${state}`, 1, numbers[0]);
        res.send(numbers[0]);
    }

Upvotes: 1

Views: 583

Answers (1)

Kevin Christopher Henry
Kevin Christopher Henry

Reputation: 48952

The issue isn't concurrency per se, it's that you have a series of operations that need to be atomic and you haven't done anything to ensure that.

Redis has facilities to try to ensure atomicity, as described here. In your case, since the value from the first operation is used in the second, you couldn't do a simple MULTI and EXEC. You'd have to instead WATCH the key and then retry the operation if it aborted.

The simpler, and recommended approach, though, is just to put your above code into a Lua script, where it can be executed on the server as a single atomic operation.

Upvotes: 1

Related Questions