Redis数据结构与基本数据类型的原理

1sds

sds的数据结构

sds相较于c字符串有什么好处

1 可以在o(1)时间负载度直接获取到字符串的长度,而c需要遍历,是O(n)

2 可以修改字符串不会导致内存溢出或者内存泄露,对sds进行修改的时候如何长度不够会自动加长,然后对字符串进行修改,更新free和len字段,c字符串如果在没有进行扩容的情况下修改字符串,如果修改后的字符串长度大于修改前的字符串长度可导致内存溢出,再者,如果对c字符串使用trim()函数去除空格,c字符串不会自动减少内存使用,会导致内存泄露

3sds是二进制安全的,c字符串默认以‘\0’结尾终止字符串,这样在存储多媒体内容如音频视频的时候可能不可用,而sds则不会有这个问题

4sds会在结尾加上\0’,这样sds可以使用一些c语言的api

sds的内存分配原理

sds在进行扩容的时候当sds的大小小于1m的时候每次扩容一倍,当sds大于1m的时候,每次加1m,最大为512m

2链表、

3字典

字典保存数据以及解决冲突

1计算hash值

2将数据保存在对应的hash的地点,在后面的链条不断追加数据

 

负载因子计算

扩容后容量计算

也就是说比如当前容量为5.,size = 4 ,那么扩容后就是16,因为5*2 = 10 ,最近的2^n是16

如何扩容

采用渐进式的hash,会创建一个扩容后的字典和原子点共存,然后将数据慢慢挪过去,最后删除原来的数据字典。

4跳表

跳表就是在原来的数据结构上加上多级索引,方便查找数据

5整数集合

整数集合的好处

1redis保存整数有16位,32位,64位,redis对于整数集合保存的时候才用渐进式升级的保存方式,采用数字中位数最大的作为保存的数据的位数,如果全部都是16则采用16位保存,如何是混合的如上面14632需要32位,则整体会升级为32位,如果把14632删除了又会整体降级为16位,这样做的好处就是可以节省内存,

6压缩表zipList

previous_entity_length:记录上一个节点的长度,如果上一个节点大小小于254个字节,那么previous_entity_length只需一个字节,否则需要5个字节

encoding:编码

连锁更新问题

如果在最前面插入一个长度为254以上的节点,那么会导致后面一个节点的previous_entity_length从1增加到5,从而引起当前节点也发生变化,如果后面的节点的长度都在251到253之间,那么就会发生连锁反应,导致所有的previous_entity_length的长度都发生扩容,导致性能问题,但是这种性能问题发发生的概率很小

7 基本数据类型string的原理

7 基本数据类型list的原理

如果list里面每一个元素的大小均小于64字节,并且元素的个数小于512个采用压缩列表,

否则采用链表

8基本数据类型hash的原理

如果每一个键值对的键和值的大小均小于64字节,并且元素个个数小于512采用压缩列表

否则采用字典

9 基本数据类型无序集合set的原理

set里面的所有元素都是整数,并且数量小于512个,采用intest

否则采用hashTable(字典)

10基本数据类型有序集合sortSet的原理

如果有序集合的元素小于128个,并且所有元素大小小于64字节,采用压缩列表ziplist,

否则采用跳跃表+字典

为什么采用字典+跳跃表

1采用字典,方便准确查找,在o(1)下可以精确找到对应的数据

2采用跳跃表,方便区间查找,

3两个加起来就能实现快速查找

11对于上面的什么时候使用压缩列表的条件是可以设置的

使用zipList好处在于节省空间,并且节省内存碎片,但是新增,修改(如链表),或者查询的效率会变低(如hash),但是当数据量大了之后,一般会使用原来的数据类型,那样的话数据结构的优势就能发挥

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值