Redis如何从海量key中查询出某一固定前缀的key
目录
- 常问问题
- 留意细节
- 给出答案
- 1.用keys指令找出指定模式的key列表
- 2.用scan指令
- SCAN cursor [MATCH pattern] [COUNT count]
- 1.scan指令是一个基于游标的迭代器
- 2.当scan指令的游标参数cursor设置为0时
- 3.scan增量式迭代
- 4.对于增量式迭代命令
- 总结
常问问题
假如Redis里有一亿个key,其中有10万个key是以某个固定的已知的前缀开头的,如何将他们全部找出来?
留意细节
摸清数据规模(数据量是多大?根据实际场景去作答),问清楚边界。
给出答案
1.用keys指令找出指定模式的key列表
- 缺点:一次性需要返回所有的key,如果可以的数量过大,会使服务器卡顿,对于内存python的消耗和redis服务器都是隐患。
2.用scan指令
- 无阻塞地提取出指定前缀的key列表,scan每次执行都只会返回少量元素,所以可以用于生产环境,不会出现像keys命令带来的可能会阻塞服务器问题。
SCAN cursor [MATCH pattern] [COUNT count]
1.scan指令是一个基于游标的迭代器
命令每次被调用都需要上一次调用返回的游标作为该次调用的游标参数(cursor),以此来延续之前的迭代过程。
2.当scan指令的游标参数cursor设置为0时
- 服务器将开始一次新的迭代,而当服务器向用户返回值为0的游标时,就表示迭代已经结束。
- 以0作为游标开始新一次的迭代,一直调用游标指令直到游标返回0,我们称这个过程为一次完整的遍历。
3.scan增量式迭代
- 并不保证每次php执行都会返回某个给定数量的元素,甚至可能会返回0个元素,但www.devze.com只要命令返回的游标不是0,应用程序就不应该将程序视为结束。
- 命令返回的元素数量总是符合一定规则的,对于一个大数据集来说,增量式迭代命令每次最多可能会返回数十个元素,而对于一个足够小的数据级来说,可能会一次迭代返回所有的key。
- 类似于keys指令,scan可以通过给定match参数的方式,传入要查找键位的模糊匹配方式,让命令只返回和给定的模式相匹配的元素。
4.对于增量式迭代命令
- 是没有办法保证每次迭代所返回的元素数量的,可以使用count选项,对命令的行php为进行一定程度上的调整。
- count选项的作用,就是让用户告知迭代命令,在每次迭代中应该从数据集里返回多少元素。
- 使用count选项对于增量式迭代命令相当于是一种提示,大多数情况下这种提示都是比较有效的控制了返回的数量的,但count选项并不能严格地控制返回的数量,只能是一个大致的约束,并非每次迭代都会返回count数量的元素js,用户可以在每次迭代根据自己的需要随意改变count值,只要将上次迭代返回的游标用在下次迭代即可。
127.0.0.1:6379> scan 0 match k1* count 10 1) "11009983" 2) 1) "k15183267" 2) "k18983203" 3) "k14348902" 127.0.0.1:6379> scan 11009983 match k1* count 10 1)"23902345" 2) 1) "k17203743" 2) "k18324732" 3) "k11028343" 4) "k11143424" 5) "k12304823" 127.0.0.1:6379> scan 23902345 match k1* count 10 1) "24080390" 2) 1) "k12438294" 2) "k18392744" 3) "k14320420" 4) "k11043243"
使用SCAN指令获取到的结果可能会重复,后端可以用hashSet收集结果,以达到去重的效果。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程客栈(www.devze.com)。
精彩评论