我正在尝试从Redis中查找与模式匹配的键列表中存储的值。我尝试使用SCAN
来获取所有值,以便稍后可以使用MGET
。问题是:
SCAN 0 MATCH "foo:bar:*" COUNT 1000
不返回任何值,而
SCAN 0 MATCH "foo:bar:*" COUNT 10000
返回所需的键。我如何强制SCAN
浏览所有现有的键?我需要查看lua吗?
我正在尝试从Redis中查找与模式匹配的键列表中存储的值。我尝试使用SCAN
来获取所有值,以便稍后可以使用MGET
。问题是:
SCAN 0 MATCH "foo:bar:*" COUNT 1000
不返回任何值,而
SCAN 0 MATCH "foo:bar:*" COUNT 10000
返回所需的键。我如何强制SCAN
浏览所有现有的键?我需要查看lua吗?
使用下面的代码,您将扫描来自游标0的前1000个对象。
SCAN 0 MATCH "foo:bar:*" COUNT 1000
结果是,您将获得一个新的光标以进行回叫
SCAN YOUR_NEW_CURSOR MATCH "foo:bar:*" COUNT 1000
扫描接下来的1000个对象。然后,当您将COUNT
从1000增加到10000并检索数据时,您会扫描更多的键,这样就匹配更多的键。
要扫描整个列表,需要重复调用SCAN
,直到游标在响应中返回零(即整个扫描)。
使用INFO
命令获取您的键数量,例如:
db0:keys=YOUR_AMOUNT_OF_KEYS,expires=0,avg_ttl=0
然后调用
SCAN 0 MATCH "foo:bar:*" COUNT YOUR_AMOUNT_OF_KEYS
以下是使用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
。SCAN
不能保证终止。我很难弄清楚游标号是什么以及为什么会随机获取一个空列表或重复项,尽管我知道我刚刚放置了项目。
阅读后:
它更加合理,但仍然存在一些深层次的编程技巧和妥协来迭代集合。
SCAN
并不能保证终止。在大多数情况下,它会终止,但如果 DB 中的项目数量继续增长并超过迭代器,它就不会停止。根据 Redis 官方文档:...仅在可迭代集合的大小保持有限到给定的最大大小时才保证终止
。 - Josh如果您的使用场景涉及Python,或者您只想在机器上安装了Python并且只想一次性获取值,那么如果您使用redis python库中的scan_iter
方法,这将是一个微不足道的任务:
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方法获得的所有键。