redis底层实现第一步

好几天没有更新博客了,这样不行的,要养成习惯。

redis的底层我还没有研究透彻,只能说研究 了一部分,本来打算看完了之后在写的,不过,为了养成习惯,也为了预防可能的惰性和迷失。

redis 的字符串有点意思,对于运行在服务器上面的信息来说,弱类型很多时候是难免的,所以redis中处理字符的情况远远要大于处理int的情况,所以字符的操作必须优化,而众所周知,c的char[]可是不怎么强大的,有两个操作比较消耗资源,一个是append 字符的时候,一个是计算长度的时候,redis提出了一个叫做sds的东西,就是一个结构体,里面包含三个值,一个记录当前字符的长度length,一个是char数组中还剩下空闲的长度free,一个是字符存储地址,里面包含两种东西,一个是申请了,但是空闲的空间,由free标记,一个是已经存储了的字符长度,由length标记,这样,就可以将字符操作比较消耗资源的两个操作以比较小的代价给解决了。free标记的是空闲的内存,也就是说每次申请内存的时候,redis不会按照刚刚好来申请,而是根据一定的策略申请了多余的内存,这样的优点是以后再次需要内存的时候u,很大的可能性就是不会再次申请了,加快执行的效率,append的时候申请内存是按照用了的字符长度,length的二倍的大小申请的,如果已经使用的内存超过了1MB,那么以后每次申请的内存就是1MB,min(1MB,length),这样内存分配也有的放矢了,sds的使用遍布了redis的底层。

第二个是ziplist 压缩列表,本来以为是很神奇的东西,结果发现跟我毕业设计差不多,简而言之,就是通过一系列精确到位的二进制定义保存字符串列表。开头zlbytes zltail zllen构成ziplist的头,zlbytes,zltail四个字节,zllen两个字节,这十个字节构成了ziplist的头,用来统计和查找表尾节点,zlbytes是表示ziplist目前占用的字节数,zltails到达表尾节点的偏移量,可以不用遍历整个ziplist的时候,找到表尾节点,zllen记录了ziplist的节点数。之后接着的位就是每个节点的具体内容,每个节点里头包括了pre_entry_length ,coding,length,content几个,pre_entype_length记录了前一个节点的长度,是为了方便调转到上一个节点,encoding表示在content里面记录的是整形还是char,什么类型的char,length记录了content的长度,类似于sds的length,最后就是保存内容的content。

还有一个就是让人难以评判的结构,就是整数集和set,应用场景是元素全部是整数,且数量不是很多的时候(512个,可以通过配置修改)。简而言之,把int拆开使用,一共用来存储三种数据,int16,int32,int64 ,这样就节省了空间,一个int64就可以存储4个或者是2个数据了,添加数据的时候,按照有序数组来,需要O(n)的将插入位置之后的数据向后移动一个位置,因为总共的数量不会超过512个,所以是效率时间不会是太大的问题,当元素不再是整数的时候,或者是超过512的时候,存储结构就变成hash。

Leave a comment

Your email address will not be published.

*