1、SDS 动态字符串

优点解析

  • 二进制安全

    C语言的字符串[0个字节的无符号指针指向的char数组]是根据 \0结尾 内容无法容纳\0而SDS 是根据 len 长度判断字符串的 而扩容时不包括 \0 且C的字符串每次更改都是新的常量池

2、InSet

有序/内容倒序扩容 为了扩容(或者说扩容编码长度)防止先放比较小的数据 伸展(右边补0)导致后面准备放其他数据的字节位被占满,也就是先将大得数据放置到准备的位置 而扩容前将要添加的数据在扩容(改变编码 )之后添加
注意 判断的数据大小是所占用的比特位 也就是所负数所占用的字节是可以比正数大的,正数插入元素角标位置不变,负数向后移动一位

类似于TreeSet

根据len 可以根据公式 startIndex + (index * typesize)很快找到前后元素
适用于数据量少 多了便会慢 数组形式[连续内存空间]

3、Dict

初始化数组最小是4 size为2^n sizemask为2^n-Redis数据类型 - 图1
Redis数据类型 - 图2
Redis数据类型 - 图3
Redis数据类型 - 图4
Redis数据类型 - 图5
Redis数据类型 - 图6
Redis数据类型 - 图7
Redis数据类型 - 图8
Redis数据类型 - 图9
Redis数据类型 - 图10
Redis数据类型 - 图11
Redis数据类型 - 图12

4. ZipList

Dict不是连续性的 每个entity都是独立的 使用了大量指针 查询快但是内存占用大,可能造成大量的内存碎片

Redis数据类型 - 图13
Redis数据类型 - 图14
Redis数据类型 - 图15
Redis数据类型 - 图16
Redis数据类型 - 图17
Redis数据类型 - 图18
Redis数据类型 - 图19
Redis数据类型 - 图20
Redis数据类型 - 图21
Redis数据类型 - 图22

类似于链表,节点找中间的节点性能慢,但是舍弃了指针,占用内存空间更小,节点数会做限制,总节点长度 和节点数是小端字节序表示,低位在前

连续锁更新问题

假如说现在有几个连续且节点长度都是250~253的节点,他们记录前一个节点都是用一个字节表示,因为没超过254,这时有一个超过254字节插入到队首,那么之前的头节点表示上一个节点长度的所使用的字节数就要从1变成5 导致本身超过超过254字节数,导致后面几个节点超过阈值随之更新,申请内存空间切换态消耗很大
Redis数据类型 - 图23
Redis数据类型 - 图24