【redis基本数据结构底层实现】

redis基本数据结构底层实现


String

redis在内部维护了一个数据结构 sds (中文叫做简单动态字符串)

用C语言的char来表示的话呼吁还有几种缺点

1.字符串的修改会造成频繁的内存分配从而导致效率

2.然后c语言的字符串结尾都有一个\0的这种标识符,表示该字符串已结尾,但是在一些特殊的字符串的时候会丢失后面的字符

3.因为c语言去获取字符串长度的时候会遍历整个字符串这样会影响性能,所有redis内部维护了字符串长度从而达到查询字符串的长度的时候时间复杂度O(1)用记录字符串的长度来识别该字符串是否已经结尾一个字符占2字节\0占一个字节

sds的优点

1.获取字符串长度时间复杂度低

2.每次修改不会频繁的分配内存而是分配内存的时候回分配多余的内存从而避免多次的内存分配

3.可以识别特殊的字符串带有\0的 因为一些文件中有\0并不代表这个字符串的结束

Hash

他的底层由两种数据结构来实现
一个是ziplist 另一个就是hashtable
ziplist
这个数据结构里面会记录整个列表的内存大小 zlbytes的字段来表示
zlen表示在这个列表的元素的数量
然后各个节点的数据的大小
还会记录最后一个元素的偏移量,
每个节点也会记录前一个字节的长度
记录内容的类型encoding
这个数据结构有点在于占用内存小,缺点在于在中间插入或者修改的时候会引起连锁更新会降低效率
hashtable
这个数据结构底层就是一个java中的hashmap 有一个key 和union (这个属性存储我们的数据)还有一个链表 在出现hash冲突的时候以链表的形式去存储这时候的存储是无序的
这里有一个扩容的一个操作类似于map的扩容但是这个是一个渐进式的rehash 而不是一次
执行完成的,因为一次完成的话会极大影响这个redis的效率(因为是单线程的)这个 ## rehash 首先会分配一个比原先大两倍的内存的哈希表 然后再后面的添加操作就是在新分配的表中的添加但是更新查找删除是两个表上都会进行的,然后首先看看有没有在扩容 有一个 -1 的标识符如不是-1 就代表着正在扩容后面扩容完毕之后把rehashidx置为-1 这个就代表着扩容结束

List

list是一个队列的数据结构底层由ziplistquicklist组成。
ziplist
这个数据结构里面会记录整个列表的内存大小 zlbytes的字段来表示
zlen表示在这个列表的元素的数量
然后各个节点的数据的大小
还会记录最后一个元素的偏移量,
每个节点也会记录前一个字节的长度
记录内容的类型encoding
这个数据结构有点在于占用内存小,缺点在于在中间插入或者修改的时候会引起连锁更新会降低效率
quicklist
接着redis推出了一个quicklist来解决ziplist的缺点
就是运用双向链表每个节点是一个ziplist在添加数据时判断当前的ziplist是否可以进行添加如果不能进行添加就会创建新的quicklist节点来进行存储这样的话就可以解决ziplist在数据量大的时候频繁出现连锁更新
还有一个listpack得到数据结构在后续会进行讲解

Set

这个数据结构底层是由 intSethashtable组成的。如果元素都是一些数字的话他会进行去重加排序 但是数量到了一定数量或者元素中有字符串的话会转变为 hashtable ,这个数据结构的底层的话相对简单一点没有什么太大的特点。

Zset

他的底层是由ziplist和**skiplist(跳表)**组成的。ziplist的话上面已经写到了就不写了,现在俩看看跳表是怎么实现的。首先跳表主要是解决查询效率的问题的,这个数据结构把原先链表的查询效率从O(n)优化到O(logn)的时间复杂度,类似于二分查找的方法,接下来就说说跳表的创建初始化首先需要说明的一点是这个多级索引的层数是由一个随机数的算法来进行分配的最多32层然后添加元素的时候不会因为添加的元素二改变其他元素的索引层数这样就不会想类似于红黑树那样频繁为了保持平衡而改动,首先在创建跳表的时候会初始化层数为1元素长度为0,然后用zslCreateNode方法来赋值层数默认为32然后把一些前后指针指向null就完成了跳表的初始化,然后修改元素底层就是先删除元素在添加新的元素的这样会更方便一些,我的理解可能有些片面了哈哈哈。

总结

总结上面的知识要去了解 String 类型的 为什么不用C的数据结构 而是用自己维护的数据结构的原因,还有就是hash类型的rehash的一个过程要记住它是一个渐进式的 而不是一次性完成的,然后就是Zset的跳表了去了解跳表的初始化,以及添加元素是的索引层级是怎么计算的。看完这些你会发现其实底层的数据结构和一些算法的思想都是值得我们去借鉴的。差不多了我对redis的基本数据类型的理解目前就是这么多,欢迎志同道合的朋友们指点哦。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值