暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Redis 如何做模糊查询

1755

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 在看” 你最好看!

喜欢,就关注我吧!




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

文章转载自PostgreSQL运维技术,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论