共计 2211 个字符,预计需要花费 6 分钟才能阅读完成。
本文首发于公众号:Hunter 后端
原文链接:Redis 数据结构一之对象的介绍及各版本对应实现
本篇笔记开始介绍 Redis 数据结构的底层实现。
当咱们被问到 Redis 中有什么数据结构,或者说数据类型,咱们可能会说有字符串、列表、哈希、汇合、有序汇合。
其实这几种数据类型在 Redis 中都由对象形成,而且是两个对象,一个键对象,一个值对象。
在这些数据类型中,它们的键都是字符串对象,而值能够是后面说的字符串对象、列表对象、哈希对象、汇合对象、有序汇合对象中的一种,这个取决于键值对的数据类型。
而在 Redis 中,这些对象都有其更底层的实现形式,也就是说这一篇笔记咱们要介绍的,更底层的数据结构,而且不同的 Redis 版本有不一样的数据结构,最根底的数据结构包含简略动静字符串、字典、跳跃表、整数汇合等,
接下来咱们先介绍一下 Redis 中对象的形成,而后介绍一下不同 Redis 版本中每个对象所应用的的底层数据结构,之后再一一介绍这些数据结构的实现原理,以下是本篇笔记的目录:
- Redis 对象的介绍
- 不同版本的 Redis 对象的数据结构
留神:本篇文章的主体框架内容是基于书籍《Redis 设计与实现》进行形容的,局部过期内容都基于网上查问的相应材料与最新版本进行了对齐,如有其余疏漏,还望斧正。
1、Redis 对象的介绍
举一个例子,当咱们设置一个字符串类型的数据:
set msg "hello world"
这样,咱们就创立了两个对象,且两个都是字符串对象,因为键值对的 key 和 value 都是字符串。
如果咱们创立了一个列表数据,那么 key 是字符串对象,而值 value 是列表对象。
在 Redis 中,每个对象都由一个 redisObject 构造来示意:
typedef struct redisObject{
// 类型
unsigned type:4;
// 编码
unsigned encoding:4;
// 指向底层实现数据结构的指针
void *ptr
//...
} robj;
type
在下面的构造中,type 指的是这个对象的类型,比方咱们创立了一个列表数据,那么这个数据的 key 就是一个字符串对象,由这个构造里的 type 来指定,这个数据的 value 就是一个列表对象,也是由 type 来进行指定辨别。
然而,当咱们想要晓得一条数据的数据类型是字符串、列表、哈希、汇合、有序汇合的哪一种时,咱们经常是须要晓得的这条数据的 value 的类型,个别也是指的 value 的类型,因为数据的 key 的类型总是字符串对象。
一条数据的值对象类型的获取咱们能够用 TYPE 命令来操作:
TYPE msg
TYPE 类型的值输入就是咱们那五种类型:string、list、hash、set、zset
encoding
encoding 指的是这个对象底层数据结构应用的编码。
一个对象在不同的状况下的编码及底层数据结构可能是不一样的,比方对于字符串对象,它的编码包含 int,embstr,raw 这三种,但后两种的底层构造其实都是简略动静字符串(SDS),不过它们的底层应用形式略有不同,这个咱们在下一节再介绍。
获取对象的值的编码应用 OBJECT ENCODING
命令:
OBJECT ENCODING msg
ptr
ptr 则是作为指针指向的是对象的底层数据结构地址。
下面这些查看对象底层编码的命令,咱们会在介绍完各个底层数据结构之后依据存储的不同数据类型进行应用。
2、不同版本的 Redis 对象的数据结构
Redis 3.2 版本以前
在 Redis 3.2 版本以前,每个对象对应的编码,及底层数据结构如下:
字符串对象
编码(OBJECT ENCODING 输入后果) | 底层数据结构 |
---|---|
int | 整数 |
embstr | embstr 编码的 SDS |
raw | SDS |
列表对象
编码(OBJECT ENCODING 输入后果) | 底层数据结构 |
---|---|
ziplist | 压缩列表 |
linkedlist | 双向链表 |
哈希对象
编码(OBJECT ENCODING 输入后果) | 底层数据结构 |
---|---|
ziplist | 压缩列表 |
hashtable | 字典 |
汇合对象
编码(OBJECT ENCODING 输入后果) | 底层数据结构 |
---|---|
intset | 整数汇合 |
hashtable | 字典 |
有序汇合对象
编码(OBJECT ENCODING 输入后果) | 底层数据结构 |
---|---|
ziplist | 压缩列表 |
skiplist | 跳跃表 |
Redis 3.2 版本
而在 3.2 版本,次要对列表对象的底层实现做了批改,由 quicklist 形成底层实现,quicklist 实际上是 linkedlist 和 ziplist 的混合结构。
列表对象
编码(OBJECT ENCODING 输入后果) | 底层数据结构 |
---|---|
quicklist | 疾速列表 |
Redis 5.1 之后版本
在 Redis 5.1 版本,引入了新的数据结构 listpack,6.x 版本作为过渡阶段,并且在 7.0 版本,listpack 曾经齐全替换了 ziplist,成为了哈希对象、有序汇合对象的底层数据结构的原有实现之一,更改如下:
哈希对象
编码(OBJECT ENCODING 输入后果) | 底层数据结构 |
---|---|
listpack | listpack |
hashtable | 字典 |
有序汇合对象
编码(OBJECT ENCODING 输入后果) | 底层数据结构 |
---|---|
listpack | listpack |
skiplist | 跳跃表 |
而且 quicklist 也变成了 linkedlist 和 listpack 的混合结构
这一篇笔记只是作为一个引子,引入 Redis 中各个数据结构的底层构造,在下一篇笔记中咱们将正式一一介绍各个数据结构的底层实现。
如果想获取更多相干文章,可扫码关注浏览: