Redis快速扫描Scan
Posted 架构技术栈
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Redis快速扫描Scan相关的知识,希望对你有一定的参考价值。
在平时我们维护线上Redis的时候需要从n个key里面找到某些特定规则的key,可能查看某些key可能清理某些不需要的key,可能我们第一印象就是keys这个指令,我们可以使用这个指令匹配我们想要的key,下面我们来试试。
> mset name1 a name2 a na1me a na2me a
OK
> keys name*
1) "name"
2) "name2"
3) "name1"
> keys na*me
1) "name"
2) "na1me"
3) "na2me"
这个指令使用非常简单,但是还是存在非常多的问题:
没有一个类似获取某几条或某个区间的搜索,比如我只想要搜索第一条,比如我想分页搜索获取第一页的10条数据。
keys的方法是遍历整个redis树,执行效率是O(n),所以当我们搜索的key非常庞大的时候。必须等到这个指令执行完后才能执行其他指令,redis搜索会延迟,这样会阻塞其他指令或者延迟等问题。
所以针对这个问题,我们的Redis在2.8版本提出了scan这个指令,那么这个指令有哪些特色呢?
复杂度虽然也是O(n),但它是通过游标分步进行的,不会阻塞线程 。
提供limit参数,可以控制每次返回结果的最大条数,limit只是个hint,返回的结果可多可少。
同keys一样,它也提供模式匹配功能。
服务器不需要为 游标保存状态 ,游标的唯一状态就是 scan 返回给客户端的游标整数。
返回的结果可能会有重复,需要客户端去重,这点非常重要。
遍历的过程中如果有数据修改,改动后的数据能不能遍历到是不确定的。
单次返回的结果是空的并不意昧着遍历结束,而要看返回的游标值是否为零。
..........漫长的添加数据
> scan 0 match name* count 10
1) "30"
2) 1) "name3"
2) "name9"
3) "name12"
4) "name"
5) "name6"
6) "name8"
7) "name11"
8) "name4"
9) "name2"
10) "name7"
> scan 30 match name* count 10
1) "0" #游标为0,没有数据了
2) 1) "name10"
2) "name5"
3) "name1"
首先我们介绍redis整个模型,redis简单来讲其实就是一个大的字典,关于字典不了解的同学可以查看我的redis字典基础。字典是由一维数组+链表构成,那么我们把这个一维数组叫做槽当然也有叫桶的,那么scan遍历的时候就是遍历这个槽,那么在上面我们发现有时候我们想返回10条记录,但是redis返回的并没有10条,这是因为我们的scan遍历槽,每个槽下面不一定有链表或者链表值不一定只有一个,所以我们在有些时候使用scan返回的数据是不规则的就是这个原因。
scan的遍历顺序和我们普通的顺序不同,普通方式就是从0->1->2->3....这样遍历下去,而scan的遍历规则是反过来的,这样的特殊遍历方式是考虑到字典扩容和内存回收字典收缩时避免槽位重复或者冲突。scan指令扩展
scan指令是一系列指令,除了可以遍历所有的key之外,还可以对指定的容器
集合进行遍历。
比如zscan遍历zset集合元素,hscan遍历hash字典的元素,sscan遍历set集合的元素。
它们的原理同scan类似,因为hash底层就是字典,set也是一个特殊的hash(所有的value指向同一个元素,zset内部也使用了字典来存储所有的元素内容。
比如我们在操作hash或者zset的时候,它的底层实现是一个字典,我们知道当字典的值到达一定程度的时候就会扩容,每次扩容的时候都会开辟一个更大的内存空间,如果在集群环境中,这个key或被迁移或被删除会影响系统性能导致系统卡顿现象,我们在运维redis系统的时候如果说redis内存大起大落的很有可能就是大key回收导致的。
那么我们在开发过程中如何避免呢?这里我们就需要用到scan指令了,对于扫描出来的每一个key,使用type指令获得key的类型,然后使用相应数据结构的size或者len方法来得到它的大小,对于每一种类型,将大小排名的前若干名作为扫描结果展示出来。
上面这样的过程需要编写脚本,比较烦琐,不过Redis官方已经在redis-cli指令
redis-cli -h 127.0.0.1 -p 7001 --bigkeys -i 0.1
一名正在抢救的coder
笔名:mangolove
以上是关于Redis快速扫描Scan的主要内容,如果未能解决你的问题,请参考以下文章
ESP32-C3入门教程 网络篇①——WiFi Scan 快速扫描附近AP无线热点
Combine框架中两个相近操作符scan和reduce探究