跋山涉水 —— 深入 Redis 字典遍历
前言
Redis 字典的遍历过程逻辑比较复杂,互联网上对这一块的分析讲解非常少。我也花了不少时间对源码的细节进行了整理,将我个人对字典遍历逻辑的理解呈现给各位读者。也许读者们对字典的遍历过程有比我更好的理解,还请不吝指教。
一边遍历一边修改
我们知道 Redis 对象树的主干是一个字典,如果对象很多,这个主干字典也会很大。当我们使用 keys 命令搜寻指定模式的 key 时,它会遍历整个主干字典。值得注意的是,在遍历的过程中,如果满足模式匹配条件的 key 被找到了,还需要判断 key 指向的对象是否已经过期。如果过期了就需要从主干字典中将该 key 删除。
那么,你是否想到了其中的困难之处,在遍历字典的时候还需要修改字典,会不会出现指针安全问题?
重复遍历
字典在扩容的时候要进行渐进式迁移,会存在新旧两个 hashtable。遍历需要对这两个 hashtable 依次进行,先遍历完旧的 hashtable,再继续遍历新的 hashtable。如果在遍历的过程中进行了 rehashStep,将已经遍历过的旧的 hashtable 的元素迁移到了新的 hashtable中,那么遍历会不会出现元素的重复?这也是遍历需要考虑的疑难之处,下面我们来看看 Redis 是如何解决这个问题的。
迭代器的结构
Redis 为字典的遍历提供了 2 种迭代器,一种是安全迭代器,另一种是不安全迭代器。
迭代器的「安全」指的是在遍历过程中可以对字典进行查找和修改,不用感到担心,因为查找和修改会触发过期判断,会删除内部元素。「安全」的另一层意思是迭代过程中不会出现元素重复,为了保证不重复,就会禁止 rehashStep。
而「不安全」的迭代器是指遍历过程中字典是只读的,你不可以修改,你只能调用 dictNext 对字典进行持续遍历,不得调用任何可能触发过期判断的函数。不过好处是不影响 rehash,代价就是遍历的元素可能会出现重复。
安全迭代器在刚开始遍历时,会给字典打上一个标记,有了这个标记,rehashStep 就不会执行,遍历时元素就不会出现重复。
迭代过程
安全的迭代器在遍历过程中允许删除元素,意味着字典第一维数组下面挂接的链表中的元素可能会被摘走,元素的 next 指针就会发生变动,这是否会影响迭代过程呢?下面我们仔细研究一下迭代函数的代码逻辑。
值得注意的是在字典扩容时进行rehash,将旧数组中的链表迁移到新的数组中。某个具体槽位下的链表只可能会迁移到新数组的两个槽位中。
迭代器的选择
除了keys指令使用了安全迭代器,因为结果不允许重复。那还有其它的地方使用了安全迭代器么,什么情况下遍历适合使用非安全迭代器呢?
简单一点说,那就是如果遍历过程中不允许出现重复,那就使用SafeIterator,比如下面的两种情况
bgaofrewrite需要遍历所有对象转换称操作指令进行持久化,绝对不允许出现重复
bgsave也需要遍历所有对象来持久化,同样不允许出现重复
如果遍历过程中需要处理元素过期,需要对字典进行修改,那也必须使用SafeIterator,因为非安全的迭代器是只读的。
其它情况下,也就是允许遍历过程中出现个别元素重复,不需要对字典进行结构性修改的情况下一律使用非安全迭代器。
思考
请继续思考rehash对非安全遍历过程的影响,会重复哪些元素,重复的元素会非常多么还是只是少量重复?
欢迎工作一到五年的Java工程师朋友们加入Java架构开发:744677563
本群提供免费的学习指导 架构资料 以及免费的解答
不懂得问题都可以在本群提出来 之后还会有职业生涯规划以及面试指导

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
想要成为一个合格的架构师?看这篇文章就足够了
在互联网圈,架构师这个名号的火热程度堪比产品经理,它在产品经理没火之前就已经风生水起。 仅以本文向带给我许多欢乐和感悟的周星驰致敬。 架构师的定义 乔布斯是苹果的产品架构师,比尔盖茨是微软的首席架构师,马化腾也号称腾讯的首席架构师。 有些人会觉得架构师很神秘,不知道整天脑袋里在想什么。那么架构师到底是什么样的人? 聚焦到 IT 技术领域,基本可以还原,架构师的本质就是更高级更资深的程序员,架构师的能力要求在程序员或者说工程师之上,是一脉相承,有延续性的。 有些大厂因为层级较多(当然也是有更顶尖的人才),高级工程师跳到小厂做个架构师游刃有余。 所以我们并不纠结于工程师进阶架构师的边界到底在哪里,实际上有的公司架构师是正式职位,有的只是项目的临时职务。 架构师是足够复杂、规模较大的系统才需要的角色,当系统架构不那么一目了然,才需要有人在更高的视角上去关注整体性的东西。 架构师是高阶职位,难以通过培训批量生产,严重依赖于个人的工作经验和成长,而且各方面都要求更高。 架构师的经验体现在什么地方呢?举一个例子: 比如一个复杂的分布式系统,时时刻刻处理业务请求,要设计一套机制,保证所有的业务都能处...
- 下一篇
Android架构合集
Android架构合集 Weibo - 欢迎关注,阿里、菜鸟、蚂蚁等招android开发,内推可私信。 著名公司架构 常见架构方法 架构库 著名公司架构 安居客 安居客Android项目架构演进 滴滴 滴滴国际化项目 Android 端演进 携程 携程Mobile架构演化(视频) 携程Android App插件化和动态加载实践 阿里 陶钧谈淘宝客户端应用框架实践 QCon旧金山演讲总结:阿里无线技术架构演进 手机淘宝构架演化实践 手机淘宝Android客户端架构 漫谈移动应用架构设计 大规模团队的Android开发 支付宝钱包客户端技术架构 百度 手机百度Android平台平台化解决方案 腾讯 涅盘新生—Android QQ音乐架构演进 微信Android客户端架构演进之路 饿了么 饿了么移动APP的架构演进
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- CentOS8安装Docker,最新的服务器搭配容器使用
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库
- Windows10,CentOS7,CentOS8安装Nodejs环境
- CentOS7设置SWAP分区,小内存服务器的救世主
- MySQL8.0.19开启GTID主从同步CentOS8
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装