【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 ...
随机推荐
- git全流程
服务器:Ubuntu 使用git前准备工作: 下载git之前先更新: apt-get update 安装git: apt-get install git 创建本地仓库: mkdir test git初 ...
- 喝完可乐桶后程序员回归本源,开源Spring基础内容
周六了,又是摸鱼的一天,今天还有点不在状态,脑瓜子迷迷糊糊的,昨晚出去喝可乐桶喝的脑子到现在都不是很正常(奉劝各位可以自己小酌:450ml威士忌+1L多一点可乐刚刚好,可能是我酒量不好),正好没啥事就 ...
- CentOS下Mysql的操作
重启Mysql的各种方法 1.通过rpm包安装的MySQL service mysqld restart /etc/inint.d/mysqld start 2.从源码包安装的MySQL // lin ...
- 转:python提取浏览器Cookie
在用浏览器进行网页访问时,会向网页所在的服务器发送http协议的GET或者POST等请求,在请求中除了指定所请求的方法以及URI之外,后面还跟随着一段Request Header.Request He ...
- CTF写脚本
今天总结一下CTF如何写脚本快速得分....(比较菜,能力有限,大佬勿喷) 所谓的写脚本得分,就是利用了 python爬虫的思想,如果之前没有听说过的话,可以去爬虫的相关语法.如果是看网上的视频的话, ...
- HDFS 操作命令
本地文件系统创建一个文件,输入带姓名学号信息. 查看新建文件所在目录 查看新建文件内容 将此文件上传到HDFS文件系统上的用户目录 HDFS上查看相应目录 HDFS上查看文件内容 HDFS上查看文件大 ...
- STL—— 容器(vector)begin() 与 rbegin() , end() 与 rend()
1. Vector 迭代器首地址与尾地址 begin() 和 end() 在代码中可以将迭代器用作参数的位置可以使用 begin() 和 end() 获取地址,如下代码: 1 #include &l ...
- ASP .Net Core 中间件的使用(一):搭建静态文件服务器/访问指定文件
前言 随着Asp .Net Core的升级迭代,很多开发者都逐渐倾向于.net core开发. .net core是一个跨平台的应用程序,可以在windows.Linux.macOS系统上进行开发和部 ...
- 百测学习之postman-接口测试
一.postman的请求 1.url与uri的区别 url与uri的区别 http://doc.nnzhp.cn/ http+host(域名)+path路径(uri) 2.g ...
- mini-web框架-装饰器-总结2(5.3.2)
@ 目录 1.说明 2.代码 关于作者 1.说明 多级装饰器嵌套 带参数的装饰器 这里打印print(index) 会在函数定义的时候@test(222) 就被调用,返回一个test2继续装饰 2.代 ...