02 Redis 底层数据结构

一、不同数据类型存储结构

Redis底层数据结构一共有 6 种,分别是简单动态字符串、双向链表、压缩列表、哈希表、跳表和整数数组。它们和数据类型的对应关系如下图所示:

1 数组与链表的区别

数组和链表是所有数据结构的基础,其差别在于数据在内存中分步是连续的,详情请参考:参考1: 数据结构之数组和链表的区别_Jasminexjf的博客-CSDN博客_数组与链表的区别第一题便是数据结构中的数组和链表的区别数组(Array)一、数组特点:所谓数组,就是相同数据类型的元素按一定顺序排列的集合;数组的存储区间是连续的,占用内存比较大,故空间复杂的很大。但数组的二分查找时间复杂度小,都是O(1);数组的特点是:查询简单,增加和删除困难;1.1 在内存中,数组是一块连续的区域1.2 数组需要预留空间 在使用前需要提前申请所占内存的大小,...https://blog.csdn.net/Jasminexjf/article/details/88847127

参考2:redis高性能-存储结构 - 简书前言 Redis作为一款高性能数据库,表现在:它接收到一个键值对操作后, 能以微秒级别的速度找到数据,并快速完成操作。其高性能得奥秘来缘于以下两点: 1 Redis 是内存数...https://www.jianshu.com/p/cbd0584da4b9

数据结构系列之跳表 - 知乎前言文中附代码实现. 在公众号回复 【跳表】 也可以获取哦。 什么是跳表 跳表是一种数据结构。它允许快速查询一个有序连续元素的数据链表。跳跃列表的平均查找和插入时间复杂度都是O(log n),优于普通队列的O(n)。…https://zhuanlan.zhihu.com/p/101143158/

mysql源码调试(一)环境搭建【图文】_archivelog_51CTO博客mysql源码调试(一)环境搭建【图文】,操作系统:windowsserver2012R2VS版本:visiostudio2015community机器配置:4core/4G安装所需包:cmake,bison,boost,activeperl,下面为具体版本cmake-3.15.0-rc3-win64-x64.msiboost_1_59.zip(注意boost版本要与mysql版本对应,会在cmake时有报错提示对应哪个版本)activehttps://blog.51cto.com/liucb/2420225

什么是ziplist

Redis官方对于ziplist的定义是(出自ziplist.c的文件头部注释):

The ziplist is a specially encoded dually linked list that is designed to be very memory efficient. It stores both strings and integer values, where integers are encoded as actual integers instead of a series of characters. It allows push and pop operations on either side of the list in O(1) time.

翻译一下就是说:ziplist是一个经过特殊编码的双向链表,它的设计目标就是为了提高存储效率。ziplist可以用于存储字符串或整数,其中整数是按真正的二进制表示进行编码的,而不是编码成字符串序列。它能以O(1)的时间复杂度在表的两端提供pushpop操作。

ziplist的数据结构定义

ziplist的数据结构组成是本文要讨论的重点。实际上,ziplist还是稍微有点复杂的,它复杂的地方就在于它的数据结构定义。一旦理解了数据结构,它的一些操作也就比较容易理解了。

我们接下来先从总体上介绍一下ziplist的数据结构定义,然后举一个实际的例子,通过例子来解释ziplist的构成。如果你看懂了这一部分,本文的任务就算完成了一大半了。

从宏观上看,ziplist的内存结构如下:

 压缩链表存储结构:

各个部分在内存上是前后相邻的,它们分别的含义如下:

  • <zlbytes>: 32bit,表示ziplist占用内存的字节总数(也包括<zlbytes>本身占用的4个字节),在对压缩列表进行重新内存分配,或者计算zllen的位置时使用;
  • <zltail>: 32bit,表示ziplist表中最后一项(entry)的起始偏移量在ziplist中的起始地址有多少字节。<zltail>的存在,使得我们可以很方便地找到最后一项(不用遍历整个ziplist),从而可以在ziplist尾端快速地执行push或pop操作。
  • <zllen>: 16bit, 表示ziplist中数据项(entry)的个数。zllen字段因为只有16bit,所以可以表达的最大值为2^16-1。这里需要特别注意的是,如果ziplist中数据项个数超过了16bit能表达的最大值,ziplist仍然可以来表示。那怎么表示呢?这里做了这样的规定:如果<zllen>小于等于2^16-2(也就是不等于2^16-1),那么<zllen>就表示ziplist中数据项的个数;否则,也就是<zllen>等于16bit全为1的情况,那么<zllen>就不表示数据项个数了,这时候要想知道ziplist中数据项总数,那么必须对ziplist从头到尾遍历各个数据项,才能计数出来。
  • <entry>: 表示真正存放数据的数据项,长度不定。一个数据项(entry)也有它自己的内部结构,这个稍后再解释。
  • <zlend>: ziplist最后1个字节,是一个结束标记,值固定等于255。

上面的定义中还值得注意的一点是:<zlbytes><zltail><zllen>既然占据多个字节,那么在存储的时候就有大端(big endian)和小端(little endian)的区别。ziplist采取的是小端模式来存储,这在下面我们介绍具体例子的时候还会再详细解释。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天秤座的架构师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值