Redis扫描计数:如何强制SCAN返回与模式匹配的所有键?

时间:2015-10-16 09:23:32

标签: redis

我试图找出存储在与redis模式匹配的键列表中的值。我尝试使用SCAN,以便稍后我可以使用MGET获取所有值,问题是:

SCAN 0 MATCH "foo:bar:*" COUNT 1000

不返回任何值,而

SCAN 0 MATCH "foo:bar:*" COUNT 10000

返回所需的键。 如何强制SCAN查看所有现有密钥?我是否必须为此寻找lua?

3 个答案:

答案 0 :(得分:23)

使用下面的代码,您将从光标0

扫描1000第一个对象
SCAN 0 MATCH "foo:bar:*" COUNT 1000 

结果你会得到一个新的光标来回忆

SCAN YOUR_NEW_CURSOR MATCH "foo:bar:*" COUNT 1000

扫描1000下一个对象。然后,当您将COUNT从1000增加到1000并检索数据时,您扫描更多的键,然后在您的情况下匹配更多的键。

要扫描整个列表,您需要调用SCAN,直到光标给出响应返回零(即整个扫描)

使用INFO命令获取您的密钥数量,如

  

DB0:键= YOUR_AMOUNT_OF_KEYS,到期= 0,avg_ttl = 0

然后致电

SCAN 0 MATCH "foo:bar:*" COUNT YOUR_AMOUNT_OF_KEYS

答案 1 :(得分:14)

对于有兴趣使用python redis库感兴趣的人,请将其放在此处:

import redis
redis_server = redis.StrictRedis(host=settings.redis_ip, port=6379, db=0)
mid_results = []
cur, results = redis_server.scan(0,'foo:bar:*',1000)
mid_results += results

while cur != 0:
    cur, results = redis_server.scan(cur,'foo:bar:*',1000)
    mid_results += results

final_uniq_results = set(mid_results)

我花了几天时间才弄明白这一点,但基本上每个scan都会返回一个元组。

示例:

(cursor, results_list)

(5433L, [... keys here ...])
(3244L, [... keys here, maybe ...])
(6543L, [... keys here, duplicates maybe too ...])
(0L, [... last items here ...])
  • 继续扫描cursor,直到它返回0
  • 保证会返回0
  • 即使扫描在扫描之间返回空results_list
  • 但是,正如@Josh在评论中指出的那样,SCAN无法保证终止。

我很难弄清楚光标编号是什么以及为什么我会随机获得一个空列表或重复项目,但即使我知道我刚刚放入了项目。

阅读后:

它更有意义,但仍然有一些深度编程魔术和妥协发生迭代集。

答案 2 :(得分:0)

如果在scan_iter python库上使用redis方法,请记住这是一项琐碎的任务:

from redis import StrictRedis

redis = StrictRedis.from_url(REDIS_URI)

keys = []
for key in redis.scan_iter('foo:bar:*', 1000):
    keys.append(key)

最后,keys将包含您应用@khanou方法所获得的所有键。

这比做shell脚本更有效,因为它们在循环的每次迭代中都会产生一个新的客户端。