Redis里怎么用模糊匹配找Key,正则啥的能不能用起来试试看
- 问答
- 2025-12-30 19:43:24
- 3
在Redis里,你想用模糊匹配的方式找Key,这个需求非常普遍,比如你想看看所有以“user:session:”开头的会话键,或者找出所有包含“temp”的临时键,Redis确实提供了这样的功能,但和你平时在编程里用的正则表达式不太一样,它更简单直接,用的是通配符的模式。
Redis的通配符怎么玩?
Redis主要通过KEYS命令来实现模糊查找,这个命令支持两个特殊的符号:
-
(星号):这个符号代表“任意数量的任意字符”,你可以把它想象成Windows系统里搜索文件时用的。
- 你想找所有以“user:”开头的key,就可以用
KEYS user:*,这会匹配到user:1001、user:profile:1001、user:等等。 - 你想找所有以“123”结尾的key,就用
KEYS *123。 - 你想找所有包含“cache”的key,就用
KEYS *cache*。
- 你想找所有以“user:”开头的key,就可以用
-
(问号):这个符号代表“一个任意字符”,它比星号更精确一点,只占一个字符的位置。
KEYS user:?会匹配像user:1、user:A这样的key,但不会匹配user:10或user:AB,因为只能代表一个字符。KEYS h?llo会匹配hallo、hbllo、hcllo等。
-
字符类(这个稍微高级一点点,但也很简单):用方括号
[]表示,匹配方括号内的任意一个字符。KEYS user:[13579]会匹配user:1、user:3、user:5、user:7、user:9,也就是匹配一位奇数的用户ID。KEYS h[ae]llo会匹配hallo和hello。
重要警告:KEYS命令不能在生产环境乱用!
根据Redis官方文档(来源:Redis官方文档对KEYS命令的说明)的明确警告,KEYS命令是一个非常危险的命令,尤其是在数据量大的生产环境中,原因是:Redis是单线程的,当你在一个拥有数百万个key的Redis实例上执行KEYS *时,这个命令会一次性遍历所有key,并返回所有匹配的结果,在这个命令执行期间,Redis的主线程会被完全阻塞,无法处理任何其他的读写请求,这会导致你的服务瞬间不可用,看起来就像“卡死了”一样。
虽然KEYS命令在测试或者数据量极小的时候用起来很方便,但正规的做法是绝对避免在生产环境使用。
那在生产环境该怎么安全地模糊匹配?
既然KEYS命令这么危险,Redis提供了一个安全的替代方案:SCAN命令。
SCAN命令的核心思想是“迭代式遍历”,它不会一次性返回所有结果,而是每次只返回一小部分(比如几十个或几百个),并给你一个“游标”(cursor),你可以拿着这个游标,再次调用SCAN,它就会从上次停下的地方继续遍历,这样就把一个庞大的、可能阻塞服务的操作,拆分成很多个微不足道的小操作,对服务的影响就降到了最低。
SCAN的用法稍微复杂一点点:
- 第一次调用时,游标从0开始:
SCAN 0 MATCH user:*。 - Redis会返回两个东西:一个是“下一次迭代的游标”(比如是
17),另一个是本次扫描到的key的列表。 - 你接着用新的游标调用:
SCAN 17 MATCH user:*。 - 重复这个过程,直到Redis返回的下一个游标是
0,这表示整个遍历已经完成。
这里的MATCH参数就是用来做模糊匹配的,它使用的通配符规则和KEYS命令一模一样(, , [])。
SCAN命令的好处是显而易见的:无阻塞、可控制,你可以在应用程序里写一个循环,慢慢地、分批地把所有想要的key找出来,同时Redis还能正常服务其他请求,缺点是编程上稍微麻烦一点,而且因为它是在整个数据集中迭代,可能会返回重复的key(但集合去重很容易),而且在整个遍历过程中,如果数据有变化(有新增或删除的key),可能会体现得不完全一致。
关于正则表达式
现在来回答你的第二个问题:“正则啥的能不能用起来试试看?”
答案是:Redis的命令行本身不支持你想象中的那种复杂的正则表达式。
你不能在KEYS或SCAN命令里直接写像\d+(匹配数字)或者[a-zA-Z](匹配字母)这样的完整正则表达式,Redis只支持上面提到的, , []这三种比较简单的通配符模式。
这并不意味着你完全没办法,变通的方法是在客户端处理,具体思路是:
- 放宽条件扫描:先用
SCAN命令,用一个比较宽泛的模式(比如直接用,或者user:*这样的前缀)把可能相关的key都扫描出来,因为SCAN是安全的,所以即使扫描的key多一点,只要分批进行,问题也不大。 - 客户端用正则过滤:在你的应用程序里(比如用Python、Java、Go写的程序),拿到这一批key之后,再用你熟悉的、强大的正则表达式库对这些key进行二次过滤,这样,你就可以使用任何复杂的正则规则了。
你想找出所有以“user:”开头,后面紧跟纯数字的key,Redis的通配符user:*会匹配user:123也会匹配user:abc,不够精确,你可以这样做:
- 用Redis的
SCAN 0 MATCH user:*分批获取所有以“user:”开头的key。 - 在Python程序中,对返回的key列表使用
re.match(r'^user:\d+$', key)来进行判断,只保留那些符合“user:纯数字”规则的key。
总结一下
- 快速测试用
KEYS:在本地开发环境或者数据极少的情况下,可以用KEYS pattern来快速查找,方便直接。 - 生产环境用
SCAN:在任何正式上线的服务中,坚决使用SCAN命令来安全地、非阻塞地进行模糊查找。 - 复杂正则客户端做:Redis本身不支持复杂正则,如果你的匹配规则超出了、、
[]的能力范围,就在用SCAN拿到初步结果后,在应用程序代码里用正则表达式进行过滤。
记住最关键的一点:保护生产环境,远离KEYS命令。

本文由符海莹于2025-12-30发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:http://waw.haoid.cn/wenda/71452.html
