Redis的列表增量

42fyovps  于 2023-10-15  发布在  Redis
关注(0)|答案(1)|浏览(136)

假设我在redis中有一个列表,上面有一个分布式服务,其思想是分布式系统将数据写入这个列表,然后可以由其他主机查询。
给出一个这样的列表:

1,2,3,4,1

我希望能够执行像increment the first element by 5increment the second element by 2这样的操作,以获得最终的结果列表:

6,4,3,4,1

由于服务是分布式的,我不能只是抓取列表,然后由服务进行计算,然后设置,因为两台机器可能会尝试向列表中添加1,但由于它们抓取了相同的列表,我们将有一个竞争条件。
我也不能通过上游强制执行一致的哈希,因为热键可能具有高负载并导致数据倾斜,所以我需要一个解决方案,可以通过上游的循环或其他非哈希算法进行负载平衡。
我怎样才能做到这一点与redis?

ltqd579y

ltqd579y1#

您可以使用以下两个命令来实现您的目标:

  1. LINDEX:获取给定索引处的值。
  2. LSET:将给定索引处的值设置为递增值。
    为了使这两个命令原子化,使其在分布式环境中工作。您可以将这两个命令 Package 到Lua script中:
local key = KEYS[1]
local index = ARGV[1]
local incr = ARGV[2]

local val = redis.call('lindex', key, index)
if not val then return nil end

val = tostring(tonumber(val) + tonumber(incr))
redis.call('lset', key, index, tonumber(val) + incr)

return val

但是,LINDEXLSET都是慢命令(特别是对于长列表),即时间复杂度O(N)您可能需要使用更有效的数据结构重新设计代码。

相关问题