我了解的Redis - 1. 对象系统

Jan. 21, 2019, 9:35 p.m.

Redis 的对象系统是一个超赞的设计。

先看一下列表对象:

列表对象是用什么数据结构来实现的呢,Redis 使用了 2 个数据结构,分别是

  • 压缩列表
  • 双端链表

看一下哈希对象的数据结构都有哪些?

  • 压缩列表
  • 字典

最后看一下有序集合对象

  • 压缩列表
  • 跳跃表

有没有发现,这3个对象,都不止使用了一个数据结构,而且都使用了压缩列表;

那对象系统的作用是什么呢,就是负责为不同的对象挑选不同的数据结构,把他们组合起来,服务于指定的对象,

这样的设计,提供了很大的灵活性,也方便在不同的数据规模和场景下,尽可能地提升性能。

为什么

因为没有一种数据结构是最好的,这里的最好指的是这个数据结构的增删改查操作都是O(1)的,数据结构的使用都是需要结合实际的场景的

如果存在一个最好的数据结构,那这个世界就不会有这么多的数据结构了,只要学一种就可以了

而 Redis 的对象系统的设计就是为了能较为方便地为不同的场景提供不同的数据结构。

有序集合

1. 使用压缩列表 ( ziplist ) 时

先看下什么情况下会使用压缩列表:

  • 有序集合保存的元素数量小于128个
  • 有序集合保存的所有元素成员的长度都小于64字节

从这些条件以及压缩列表的作用,我们可以得出这样的结论

在数据量较小时,为了达到节约内存的目的而使用压缩列表,由于压缩列表是顺序型的数据结构,底层实现是数组,使用连续的内存空间

所以在数据规模较大,且需要扩容时,对内存的要求较高,为了更高解决这个场景下的问题,使用了跳跃表

2. 使用跳跃表时 ( skiplist ) 时

同时使用了字典和跳跃表这2个数据结构

字典

  • 优势:能以O(1)的时间复杂度查询出指定的成员数据
  • 劣势:是无序的,无法满足有序集合,有序的需求

跳跃表

  • 优势:有序的数据结构,最基础的链表数据结构,天然支持扩容,相比数组对内存要求低
  • 劣势:查询成员需要顺序查找,O(n)的时间复杂度

从上面的的优劣势对比,我们可以看出,字典和跳跃表他们是互补的

在 <查找成员> 和 <按范围查找的操作> 时,都可以获取不错的性能,因为他们使用不同的数据结构

既然使用了2个数据结构,那数据是不是在不同的数据结构里分别存储一份呢?

当然不是了,Redis 是用 C 语言实现的,C 语言是支持指针操作的,它们是通过指针来共享相同元素的成员和分值,不会造成额外的空间浪费

总结

  • 从上面有序集合的例子看

    • 1.首先是根据数量的大小,做一次选择,是压缩列表还是跳跃表
    • 2.对于跳跃表,还做了一次组合,加入了字典的数据结构
  • 还记得当时了解了 Redis 的对象系统的设计后,觉得越是优秀的软件,其设计思想就越是朴素。

  • 这个设计打个形象的比喻就是:寻找每个人优秀的地方,并组合成一个整体,共同对外提供服务,一个团队不也是如此吗?哈哈哈

返回首页