高并发下的redis zrangebyscore和zincrby
Redis zrangebyscore and zincrby under high concurrency
我面临 Redis 的并发问题,我的 API 是基于 Nodejs Fastify 构建的,我在 API 调用中使用 fastify-redis。
我正在使用redis的两种简单方法ZRANGEBYSCORE和ZINCRBY
问题是在高并发下 ZINCRBY 执行晚了,导致在多个请求上给我相同的值。
高并发下如何防止,有什么方法可以锁定之前执行过的KEY
这是我的代码示例
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]);
}
问题不在于并发本身,而是你有一系列需要原子化的操作,而你没有做任何事情来确保这一点。
如 here 所述,Redis 具有尝试确保原子性的工具。在您的情况下,由于第一个操作的值在第二个操作中使用,因此您无法执行简单的 MULTI
和 EXEC
。您必须改为 WATCH
键,然后在操作失败时重试该操作。
不过,更简单且推荐的方法是将上述代码放入 Lua script,它可以作为单个原子操作在服务器上执行。
我面临 Redis 的并发问题,我的 API 是基于 Nodejs Fastify 构建的,我在 API 调用中使用 fastify-redis。
我正在使用redis的两种简单方法ZRANGEBYSCORE和ZINCRBY
问题是在高并发下 ZINCRBY 执行晚了,导致在多个请求上给我相同的值。
高并发下如何防止,有什么方法可以锁定之前执行过的KEY
这是我的代码示例
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]);
}
问题不在于并发本身,而是你有一系列需要原子化的操作,而你没有做任何事情来确保这一点。
如 here 所述,Redis 具有尝试确保原子性的工具。在您的情况下,由于第一个操作的值在第二个操作中使用,因此您无法执行简单的 MULTI
和 EXEC
。您必须改为 WATCH
键,然后在操作失败时重试该操作。
不过,更简单且推荐的方法是将上述代码放入 Lua script,它可以作为单个原子操作在服务器上执行。