前言
最近看了相关的Redis设计核心相关的书籍,对Redis有了一些小的认识,然后自己也做一些产出加深映象,我会从几个方面去总结Redis设计的核心内容:Redis底层数据结构总结、Redis高性能由哪些基础支撑、Redis应用场景、那些有趣的功能。
概述
本篇主要内容是Redis底层数据结构总结。Redis供用户直接使用的数据结构有String、List、Set、Zset、Hash等结构,而这些结构下层又基于一些数据结构,这些数据结构被设计的非常优美,来提供了Redis高效的性能、低内存占用、多样的功能等,他们有Dict、RedisObject、SDS、ZipList、QuickList、Listpak、Skiplist,我将从是什么、为什么使用、设计思想、特点、实现结构几个方面去总结。续上次说到了Ziplist,本章将继续介绍剩余的底层数据结构。
目录
Redis是如何在ziplist和skiplist中选择的:
QuickList
是什么
quicklist是List的底层数据结构,他是ziplist和linkedlist的混合体,将双向链表按段划分,每一段使用ziplist来紧凑存储,多个ziplist之间使用双向指针串联
为什么使用
- 1.因为双向链表结构每个元素都需要维护前后向指针,当元素较小时,本身的结构会比元素占用的空间多,浪费内存资源。
- 2.双链链表的每个元素内存是独立的,加剧了内存碎片率。
- 3.ziplist使用紧凑字节数组存储,但对于大长度的修改操作可能触发空间重分配
- 4.ziplist元素之间不独立,可能导致级联更新。
所以quciklist采用了双方的优点,避免了双方的缺点,采用分段的方式将一个长链表划分成多段node节点 ,每一段node节点使用ziplist存储:1.采用ziplist节省内存的优点 2.采用ziplist连续内存,降低内存碎片率 3.避免生成大的ziplist减少内存空间重分配的影响,4.减少node节点数量,使维护的指针数量变少节省内存空间;5.提供数据压缩功能,因为一般链表操作首尾更多,对中间元素来提高存储效率
设计思想
Quicklist采用了Ziplist高效存储的特点,并且避免了将ziplist分段存储,避免单个Ziplist过大导致的操作缓存,将Ziplist当成一个Node使用,多个Node串联形成一条双向链表。
特点
- 1.结合ziplist和linkedlist的特点;
- 2.降低内存碎片率;
- 3.使用ziplist降低内存占用;
- 4.访问头尾的时间复杂度为O(1);
- 5.可以快速跳过ziplist;
- 6.快速删除;
- 7.提供压缩功能
- 8.Ziplist的一些缺点仍存储,比如元素之间不独立、不适合存储大量元素、每次修改都会触发realloc,但是Quicklist限制了Ziplist的最大长度,即使发生以上情况对性能的影响也较小
- 9..ziplist的拆分和合并。Quicklist模式Ziplist节点最大为8kb,当超出时则生成新ziplist节点,所以对中间的元素修改时可能导致ziplist的拆分和合并。
- 10.存储有序、可重复的小字节元素,充分利用ziplist的特性,一般list适用在访问最新数据的场景或者提供顺序访问