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

Dar*_*ous 21 redis

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

SCAN 0 MATCH "foo:bar:*" COUNT 1000
Run Code Online (Sandbox Code Playgroud)

没有返回任何值,而

SCAN 0 MATCH "foo:bar:*" COUNT 10000
Run Code Online (Sandbox Code Playgroud)

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

kha*_*nou 26

使用下面的代码,您将从光标0扫描1000第一个对象

SCAN 0 MATCH "foo:bar:*" COUNT 1000 
Run Code Online (Sandbox Code Playgroud)

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

SCAN YOUR_NEW_CURSOR MATCH "foo:bar:*" COUNT 1000
Run Code Online (Sandbox Code Playgroud)

扫描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
Run Code Online (Sandbox Code Playgroud)

  • 是的,这不是生产中的正确方法.更好的是迭代光标,为此做SCAN.迭代直到光标返回零进行全扫描.这将每次扫描计数值. (3认同)
  • 我如何强制 SCAN 查看所有现有密钥以查看是否存在匹配项? (2认同)

jmu*_*sch 15

对于有兴趣如何使用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)
Run Code Online (Sandbox Code Playgroud)

我花了几天时间搞清楚这一点,但基本上每个scan都会返回一个元组.

例子:

(cursor, results_list)

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

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

看完之后:

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


Joã*_*aas 5

如果您的用例涉及 Python,或者您只想获取一次值并且机器上安装了 Python,那么如果您scan_iterredispython 库上使用该方法,那么这是一项微不足道的任务:

from redis import StrictRedis

redis = StrictRedis.from_url(REDIS_URI)

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

最后,keys将包含通过应用 @khanou 的方法获得的所有密钥。

这也比执行 shell 脚本更有效,因为这些脚本在循环的每次迭代中都会生成一个新客户端。