你可能会抱有疑问:我只是使用Redis的功能并且公司的运维同事都已经搭建好了平台,只需要在线申请一下配置和获取连接的地址就可以愉快地使用了,为啥还要这么深入的理解底层的数据结构呢?有啥用呢?
其实这个问题可以分几个方面去回答吧,笔者试着去解释一下原因:
好奇心 作为技术人员,没有好奇心会让我们错过很多精彩,难道你对如此强悍的NoSQL是如何跑起来的不感兴趣吗?好奇心让我们知道的更多,也让我们不知道的更多;
辩证的职业素养 无论是996还是快速迭代,让很多人陷入了网上找找、github找找、改改、跑起来万事大吉的循环,但是这种确实是温水煮青蛙,长此以往我们将渐渐失去判断力,再者国内的文章或者技术点说明基本上都是抄来抄去,没有好的鉴别能力往往就走很多弯路,在这个过程中职业素养就显得意义重大,算是比较核心的竞争力了;
善于思考的习惯 个人认为了解源码的一个好处是能对其中的原理有一定认识,不至于完全黑盒子一样使用,调包Boy或者API工程师往往在遇到一些问题是束手无策,因为不知道是什么原因造成的。更重要的一个好处在于对源码的学习本质上是相同问题的迁移,换句话说,我们有时候抱怨自己接触不到高难度的项目,无法快速提高自己的能力,但是个人觉得如果能力不够给你高难度项目只能让你失眠,因为当没有可借鉴可参考的过往项目时会让你束手无策,因为从0-1做一个好项目的能力不是一天养成的。深入研究开源工程的实现细节能让我们置身相同的境况来思考问题,假如自己被指定去完成该任务,那么要如何实现呢?
胸有成竹的能力 我们有个成语叫庖丁解牛,就是说我们掌握了事物的客观规律,就能运用自如。经验丰富的人在拿到一个任务之后,脑海里便可以浮现出这个任务需要被拆解成几部分,设计的重难点是什么,其中可能出现的坑是什么,需要使用哪些方法来解决特殊的问题,个人感觉阅读源码可以让你慢慢获得这种能力,试想你和大师面对一样的问题,你先深入思考如何去做,然后再仔细研究大师的方案,久而久之自己的功力也必然会提升,我觉得这也是研究开源工程源码最重要的原因。
说了这么多,无非是想表达,带着思考去学习,受益的必然是你自己,大的方针政策是正确的,剩下的就是一步步去执行了,源码工程千千万,那也不必着急,核心的思想并没有那么多,怕什么真理无穷,进一寸有一寸的欢喜!
Q6:Redis的ziplist是如何实现的?压缩列表的连锁更新的原因了解吗?
前面的文章介绍了zset和hash在数据量少且长度满足一定条件的基础上就会选择使用ziplist来进行存储。
当然后面antirez又推出了quicklist的结构,后续可以聊聊quicklist,不过快速链表也是基于压缩列表实现的,ziplist是一种使用特殊编码的内存连续型的数据结构,让我们来一起揭开ziplist的神秘面纱吧。
1.如何设计ziplist先不看Redis的对ziplist的具体实现,我们先来想一下如果我们来设计这个数据结构需要做哪些方面的考虑呢?思考式地学习收获更大呦!
考虑点1:连续内存的双面性
连续型内存减少了内存碎片,但是连续大内存又不容易满足。
这个非常好理解,你和好基友三人去做地铁,你们三个挨着坐肯定不浪费空间,但是地铁里很多人都是单独出行的,大家都不愿意紧挨着,就这样有2个的位置有1个的位置,可是3个连续的确实不好找呀,来张图:
考虑点2: 压缩列表承载元素的多样性
待设计结构和数组不一样,数组是已经强制约定了类型,所以我们可以根据元素类型和个数来确定索引的偏移量,但是压缩列表对元素的类型没有约束,也就是说不知道是什么数据类型和长度,这个有点像TCP粘包拆包的做法了,需要我们指定结尾符或者指定单个存储的元素的长度,要不然数据都粘在一起了。
考虑点3:属性的常数级耗时获取
就是说我们解决了前面两点考虑,但是作为一个整体,压缩列表需要常数级消耗提供一些总体信息,比如总长度、已存储元素数量、尾节点位置(实现尾部的快速插入和删除)等,这样对于操作压缩列表意义很大。