如何计算Redis中所有Key的值总和

7
在Redis数据库中,我有许多以字符串类型保存应用程序中的下载时间的键,例如:
   Key            value
20131028:1         100
20131028:2         15
20131028:3         10
..........

我想通过Redis命令将所有键的值相加。
4个回答

17

Redis并不是设计用来做这种事情的。你最好选择关系型数据库、MongoDB或类似ElasticSearch的东西。

不过,如果你确实需要这样做(可以从shell中启动):

$ redis-cli keys '20131028:*' | awk '{print "get "$1}' | redis-cli | awk '{x+=$1} END { print x }'

另一种方法是使用Lua服务器端脚本:

$ redis-cli eval "local keys = redis.call('keys',KEYS[1]) ; local sum=0 ; for _,k in ipairs(keys) do sum = sum + redis.call('get',k) end ; return sum" 1 '20131028:*'

如果Redis实例中有许多键,则两种情况下的性能都会变差,并且在扫描键时,该实例将被所有连接阻塞。


3
以防某些人偶然看到这个答案,另一个好的选择(如果可以的话)是将你的值添加到一个单独的键中,就像使用INCRBY存储一样。然后,只需获取先前计算的值即可。 - Lisandro

5
自Redis v2.6起,最棒的功能之一就是在Redis服务器上执行Lua脚本。
127.0.0.1:6379> EVAL "local sum = 0 local i=1 local a1 = redis.call('hvals','Key') while(a1[i]) do sum=sum+a1[i] i=i+1 end return sum" 0

一个重要的注意点是 Redis 服务端的 lua 脚本会阻塞 EVERYTHING,这在大多数情况下都是一个致命缺陷。来源:stackoverflow.com/a/30896608/2440

1

我认为最好使用mget命令,一次性获取所有键的值,而不是为每个键发出一个命令。这样你只需要一次调用redis即可获得所有结果,并且只需将它们相加即可。当然,这仅在事先知道键的情况下才有效...


0
使用 Redis Lua:
eval "local s = 0 for _,v in ipairs(redis.call('hvals', KEYS[1])) do s = s + v end return s" 1 Key

可以使用 script load 命令保存脚本,然后使用 evalsha 命令对任何哈希键重复使用该脚本。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接