当前位置:首页 > 问答 > 正文

Redis模糊查询其实没那么难,教你几招快速搞定那些复杂匹配问题

很多人一听到要在Redis里做模糊查询,就觉得头大,感觉这玩意儿特别复杂,远不如关系型数据库里的SQL语句来得直接,比如在MySQL里,一个简单的LIKE '%keyword%'好像就能解决大部分问题,但其实,Redis也提供了几种非常实用的方法来实现类似“模糊”匹配的效果,一旦用熟了,你会发现它们在某些场景下甚至更高效,今天我们就来聊聊这几招,帮你快速搞定那些复杂的匹配问题。(来源:常见的Redis技术讨论与开发者经验分享)

第一招:万能钥匙——KEYS 命令

这可能是最直接、最广为人知的一招了,KEYS命令允许你使用通配符来查找所有符合给定模式的键,它的用法很简单:

  • (星号):匹配任意数量的任意字符。KEYS user:* 会找出所有以 user: 开头的键。
  • (问号):匹配一个任意字符。KEYS user:? 会找出像 user:1user:A 这样的键,但不会找出 user:10
  • [ ] (中括号):匹配括号内的某一个字符。KEYS user:[123] 会找出 user:1user:2user:3

听起来是不是很强大?确实,在开发环境或者数据量极小的情况下,用KEYS命令来临时排查问题非常方便。这里有个非常重要的“!(来源:Redis官方文档警告以及几乎所有Redis最佳实践指南) 在生产环境中,要极其谨慎地使用KEYS命令,最好完全不用,为什么呢?因为Redis是单线程的,KEYS命令会遍历整个数据库的所有键名,当你的数据库里有几百万甚至上千万个键时,执行一个KEYS *可能会导致Redis服务器短暂地“卡死”,在这期间无法处理任何其他请求,后果可能是灾难性的,请把KEYS命令当作一个调试工具,而不是一个常规的查询手段。

第二招:安全卫士——SCAN 命令

既然KEYS命令这么危险,那我们该怎么办呢?Redis提供了一个更安全的替代方案:SCAN命令,SCAN命令的核心思想是“迭代式”遍历。(来源:Redis官方文档对SCAN命令的说明)

你可以把整个键空间想象成一本很厚的书,KEYS命令的做法是让你一口气把整本书从头到尾翻一遍找出所有带某个关键词的页码,而SCAN命令则是每次只翻几页,记下当前位置,然后歇一下让你处理其他事情,下次再从记下的位置继续翻。

Redis模糊查询其实没那么难,教你几招快速搞定那些复杂匹配问题

它的基本用法是 SCAN cursor [MATCH pattern] [COUNT count]

  • cursor:游标,第一次遍历时设为0,之后使用上次返回的新游标。
  • MATCH pattern:和KEYS一样的模式匹配,MATCH user:*
  • COUNT count:提示每次迭代返回多少元素,只是一个参考值,实际返回的数量可能不同。

使用SCAN命令,你需要在程序里写一个循环,每次调用SCAN并更新游标,直到游标再次变为0,表示遍历完成,这样做的好处是,虽然总的工作量和KEYS命令差不多,但它是分批次进行的,每次只占用一点点服务器资源,不会阻塞其他操作,对生产环境非常友好。当你确实需要遍历所有键进行模糊查找时,SCAN是你的不二之选。

第三招:精准定位——基于数据结构的查询

前面两招都是针对键名的模糊匹配,但很多时候,我们的需求是模糊查询键里面的值,我们用一个Hash结构存储了用户信息,现在想找出所有名字里带“张”的用户,这时候,光靠键名匹配就不行了,需要深入到数据结构内部。

Redis模糊查询其实没那么难,教你几招快速搞定那些复杂匹配问题

对于这种需求,Redis本身没有提供直接的内置命令,常见的解决方案有以下几种:

  1. 维护一个反向索引:这是一种“空间换时间”的思路,我们除了存储user:1001这个Hash键(包含name, age等字段),还可以额外维护一个集合(Set)或有序集合(Sorted Set),键名可以是index:name:张,然后把用户ID1001放进去,这样,当你需要查找名字带“张”的用户时,可以直接用SMEMBERS index:name:张或者更复杂的模式匹配键名(结合SCAN)来快速拿到所有相关的用户ID,再去主键里查询详细信息,这种方法效率最高,但需要你在写入数据时同步维护这些索引,增加了代码的复杂性。

  2. 使用RedisGears或RediSearch等模块:(来源:Redis官方对模块生态的介绍)如果你的需求非常复杂,比如需要全文搜索、拼音搜索等高级功能,那么可以考虑使用Redis的扩展模块,RediSearch就是一个功能强大的全文搜索引擎模块,它可以为Redis中的数据建立复杂的倒排索引,提供类似专业搜索引擎的查询能力,但这属于更高级的用法,需要单独安装和学习。

总结一下

Redis的模糊查询其实并不神秘,关键在于根据你的场景选择合适的方法:

  • 临时查看键名? 在非生产环境,可以小心使用 KEYS
  • 程序里需要安全地遍历键? 一定要用 SCAN 命令。
  • 需要查询值的内容? 考虑设计 反向索引 来优化,或者对于极致需求,探索 RediSearch 这样的强大工具。

希望这几招能让你对Redis的模糊查询有一个清晰的认识,下次再遇到类似的匹配问题,就能胸有成竹地选择最适合的方案了。