【实战总结】使⽤Redis做模糊匹配查询
最近在做⼀个模糊匹配查询的需求,剖析需求本质⽆⾮就是根据⼊参来模糊匹配相关数据进⾏返回展⽰。
由于数据是存储在数据库的,简单实现的话可以考虑使⽤DB的SQL来进⾏模糊匹配查询,⽐较考量的就是如何控制你的SQL以及如果能够⾼效命中索引来优化SQL来实现快速查询了。
由于是全查询的业务,⽽且业务场景对服务响应是有⼀定要求的,如果简单的使⽤数据库恐怕后续峰值难以抗住且也会影响其他同库的读写操作,所以这次打算还是使⽤缓存来解决这种全查询场景。
Redis的性能⾮常棒,⽽且⽀持多种数据结构供开发者存储和调⽤,⽽且提供了⼤量API对开发⾮常友好,⽽且这些API的内部算法也是⾮常考究的,真的是开发利器。
1、需求背景
按照汉字以最左匹配原则进⾏模糊匹配,每次返回不超过固定数量的匹配词即可。
2、设计分析
⾸先要分析设计要解决哪些问题:
Q:⾼并发场景下,如何保证服务可靠且快速响应
A:使⽤Redis做全查询缓存,DB做数据持久化,所有请求打到缓存,保护DB;若缓存失效,把请求拦截直接返回,发送MQ异步请求DB 数据更新缓存;若缓存异常,代码做兜底控制,如果可以置⼊动态配置来控制是否兜底查DB,极端情况下直接服务降级处理不⾛DB。
Q:使⽤Redis哪种数据结构进⾏存储数据?
A:⾸先要考虑需要返回哪些数据,且这些数据的查询可以⽀持模糊查询;由于需求只需要返回名称和对应ID,决定采⽤Hash表进⾏存储;且hash表⽀持模糊查询命令。
3、数据存储
在应⽤启动时,使⽤hmset进⾏批量全量缓存数据更新,这⾥有个细节点,由于是分布式部署,如果不加限制默认每台机器启动都会更新⼀遍,其实是没有必要的,可以做⼀个全局分布式锁进⾏判断和控制,这个不难实现不再细说。redis支持的数据结构
HMSET key field value [field value ...]
要模糊查什么就把模糊查的作为field就可以了,由于我这⾥只需要两个字段,我就借⽤哈希表的数据结构进⾏存储了,如果需要更多字段可以研究使⽤有序集合或者其他数据结构。
4、数据模糊查询
HSCAN key cursor [MATCH pattern] [COUNT count]
由于hscan使⽤了游标,是⼀个增量式命令,每次查询都是返回⼀部分数据,所以不会像keys类命令hang住Redis导致服务短暂停滞,所以它是安全⽆公害的,只要运⽤得当,在⽣产环境是可以放⼼使⽤的,关于缺点要参考:
同⼀个元素可能会被返回多次。 处理重复元素的⼯作交由应⽤程序负责, ⽐如说, 可以考虑将迭代返回的元素仅仅⽤于可以安全地重复执⾏多次的操作上。
如果⼀个元素是在迭代过程中被添加到数据集的, ⼜或者是在迭代过程中从数据集中被删除的, 那么这个元素可能会被返回, 也可能不会, 这是未定义的(undefined)。
在使⽤过程中仔细研究这个命令的底层实现,根据实际业务场景去使⽤。
业务底层还是需要封装下hscan命令,由于是游标查询,最开始cursor我们都设置为0就好,每次从0开始查询,count来控制每次遍历的数量,由于这个命令执⾏的时间复杂度是O(N),所以count越⼤,每次执⾏时间理论上会越长,可以根据实际场景进⾏调整,在遍历时候判断返回的游标cursor是否为0,如果为0代表整个遍历结束。
⽬前只使⽤到最左匹配模糊查询,如上图,我试了下最右匹配、中间模糊也是可以查询到的,可以⽀持后续其他业务诉求。
5、特殊字符处理
由于⼀般我们检索的名称是汉字,存储到Redis可能会有环境问题导致乱码,我⽬前的处理是把汉字转ASCII码进⾏存储,同样查询的时候也是转ASCII码进⾏查询,这样可以解决汉字或者编码带来的乱码问题。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论