Redis数据结构一之对象的介绍及各版本对应实现
本文首发于公众号: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 中各个数据结构的底层结构,在下一篇笔记中我们将正式逐个介绍各个数据结构的底层实现。
如果想获取更多后端相关文章,可扫码关注阅读:

Redis数据结构一之对象的介绍及各版本对应实现的更多相关文章
- redis学习(二) redis数据结构介绍以及常用命令
redis数据结构介绍 我们已经知道redis是一个基于key-value数据存储的数据结构数据库,这里的key指的是string类型,而对应的value则可以是多样的数据结构.其中包括下面五种类型: ...
- RedisTemplate访问Redis数据结构(介绍和常用命令)
Redis 数据结构简介 Redis 可以存储键与5种不同数据结构类型之间的映射,这5种数据结构类型分别为String(字符串).List(列表).Set(集合).Hash(散列)和 Zset(有序集 ...
- 深入了解Redis【二】对象及数据结构综述
引言 Redis中每个键值对都是由对象组成: 键总是一个字符串对象(string) 值可以是字符串对象(string).列表对象(list).哈希对象(hash).集合对象(set).有序集合对象(z ...
- Redis数据结构与对象
参考<Redis设计与实现> 系列文章目录和关于我 一丶简单动态字符串 当redis需要的不仅仅是一个字符串字面量,而是一个可以被修改的字符串值时,就会使用SDS(simple dynam ...
- Redis 数据结构与内存管理策略(上)
Redis 数据结构与内存管理策略(上) 标签: Redis Redis数据结构 Redis内存管理策略 Redis数据类型 Redis类型映射 Redis 数据类型特点与使用场景 String.Li ...
- Redis数据结构之intset
本文及后续文章,Redis版本均是v3.2.8 上篇文章<Redis数据结构之robj>,我们说到redis object数据结构,其有5中数据类型:OBJ_STRING,OBJ_LIST ...
- Redis数据结构之robj
本文及后续文章,Redis版本均是v3.2.8 我们知道一个database内的这个映射关系是用一个dict来维护的.dict的key固定用一种数据结构来表达,这这数据结构就是动态字符串sds.而va ...
- [转]Redis 数据结构简介
Redis 数据结构简介 Redis可以存储键与5种不同数据结构类型之间的映射,这5种数据结构类型分别为String(字符串).List(列表).Set(集合).Hash(散列)和 Zset(有序集合 ...
- Redis学习系列六ZSet(有序列表)及Redis数据结构的过期
一.简介 ZSet可以说是Redis中最有趣的数据结构了,因为他兼具了Hash集合和Set的双重特性,也是用的最多的,保证了value值的唯一性的同时,,同时又保证了高性能,最主要的是还可以给每个Va ...
- RedisTemplate访问Redis数据结构
https://www.jianshu.com/p/7bf5dc61ca06 Redis 数据结构简介 Redis 可以存储键与5种不同数据结构类型之间的映射,这5种数据结构类型分别为String(字 ...
随机推荐
- alt_flash_open_dev读写EPCS出现“Cannot open flash device”的解决办法
转载 http://www.corecourse.cn/forum.php?mod=viewthread&tid=28317 在对EPCS读写操作时alt_flash_open_dev(EPC ...
- MySql数据库的两大引擎InnoDB和MyIsam的区别
事务方面 InnoDB支持事务,MyISAM不支持事务.MySql的默认存储引擎为InnoDB 外键方面 InnoDB支持外键,MyISAM不支持,对一个包含外键的InnoDB表转为MYISAM会失败 ...
- 明解STM32—GPIO理论基础知识篇之八种工作模式
一.引言 在之前围绕STM32的GPIO的基本结构进行了介绍,图1为STM32的5V容忍的GPIO口内部基本结构图,图2为GPIO的基本结构中各个模块部分的概述. 阅读GPIO基本结构的内容能够对GP ...
- Android日常--今日的APP进度+1
学了这么久的APP,是时候拿出来实践一下啦! 今天洗的内容都比较基础,基本上不涉及到后台代码的编写,看到本阶段的目标需要连接数据库,也是有被震住哈哈哈哈哈: 我发现,第一阶段主要分为两个界面,第一个注 ...
- Weak Encryption 弱加密安全问题处理
Weak Encryption Abstract 程序使用了弱加密算法,无法保证敏感数据的保密性. Explanation 陈旧的加密算法(如 DES)再也不能为敏感数据提供足够的保护了. 加密算法依 ...
- Kafka为什么比其他消息中间件快
更多内容,前往 IT-BLOG 无论 Kafka 作为 MQ 也好,还是作为存储层也罢,无非就是两个功能,一是 Producer 生产的数据存到 Broker,二是 Consumer 从 Broker ...
- R数据分析:生存分析的列线图的理解与绘制详细教程
列线图作为一个非常简单明了的临床辅助决策工具,在临床中用的(发文章的)还是比较多的,尤其是肿瘤预后: Nomograms are widely used for cancer prognosis, p ...
- 每日复习------main()方法以及对象的初始化顺序
由于 Java 虚拟机需要调用类的 main()方法,所以该方法的访问权限必须是 public,又因为 Java 虚拟机在执行 main()方法时不必创建对象,所以该方法必须是 static 的,该方 ...
- day12:闭包函数&匿名函数(lambda)
闭包函数 闭包函数的定义: 如果内函数使用了外函数的局部变量并且外函数把内函数返回出来的过程 叫做闭包里面的内函数是闭包函数 一个简单的闭包函数示例: def songyunjie_family(): ...
- 【vue3-element-admin 】基于 Vue3 + Vite4 + TypeScript + Element-Plus 从0到1搭建后台管理系统(前后端开源@有来开源组织)
vue3-element-admin 是基于 vue-element-admin 升级的 Vue3 + Element Plus 版本的后台管理前端解决方案,技术栈为 Vue3 + Vite4 + T ...