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),但是当数据量大了之后,一般会使用原来的数据类型,那样的话数据结构的优势就能发挥