有没有更好的方法来计算Redis中的大量键?

时间:2013-06-30 15:11:33

标签: ruby redis

如果我做的话

number_of_keys = redis_instance.keys('foo*').size

但是这个请求有10,000个键,有没有办法加快进程,因为我只想计算它们,而不是先返回整批它们然后再运行ruby .size方法他们要数数呢?

问题是,考虑到我实际上并不需要它们,返回10,000个钥匙有点慢和浪费 - 我只需看看有多少钥匙。

编辑:我应该指定redis_instance是redis class的实例。

2 个答案:

答案 0 :(得分:3)

所以,在说出任何其他内容之前,按照documentation

  

警告:将KEYS视为仅应在其中使用的命令   生产环境非常谨慎。它可能会破坏性能   当它针对大型数据库执行时。这个命令是有意的   用于调试和特殊操作,例如更改密钥空间   布局。不要在常规应用程序代码中使用KEYS。如果你是   想一想在键空间的子集中查找键的方法,请考虑   使用套装。

所以,如果你可以抛出任何东西,你需要计算一个哈希并在那里做一个HLEN而不会让事情变得太乱,那就更好了。

除了警告,你应该100%做这个Lua脚本。毫无疑问,这里的瓶颈将是网络吞吐量,Lua完全解决了这个问题。 Lua将运行您的整个脚本服务器端,因此您将获取所有密钥并在Redis机箱上统计所有密钥而无需任何网络传输,然后您只会发回计数。脚本很简单:

local all_keys = redis.call('KEYS', ARGV[1])
return #all_keys

然后您只需拨打&foo *'作为论点。在纯Redis中,它将是(未经测试的):

EVAL "your_script.lua" 0 'foo*'

之前我还没有在Ruby中使用过Redis,因此您需要将其转换为Ruby。

答案 1 :(得分:1)

在这种情况下,最好使用计数器存储起始计数,然后在添加匹配键时递增计数器。无论你发现哪种计数技巧很快,它仍然依赖于扫描你的密钥空间并寻找匹配。在密钥(例如INCR)上使用INCR starts_with_foo将更快,并且最终可扩展。