Redis提供了两种模糊查询键的方法:KEYS , SCAN,但是它们在实现和使用上有一些区别。
keys命令:keys命令是个阻塞式命令,它会一次性遍历整个数据库来匹配模式,并且将匹配模式的键一次性地返回给客户端。这种算法的优点是简单直接,对于小型数据库或者匹配模式较少的情况下,影响较小。但是生产环境极易造成服务器阻塞,生产环境要慎用。 scan命令:scan命令使用游标(cursor)方式来逐步迭代匹配的键。它将匹配的键分批返回,以减轻服务的阻塞和性能压力。SCAN命令的算法是基于近似随机采样的算法。它使用一个游标来记录当前迭代的位置,并在每次迭代时返回一批键。迭代过程中,服务器会根据游标位置和一定的采样数量来获取匹配的键。这种算法的优点是能够提供相对较好的性能和减少阻塞的影响,特别是对于大型数据库和匹配模式较多的情况。
keys命令
keys命令的语法:
KEYS pattern
keys使用示例
# 查找以 "user:" 开头的所有键
KEYS user:*
# 查找以 ".jpg" 结尾的所有键
KEYS *\.jpg
# 查找包含 "product" 字符串的所有键
KEYS *product*
# 查找以 "user:" 开头且包含数字的所有键
KEYS user:[0-9]*
scan命令
scan命令的语法如下:
SCAN cursor [MATCH pattern] [COUNT count]
● cursor:表示当前的游标位置,用于指定从哪个位置开始迭代遍历。初始游标通常为 0。● MATCH pattern(可选):指定一个模式来匹配键名。只有与模式匹配的键会被返回。模式可以包含通配符 *(匹配零个或多个字符)和 ?(匹配一个字符)。● COUNT count(可选):指定每次迭代返回的键的数量。这可以用于控制每次迭代的工作量和网络传输的开销。如果不指定 COUNT 参数,默认返回 10 个键。使用 SCAN 命令时,您需要在每次迭代中根据返回的新游标(cursor)继续调用 SCAN 命令,直到游标返回 0,表示遍历完成。
scan使用示例
# 使用 SCAN 迭代查找以 "user:" 开头的所有键,并每次返回 10 个键
SCAN 0 MATCH user:* COUNT 10
# 使用 SCAN 迭代查找以 ".jpg" 结尾的所有键,并每次返回 100 个键
SCAN 0 MATCH *\.jpg COUNT 100
# 使用 SCAN 迭代查找包含 "product" 字符串的所有键,并每次返回 50 个键
SCAN 0 MATCH *product* COUNT 50
# 使用 SCAN 迭代查找以 "user:" 开头且包含数字的所有键,并每次返回 20 个键
SCAN 0 MATCH user:[0-9]* COUNT 20
SCAN命令可以通过添加COUNT参数来控制每次迭代返回的键的数量。COUNT参数用于指定每次迭代返回的键的最大数量,以减少单次迭代的工作量。COUNT参数并不保证每次迭代都返回指定数量的键,它仅用于指定每次迭代的最大数量。实际返回的键的数量可能会小于指定的COUNT值,但绝不会超过它。
scan命令返回的结果是一个包含两个元素的数组:
1.第一个元素是一个新的游标(cursor),我们可以将该游标作为参数传递给下一次scan命令,以获取下一批匹配的键。
2.第二个元素是一个数组,包含了当前批次匹配的键。
{"cursor":"41943040","result":["key1","key2"]}
需要注意的是,SCAN 命令需要使用游标(cursor)来进行迭代,并根据返回的游标值执行下一次迭代。在实际使用中,需要逐步迭代,每次执行scan命令时,将上一次返回的游标作为参数传递给下一次scan命令,直到游标值为0即可,以确保获取所有匹配的键。
我们可以通过如下python脚本,使用scan命令,找到redis中所有匹配的模式。
import redis
def find_keys_with_pattern(pattern):
r = redis.Redis(host='localhost', port=6379, db=0)
cursor = '0'
keys = []
while cursor != '0':
cursor, scan_keys = r.scan(cursor=cursor, match=pattern)
keys.extend(scan_keys)
return keys
pattern = 'product'
matching_keys = find_keys_with_pattern(pattern)
print(matching_keys)
总结
于开发同学来说,可能更习惯于用keys命令,但是在生产环境大数据量的场景下,这个命令往往会造成服务器阻塞,所以DMS上我们禁用了keys命令,仅支持使用scan命令,以保障线上服务的性能和安全性。但是需要注意的是scan命令,也需要适当地设置匹配模式和每次迭代返回键的数量,以平衡性能和准确性。线上count n的数据量建议不超过1000。
redis命令参考:
https://redis.io/commands/scan/
https://redis.io/commands/keys/
老板们都看到这儿了,下面的犷诰卡片帮我点下吧!

点个“赞 or 在看” 你最好看!

👇👇👇 谢谢各位老板啦!!!




