redis 数据结构与对象
1 动态字符串 SDS (redis中字符串值、AOF缓冲区以及客户端输入缓冲区)
2 链表 linkedlist(发布与订阅、慢查询、监视器、redis本身保存多客户端的状态信息、构建客户端输出缓冲区)
3 字典 HashTable(又称为符号表、关联数组、映射、保存键值对抽象数据结构) 是hash键的底层
4 跳跃表 skiplist(有序集合键、集群节点中用作内部数据结构)
1 字符串对象(String) int raw embstr(专门保存短字符串的一种优化编码方式)
2 列表对象(List) ziplist linkedlist
3 哈希对象(Hash) ziplist hashtable
5 有序集合对象(Zet) ziplist skiplist
1 动态字符串 SDS (redis中字符串值、AOF缓冲区以及客户端输入缓冲区)
1 常数复杂度获取字符串长度
2 杜绝缓冲区溢出(api 会检查SDS是否满足需求)
3 减少字符串带来的内存重分配次数
(空间预分配、小于1MB 13+13+1 大于1MB 30MB+1MB+1) 惰性空间释放
4 二进制安全 使用len来判断字符串是否结束
5 兼容部分C字符串函数
2 链表 linkedlist(发布与订阅、慢查询、监视器、redis本身保存多客户端的状态信息、构建客户端输出缓冲区)
3 字典 HashTable(又称为符号表、关联数组、映射、保存键值对抽象数据结构) 是hash键的底层
哈希表
哈希表节点
字典
Ht[1]会在rehash的时候使用
哈希表的扩展与收缩
渐进性rehash
4 跳跃表 skiplist(有序集合键、集群节点中用作内部数据结构)
(平均O(logN))、最坏O(N)复杂度 效率可以和平衡树来媲美)
跳跃表 skiplist 就是受到这种多层链表结构的启发而设计出来的。按照上面生成链表的方式,上面每一层链表的节点个数,是下面一层的节点个数的一半,这样查找过程就非常类似于一个二分查找,使得查找的时间复杂度可以降低到 O(logn)。
但是,这种方法在插入数据的时候有很大的问题。新插入一个节点之后,就会打乱上下相邻两层链表上节点个数严格的 2:1 的对应关系。如果要维持这种对应关系,就必须把新插入的节点后面的所有节点 (也包括新插入的节点) 重新进行调整,这会让时间复杂度重新蜕化成 O(n)。删除数据也有同样的问题。
skiplist 为了避免这一问题,它不要求上下相邻两层链表之间的节点个数有严格的对应关系,而是 为每个节点随机出一个层数(level)。比如,一个节点随机出的层数是 3,那么就把它链入到第 1 层到第 3 层这三层链表中。
说一下跳表的缺点:
1.内存占用比红黑树大(每个节点4指针);
2.由于插入时是随机选择level,cache友好性不够好;
https://blog.csdn.net/brillianteagle/article/details/52206261跳跃表原理与java实现
https://blog.csdn.net/DERRANTCM/article/details/79063312跳跃表Skip List的原理和实现
https://www.cnblogs.com/tong-yuan/p/skiplist.html 跳表的插入删除
5 整数集合 Intset(集合键的底层实现)
6 压缩列表 ziplist(列表键和哈希键的底层实现)
7 对象
0字符串对象、列表对象、哈希对象、集合对象、有序集合对象
1 字符串对象(String) int raw embstr(专门保存短字符串的一种优化编码方式)
2 列表对象(List) ziplist linkedlist
3 哈希对象(Hash) ziplist hashtable
4 集合对象(Set) intset hashtable
5 有序集合对象(Zet) ziplist skiplist