深入探索Redis之底层数据结构

Posted 码农的修炼之道

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了深入探索Redis之底层数据结构相关的知识,希望对你有一定的参考价值。

        在Redis中有五种数据类型,分别是string,hash,list,set,sorted set。分别是字符串,字典,列表,集合,有序集合。一起聊聊底层是数据结构。字符串没什么好说的,重点聊聊列表、集合、有序集合。


1、列表list

     list支持存储一组数据,底层对应有两种实现,分别是压缩列表ziplist和双向循环链表。当列表中数据比较小的时候,list采用ziplist作为实现方式。具体是单个数据小于64字节,列表中个数少于512。

    

       其实这种ziplist方法在我们开发过程中也经常用到。比如我们传输二进制数据(非序列化),可以采用这种方式。格式如下:

   <data_len><data_content><data_len><data_content>


    压缩列表的好处就是节约内存,相比数组存储方式可以节约很多内存。因为数组定义肯定要按照最长的数据来申请内存。其余达不到这个长度的就会有部分内存空闲。当数据量较大的时候,list将转化为双向链表来进行存储。


2、字典hash

    字典常用于存储一组数据对,每个数据包括key和value。字典也有两种数据结构,分别是ziplist和散列表。



3、集合set

    set用于存储一组不重复的数据,这种有两种实现方式,分别是有序数组和散列表。当数据都是整数或数据个数不超过512的时候,将采用有序数组进行存储。其他情况采用散列表进行存储(可以想象为hashset)。


4、有序集合sortedset

     有序集合用于存储一组数据,这里每个数据会携带一个score。通过score的大小进行排序。当数据较小的时候,将采用压缩列表ziplist进行存储。这里的条件是单个数据小于64字节,元素个数小于128。当超过这个的时候,将采用跳表skiplist进行存储而不是红黑树的实现。(像STL里面的map,Java集合里面的hashmap底层都是红黑树实现,红黑树的查找、插入平均复杂度为o(lgn))。 


      跳表作为一种平衡数据结构,经常和平衡树进行比较,在大多数场景下,跳表都可以达到平衡树的效率(查询节点支持平均O(lgN),最坏O(N)的复杂度),但实现和维护起来却比平衡树简单很多。

   

      简单的说,跳表就是将顺序查找的链表经过节点的抽取来达到二分查找的效率。比如下面这个图很形象的展示了跳表的查找过程。


   关于跳表,这里推荐几篇文章供参考。

  1、http://ju.outofmemory.cn/entry/81525

  2、http://www.imooc.com/article/258009

     关于跳表的时间复杂度和空间复杂度,也可以自己推导一下。这里总结一下,跳表的平均插入、删除、查找时间复杂度都是o(lg(n)),空间复杂度o(n)


   本文先写到这里吧,明天继续搬砖去了,后续有空继续深入聊聊。

   注:封面图片是去秋游摘葡萄拍的。

以上是关于深入探索Redis之底层数据结构的主要内容,如果未能解决你的问题,请参考以下文章

Redis技术探索「底层架构原理」探索分析服务核心数据结构介绍和案例

Redis技术探索「底层架构原理」探索分析服务数据同步持久化机制

Redis技术探索帮你从底层彻底吃透RDB技术原理(基础篇)

Redis技术探索帮你从底层彻底吃透AOF技术原理(基础篇)

Redis技术探索「底层架构原理」帮你从底层彻底吃透RDB技术原理(入门第一步)

Redis技术探索「底层架构原理」探索分析服务系统的网络架构和线程模型