Redis模糊查询的几种实现方法
作者:IT利刃出鞘
简介
说明
本文介绍Redis模糊查询的方法。
官网网址
https://redis.io/commands/keys/
https://redis.io/commands/scan/
Redis模糊查询键的方法
Redis提供了两种模糊查询键的方法:KEYS , SCAN。推荐用SCAN,下边会介绍。
模糊查询的通配符
KEYS和SCAN都支持glob通配符中的三个:*,?,[]:
- *:通配任意多个字符
- ?:通配单个字符
- []:通配括号内的某一个字符
示例
- h?llo
- 匹配 hello, hallo and hxllo
- h*llo
- 匹配 hllo、heeeello
- h[ae]llo
- 匹配 hello、hallo
- 不匹配 hillo
- h[^e]llo
- 匹配 hallo、hbllo…
- 不匹配 hello
- h[a-b]llo 匹配 hallo and hbllo
KEYS
说明
KEYS指令会一次性查出所有满足条件的key(没有 offset、limit 参数)。keys 算法是遍历算法,复杂度是 O(n)。
数据量大时会有问题:redis 是单线程的,操作都是原子的,如果实例中有千万级以上的 key,这个指令就会导致 Redis 服务卡顿,所有读写 Redis 的其它的指令都会被延后甚至会超时报错,可能会引起缓存雪崩甚至数据库宕机。
指令格式
KEYS pattern
pattern即key的正则表达式。
示例
先写入一些数据:
192.168.xxx.21:6379[2]> set hello 1 OK 192.168.xxx.21:6379[2]> set word 1 OK 192.168.xxx.21:6379[2]> set hellp 1 OK 192.168.xxx.21:6379[2]> set ahellog 1 OK 192.168.xxx.21:6379[2]> set hellog 1 OK
查询:
192.168.xxx.21:6379[2]> keys * 1) "hello" 2) "hellog" 3) "hellp" 4) "word" 5) "ahellog" 192.168.xxx.21:6379[2]> keys *hell* 1) "hello" 2) "hellog" 3) "hellp" 4) "ahellog" 192.168.xxx.21:6379[2]> keys hell* 1) "hello" 2) "hellog" 3) "hellp" //知道前面的一些字母,忘记了最后一个字母 192.168.xxx.21:6379[2]> keys hell? 1) "hello" 2) "hellp" //知道前面的一些字母,忘记了最后两个个字母 192.168.xxx.21:6379[2]> keys hell?? 1) "hellog" //知道前面四个字母,最后一个字母有可能是p t y 其中的一个 192.168.xxx.21:6379[2]> keys hell[pty] 1) "hellp" 192.168.xxx.21:6379[2]>
SCAN
说明
Redis 2.8版本引入,目标是解决keys命令的一些问题,特点:
- 复杂度O(n),通过游标分步进行的,不会阻塞线程;
- 提供 limit 参数,可以设置每次返回结果的数据量,limit只是对增量式迭代命令的hint,返回的结果可多可少;
- 支持模式匹配功能;
- 服务器不需要为游标保存状态,游标的唯一状态就是 scan 返回给客户端的游标整数;
- 返回的结果可能会有重复,需要客户端去重复;
- 无法提供完整的快照遍历,即遍历过程中若有数据修改,改动后的数据可能遍历不到;每次返回的数据条数不一定,极度依赖内部实现;
- 单次返回的结果是空的并不意味着遍历结束,而要看返回的游标值是否为零
SCAN不是从第一维数组的第 0 位一直遍历到末尾,而是采用高位进位加法来遍历。之所以使用这样特殊的方式进行遍历,是考虑到字典的扩容和缩容时避免槽位的遍历重复和遗漏。
高位进位法从左边加,进位往右边移动,同普通加法正好相反。但是最终它们都会遍历所有的槽位并且没有重复。
指令格式
SCAN cursor [MATCH pattern] [COUNT count] [TYPE type]
- cursor
- 游标,当次遍历的起始位置
- pattern
- 与Keys命令中的patterns相同,支持通配符匹配
- count
- 返回数据条数。默认为10
- 如果MATCH选项没有指定,则返回条数可能大于等于这个数。因为Redis对全局哈希表的每个哈希槽进行遍历,一旦发现拿到的元素个数大于了count,就停止遍历。若一个桶里有多个元素,这时返回的元素就有可能多于count一点了。
- type:
- Redis 6.0 支持的参数,指定返回Key的类型,类型可选值与 TYPE命令相同:string, list, set, zset, hash and stream。
第一次遍历时,cursor 值为 0,然后将返回结果中第一个整数值作为下一次遍历的 cursor。一直遍历到返回的 cursor 值为 0 时结束。
示例
192.168.xxx.21:6379[2]> keys * 1) "hello" 2) "hellog" 3) "hellp" 4) "word" 5) "ahellog" 192.168.xxx.21:6379[2]> scan 0 match *ll* count 2 1) "5" 2) 1) "hellp" 2) "hello" 192.168.xxx.21:6379[2]> scan 5 match *ll* count 2 1) "0" 2) 1) "hellog" 2) "ahellog" 192.168.xxx.21:6379[2]>
到此这篇关于Redis模糊查询的几种实现方法的文章就介绍到这了,更多相关Redis模糊查询内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!