使用python获取Redis数据库中的所有密钥

tsc*_*zle 53 python database redis

有一篇关于Redis命令的帖子来获取所有可用的密钥,但是我想用Python来做.

有什么办法吗?

Pat*_*ins 83

scan()优于keys()大量的键,因为它为您提供了一个可以使用的迭代器,而不是尝试将所有键加载到内存中.

我的redis中有一条1B记录,我永远无法获得足够的内存来立即返回所有密钥.

扫描键一个接一个

这是一个python代码段,scan()用于从商店获取匹配模式的所有键并逐个删除它们:

import redis
r = redis.StrictRedis(host='localhost', port=6379, db=0)
for key in r.scan_iter("user:*"):
    # delete the key
    r.delete(key)
Run Code Online (Sandbox Code Playgroud)

扫描批次

如果您有一个非常大的要扫描的键列表 - 例如,大于> 100k的键 - 批量扫描它们会更有效,如下所示:

import redis
from itertools import izip_longest

r = redis.StrictRedis(host='localhost', port=6379, db=0)

# iterate a list in batches of size n
def batcher(iterable, n):
    args = [iter(iterable)] * n
    return izip_longest(*args)

# in batches of 500 delete keys matching user:*
for keybatch in batcher(r.scan_iter('user:*'),500):
    r.delete(*keybatch)
Run Code Online (Sandbox Code Playgroud)

我对此脚本进行了基准测试,发现使用500的批量大小比逐个扫描密钥快5倍.批量大小为500似乎是我Macbook Pro本地运行的最佳选择,它可能因网络而异.我测试了10,100,500,1000和10000的批量大小.如果您想了解我如何对其进行基准测试,请与我联系.

请注意,无论您使用的是scan()or keys()方法,操作都不是原子操作,并且可能无法完成.

绝对避免在命令行使用XARGS

我不建议我在其他地方重复发现这个例子.它不适用于unicode键,即使是中等数量的键,速度也非常慢:

redis-cli --raw keys "user:*"| xargs redis-cli del
Run Code Online (Sandbox Code Playgroud)

在这个例子中,xargs为每个键创建一个新的redis-cli进程!让人惊讶.

我将这种方法的基准测试速度比第一个python示例快4倍,在第一个python示例中,它逐个删除每个键,比以500个批量删除的速度慢20倍.

  • izip_longest 在 Python 3 中被重命名为 zip_longest /sf/ask/2704436731/ (4认同)
  • 这里的“批量扫描”部分在这里具有误导性。您可能获得了更好的性能,但这与获取密钥无关,而这正是问题所在。您获得的更好性能可能是通过批量删除密钥而不是一一删除来实现的。 (2认同)

fed*_*qui 44

是的,keys()从StrictRedis模块使用:

>>> import redis
>>> r = redis.StrictRedis(host=YOUR_HOST, port=YOUR_PORT, db=YOUR_DB)
>>> r.keys()
Run Code Online (Sandbox Code Playgroud)

给出一个空模式将获取所有这些模式.根据页面链接:

键(图案= '*')

返回匹配模式的键列表

  • 请注意,不鼓励在生产服务器上使用此命令.如果您拥有大量密钥,Redis实例在处理此请求时将不会响应任何其他请求,这可能需要相当长的时间才能完成. (11认同)
  • 考虑添加对“SCAN”命令的引用,因为它现在是获取每个请求的时间复杂度为 O(1) 的所有键的首选方法。(和所有请求的 O(N)) (2认同)
  • 当您尝试匹配模式而不只是返回所有键时,`r.keys()` 非常慢。考虑使用下面答案中建议的`scan` (2认同)
  • @KonstantineNikolaou 我通知了 OP,他很高兴不接受我的回答以接受另一个。感谢您的报告,我很久以前就使用过这个,但我现在缺乏对该主题的关注来检查什么是最好的。 (2认同)

Bla*_*der 9

import redis
r = redis.Redis("localhost", 6379)
for key in r.scan_iter():
       print key
Run Code Online (Sandbox Code Playgroud)

使用Pyredis库

扫描命令

自2.8.0起可用.

时间复杂度:每次通话都是O(1).O(N)进行完整的迭代,包括足够的命令调用,使光标返回0. N是集合中元素的数量.