Redis的设计与实现 对象

125 阅读2分钟

一 对象的概念

Redis没有使用数据结构来实现键值对数据库,而是基于数据结构创建了一个对象系统,包括字符串对象,列表对象,有序集合对象,哈希对象,集合对象五种类型的对象。

二 对象的数据结构

  typedef stuct redisObject {
      // 类型
      unsigned type:4;
      // 编码
      unsigned encoding:4;
      // 指向底层数据结构的指针
      void *ptr;
      
      ....
      unsigned lru:22
  }
  
  1. 类型

    字符串键,列表键,有序集合键,哈希键,集合键

  2. 编码

    对应底层的数据结构

二 对象的种类

  1. 字符串对象

    三种编码 int raw embstr

  2. 列表对象

    列表对象的编码可以是ziplist(压缩列表)和linkedlist(链表) 当列表中保存的字符串元素都小于64字节,或者元素数量小于512时使用ziplist否则使用linkedlist

  3. 哈希对象

    哈希对象的编码可以是ziplist或者hashtable(底层通过字典来实现,类似java hashMap) 当哈希对象中保存的字符串元素都小于64字节,或者元素数量小于512时使用ziplist否则使用hashtable

  4. 集合对象

    集合对象编码可以是intsert和hashtable insert是整数集合,如果使用hashtable那么只是使用了hashtable的key他的value都是为null的

  5. 有序集合对象

    有序集合对象编码可以是ziplist也可以是skiplist 有序集合元素数量小于128个时或者里面保存的元素都小于64字节时使用ziplist,其他的使用hashtable

三 内存回收

C语言不具备自动内存回收功能,所以redis自己实现了引用计数来实现垃圾回收,基本和java的引用计数发回收是一致的

四 对象共享

创建1000个字符串对象在内存中,这1000个对象其实是可以共享,如不同的键但是相同的value,这样就可以节省空间。

五 对象的空转时长

redisObject对象中有一个lru属性,记录对象最后一次命令的访问时间,通过当前时间减去键值对的lru时间就会得到这个键值对多长时间没有被使用,也就是他的空转时长。