Redis里怎么搞模糊匹配然后顺带删掉那些东西,挺实用的操作分享
- 问答
- 2025-12-26 15:31:38
- 2
Redis官方文档对KEYS和SCAN命令的说明,以及DEL命令的用法;网络技术博客中关于生产环境使用模式的讨论)
行,咱就直接唠唠在Redis里怎么通过模糊匹配来找钥匙,然后顺手把这些钥匙对应的东西给清理掉,这个操作确实挺实在的,比如你有一大堆临时性的缓存数据,它们的键名都有个共同的前缀,像 temp_session:12345、temp_cache:article:678 这种,现在你想一口气把它们全找出来删了,就得用上这招。
核心就两步:1. 模糊匹配找出所有符合模式的键,2. 把这些键删掉。 听着简单,但里头有几个关键点和坑得特别注意,搞不好会出问题。
第一步:怎么模糊匹配找键?
Redis主要提供两个命令来干这个事:KEYS 和 SCAN,这俩都能用通配符。
-
KEYS命令(来源:Redis命令文档):这是最直接、最“暴力”的,比如你想找所有以temp_session:开头的键,你就直接敲命令:KEYS temp_session:*这个星号 就代表匹配任意字符,它立马会给你返回一个列表,里面全是符合这个模式的键名,简单粗暴,立竿见影。
千万要小心!
KEYS命令有个巨大的缺点:它是阻塞式的。(来源:众多生产环境故障总结和经验分享)啥意思呢?就是当Redis在执行KEYS命令的时候,尤其是你的Redis里存了成百万上千万个键的时候,这个命令会非常慢,它需要遍历整个数据库的所有键,在这期间,Redis服务器会被它“卡住”,没法处理其他任何来自客户端的请求,如果你在生产环境(就是正在对外提供服务的正式系统)里,随便对一个大数据量的Redis实例用了KEYS命令,很可能瞬间导致服务超时、雪崩,这可是个危险操作,大家有个共识:KEYS命令绝对不要在生产环境下使用,最多只在测试环境或者你确定键数量非常少的时候用用。 -
SCAN命令(来源:Redis命令文档,为解决KEYS阻塞问题而设计):这是官方推荐的、安全的替代方案,它也是迭代遍历所有的键,但它的高明之处在于非阻塞,它不是一次性返回所有结果,而是一次只返回一小部分(比如几十个或者几百个),同时给你一个“游标”(cursor),你拿着这个游标,再发起下一次SCAN,它就从上次停下的地方继续找,这样就把一个庞大的、耗时的任务,拆分成很多个快速的小任务,中间Redis就能腾出手来处理其他请求,不会导致服务卡顿。用法大概是这样的:
SCAN 0 MATCH temp_session:* COUNT 100这里的
0表示从游标0开始第一次遍历。MATCH temp_session:*是指定匹配模式,和KEYS的一样。COUNT 100是建议每次返回大概100个元素(只是个提示,不一定完全精确),执行后,它会返回两部分:一个新的游标值,以及本次扫描找到的键列表。 如果新的游标不是0,说明还没遍历完,你就得用这个新游标继续执行SCAN命令,直到返回的游标是0为止,这才表示整个数据库遍历完毕。显然,
SCAN比KEYS麻烦一点,需要写个循环来多次调用,但为了系统的稳定性,这是必须的。
第二步:怎么删除找到的键?
找到键之后,删除就简单了,用 DEL 命令,你可以一次删一个,也可以一次删多个。
- 单删:
DEL key_name - 批量删:
DEL key1 key2 key3 ...
把两步连起来:高效又安全的做法
现在问题来了,怎么把找和删优雅地结合起来?如果你用 KEYS,可以这样(再次强调,仅限测试或极小数据量):
DEL $(redis-cli KEYS "temp_session:*")
这个命令是先执行 KEYS 拿到所有键名,然后传给 DEL 命令,一气呵成,但风险就是 KEYS 的阻塞风险。
正经的做法是用 SCAN 命令迭代,然后分批删除。 因为 SCAN 返回的键列表是一批一批的,我们可以在每一批拿到后,立刻用 DEL 命令删掉这一批,这样边找边删,对服务的影响最小。
你可以写一个脚本来实现这个逻辑,比如用Shell脚本、Python脚本或者Lua脚本,这里用个伪代码表示一下思路:
游标 = 0
循环 {
结果 = SCAN 游标 MATCH 你的模式 COUNT 500
新的游标 = 结果[0]
本次找到的键列表 = 结果[1]
本次找到的键列表 不为空 {
DEL 本次找到的键列表 // 批量删除这一批键
}
新的游标 == 0 {
跳出循环 // 遍历结束了
} 否则 {
游标 = 新的游标 // 继续下一轮
}
}
特别提一下Lua脚本(来源:Redis对Lua脚本的支持):如果你希望这个“查找并删除”的操作是一个原子性的(要么全成功,要么全失败),或者不想在客户端和服务器之间来回传输大量键名,可以考虑用Redis的Lua脚本,把整个SCAN和DEL的逻辑写在一个Lua脚本里,在服务器端执行,但要注意,Lua脚本本身执行时间过长也会阻塞其他客户端,所以里面的 SCAN 逻辑还是要写,避免单次操作太多数据。
总结一下关键点:
- 目的:模糊匹配键并删除。
- 找键:弃用危险的
KEYS,改用非阻塞、分批的SCAN命令。 - 删除:结合
SCAN的迭代,分批使用DEL进行删除。 - 实现:通常需要写一个小脚本(Shell/Python/Lua)来自动化这个循环过程。
- 安全第一:尤其是在处理生产环境的Redis时,任何可能引起阻塞的操作都要极其谨慎,操作前最好先在一个备份数据上测试,或者用
SCAN命令只计数不删除,确认匹配的键数量和预期一致再执行真正的删除。
这么一套下来,这个“模糊匹配顺带删除”的操作就算是被你拿捏了,既实现了功能,又保证了服务的平稳。

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