【Redis】内部数据结构自顶向下梳理
本博客将顺着自顶向下的思路梳理一下Redis的数据结构体系,从数据库到对象体系,再到底层数据结构。我将基于我的一个项目的代码来进行介绍:daredis。该项目中,使用Java实现了Redis中所有的数据结构,思想与Redis大致类似,各种变量的命名与Redis源码基本一致,只是将结构体换成了类来实现。
Redis数据库
Redis服务器在初始化时,会创建一个db数组,大小默认是16,即创建16个数据库。如下所示:
public class RedisServer {
private static int dbNum = 16;
public static RedisDB[] db;
public static void init(){
db = new RedisDB[dbNum];
}
public static void initDB(int index){
db[index] = new RedisDB();
}
}
RedisDB类型包含一个字典,代码如下:
public class RedisDB {
//数据库的键空间
Dict<SDS, RedisObject> dict;
public RedisDB() {
this.dict = new Dict<>();
}
}
数据库RedisDB实际上包含一个Dict类型,即字典(Redis中尤为关键的底层数据结构),是一个键值对集合,键名是SDS字符串,键值是RedisObject。Dict是后面要讲的一种底层数据结构,在数据库体系中也是用到了Dict。
可以这样理解,Redis的所有对象体系都是挂在一个Dict字典下的。这也体现了Redis非关系型的特点。
Redis对象系统
继续向下探索,看一看数据库键值RedisObject是什么。RedisObject表示Redis中的对象。Redis包含五种对象,统称对象系统
- RedisHash哈希对象
- RedisList列表对象
- RedisSet集合对象
- RedisString字符串对象
- RedisZSet有序集合对象
RedisObject包含一个类型字段type和一个编码字段encoding,以及一个底层数据结构的引用ptr。如下所示:
public abstract class RedisObject {
protected int type;
protected int encoding;
protected RedisObj ptr;
}
type的值由一个枚举类型来维护,表示上述五种类型中的某种类型,如下所示
public enum RedisType {
STRING(0),
LIST(1),
HASH(2),
SET(3),
ZSET(4);
private final int val;
RedisType(int VAL) {
this.val = VAL;
}
public int VAL(){
return val;
}
}
encoding同样由一个枚举类型来维护,表示ptr指向的数据结构的类型,如下所示
public enum RedisEnc {
RAW(0),
INT(1),
HT(2),
LINKEDLIST(3),
ZIPLIST(4),
INTSET(5),
SKIPLIST(6),
EMBSTR(7);
private final int val;
RedisEnc(int VAL) {
this.val = VAL;
}
public int VAL(){
return val;
}
}
RedisObject中的ptr引用的对象可以是多种类型。例如列表对象可由压缩列表ziplist或者双端链表linkedlist来编码。两种编码可以转换,当满足以下两个条件时,使用ziplist编码
- 列表对象保存的所有字符串元素长度都小于64字节;
- 列表对象保存的元素数量小于512个;
两个条件有一项不满足,会将压缩列表转化为双端链表。
其它Redis对象的数据结构编码切换方式也与之类似。
Redis底层数据结构
底层数据结构指的是ptr指向的对象的内部结构,在Redis中,包含6种底层数据结构:
- SDS动态字符串
- ziplist压缩列表
- list链表
- dict字典
- skiplist跳跃表
- intset整数集合
熟悉Redis的同学来说,这些都是耳熟能详的数据结构,就不一一去介绍源码了,项目daredis中都有具体实现。
之前写过一篇介绍跳跃表的博客,也可以看看:
【Redis】跳跃表原理分析与基本代码实现(java)
对象系统与各种底层数据结构映射关系如下:
【Redis】内部数据结构自顶向下梳理的更多相关文章
- [转]Redis内部数据结构详解-sds
本文是<Redis内部数据结构详解>系列的第二篇,讲述Redis中使用最多的一个基础数据结构:sds. 不管在哪门编程语言当中,字符串都几乎是使用最多的数据结构.sds正是在Redis中被 ...
- redis内部数据结构
redis内部数据结构,是指redis在自身的构建中,基于这些特定的内部数据结构进行的. 简单动态字符串:Simple Dynamic String 双端链表 字典:Dictonary 跳跃表:ski ...
- Redis学习笔记-Redis内部数据结构
Redis内部数据结构 Redis和其他key-value数据库的很大区别是它支持非字符串类型的value值.它支持的value值的类型如下: sds (simple dynamic string) ...
- 探索Redis设计与实现6:Redis内部数据结构详解——skiplist
本文转自互联网 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial ...
- 探索Redis设计与实现7:Redis内部数据结构详解——intset
本文转自互联网 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial ...
- 探索Redis设计与实现5:Redis内部数据结构详解——quicklist
本文转自互联网 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial ...
- 探索Redis设计与实现4:Redis内部数据结构详解——ziplist
本文转自互联网 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial ...
- 探索Redis设计与实现3:Redis内部数据结构详解——sds
本文转自互联网 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial ...
- 探索Redis设计与实现2:Redis内部数据结构详解——dict
本文转自互联网 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial ...
随机推荐
- python之Bug之字符串拼接bug
\r\n拼接Bug 环境: python3.4.pycharm2017 偶然的学习中遇到了一个问题,百思不得姐,什么问题呢,大家输入太快了,难免有失误就如下面的代码 #构造响应数据 response_ ...
- 第三十八章、PyQt输入部件:QKeySequenceEdit快捷键输入部件使用案例
专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 老猿学5G博文目录 一.功能简介 Key Sequence Edit输 ...
- PyQt(Python+Qt)学习随笔:树型部件QTreeWidget中使用sortItems进行项排序
老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 树型部件QTreeWidget中的项可以使用sortItems方法按照指定列进行排序,调用语法: s ...
- 第15.1节 PyCharm安装及使用
一. 引言 在本章以前,所有老猿实现的代码都是基于Python自带的解释器IDLE来开发和执行的,很方便.消耗少,但进入PyQt图形界面开发以后,IDLE不能实现和PyQt的集成,且不能支持断点调试, ...
- PyQt(Python+Qt)学习随笔:部件的inputMethodHints属性
inputMethodHints属性只对输入部件有效,输入法使用它来检索有关输入法应如何操作的提示,例如,如果设置了只允许输入数字的标志,则输入法可能会更改其可视组件,以反映只能输入数字.相关取值及含 ...
- 从Excel获取整列内容进行批量扫描
实习工作原因,需要测试excel表里面ip地址是否存在漏洞,扫了一眼,呕,四五百个IP,光是挨个进行访问,都是一个浩大的工程,所以准备开始摸鱼认真工作 思路是:excel按列提取->将IP按行存 ...
- 手写Json解析器学习心得
一. 介绍 一周前,老同学阿立给我转了一篇知乎回答,答主说检验一门语言是否掌握的标准是实现一个Json解析器,网易游戏过去的Python入门培训作业之一就是五天时间实现一个Json解析器. 知乎回答- ...
- pandas 处理缺失值(连续值取平均,离散值fillna"<unk>")
# 2.1处理缺失值,连续值用均值填充 continuous_fillna_number = [] for i in train_null_ix: if(i in continuous_ix): me ...
- 百度前端技术学院-基础-day5.6
今天学习了关于盒模型.浮动等页面布局的方法. 受到同学的启发,顺便学习了flex的布局. 还了解了一些编码的基本规则. 对我接下来的学习帮助很大. 交作业: HTML : https://github ...
- CSP-S2020 浙江 游记
2020.10.9 今天是 \(2020\) 年 \(10\) 月 \(9\) 日,距离初赛还有两天(算两天吗,完整的应该只有一天多了). 原本对于比赛还是没什么感觉的,每天做做题,水水文章,感觉时间 ...