Redis 5种数据类型的内部数据结构(二)

哈希对象(hash)
哈希对象的编码有两种,分别是ziplist、hashtable。当哈希对象保存的键值对数量小于512,并且所有键值对的长度都小于64字节时,使用压缩列表存储;否则使用hashtable存储。
列表对象(list)
列表对象的编码有两种,分别是:ziplist,linkedlist。考虑到链表的附加空间相对太高,prev 和 next 指针就要占去 16 个字节 (64bit 系统的指针是 8 个字节),另外每个节点的内存都是单独分配,会加剧内存的碎片化,影响内存管理效率。后续版本对列表数据结构进行了改造,使用 quicklist 代替了 ziplist 和 linkedlist。
ziplist(压缩列表)主要是为节省内存而设计的内存结构,它的优点就是节省内存,但缺点就是比其他的结构要消耗的更多的时间,所以Redis在数据量小的时候使用压缩列表存储。压缩列表是一块连续的内存空间,元素之间紧挨着存储,没有任何冗余空隙。
  1. struct ziplist<T> {
  2. int32 zlbytes; // 整个压缩列表占用字节数
  3. int32 zltail_offset; // 最后一个元素距离压缩列表起始位置的偏移量,用于快速定
  4. //位到最后一个节点
  5. int16 zllength; // 元素个数
  6. T[] entries; // 元素内容列表,挨个挨个紧凑存储
  7. int8 zlend; // 标志压缩列表的结束,值恒为 0xFF
  8. }

压缩列表为了支持双向遍历,所以才会有 ztail_offset 这个字段,用来快速定位到最后一个元素,然后倒着遍历。
当列表的长度小于512,并且所有的元素长度都小于64字节时,使用压缩列表存储,否则使用linkedlist存储
集合对象(set)
集合对象的编码有两种,分别是:intset、hashtable。
intset(整数集合)主要是为节省内存而设计的内存结构,它的优点就是节省内存,但缺点就是比其他结构要消耗更多的时间,所以 Redis 在数据量小的时候使用整数集合存储。
当集合的长度小于 512,并且所有元素都是整数时,使用整数集合存储;否则使用 hashtable 存储.
hashtable 的结构和 Java 的 HashMap 几乎是一样的,都是通过分桶的方式解决 hash 冲突。第一维是数组,第二维是链表。数组中存储的是第二维链表的第一个元素的指针。
有序集合对象(sort set)
有序集合对象的编码有两种,分别是:ziplist、skiplist。
当有序集合的长度小于 128,并且所有元素的长度都小于 64 字节时,使用压缩列表存储;否则使用 skiplist 存储。

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注