Redis RDB文件格式全解析

转载自  Redis RDB文件格式全解析

点评

这篇文章作为对RDB理解的教程文章,对RDB文件的原理理解有助于进行Redis高阶应用的设计与开发。

文章转自:http://blog.nosqlfan.com/html/3734.html 作者:@nosqlfan

RDB文件是Redis持久化的一种方式,Redis通过制定好的策略,按期将内存中的数据以镜像的形式转存到RDB文件中。那么RDB文件内部格式是什么样的呢,Redis又做了哪些工作让RDB能够更快的dump和加载呢,下面我们深入RDB文件,来看一看其内部结构。首先我们来看一个RDB文件的概况图:

----------------------------# RDB文件是二进制的,所以并不存在回车换行来分隔一行一行.
52 45 44 49 53              # 以字符串 "REDIS" 开头
30 30 30 33                 # RDB 的版本号,大端存储,比如左边这个表示版本号为0003
----------------------------
FE 00                       # FE = FE表示数据库编号,Redis支持多个库,以数字编号,这里00表示第0个数据库
----------------------------# Key-Value 对存储开始了
FD $length-encoding         # FD 表示过期时间,过期时间是用 length encoding 编码存储的,后面会讲到
$value-type                 # 1 个字节用于表示value的类型,比如set,hash,list,zset等
$string-encoded-key         # Key 值,通过string encoding 编码,同样后面会讲到
$encoded-value              # Value值,根据不同的Value类型采用不同的编码方式
----------------------------
FC $length-encoding         # FC 表示毫秒级的过期时间,后面的具体时间用length encoding编码存储
$value-type                 # 同上,也是一个字节的value类型
$string-encoded-key         # 同样是以 string encoding 编码的 Key值
$encoded-value              # 同样是以对应的数据类型编码的 Value 值
----------------------------
$value-type                 # 下面是没有过期时间设置的 Key-Value对,为防止冲突,数据类型不会以 FD, FC, FE, FF 开头
$string-encoded-key
$encoded-value
----------------------------
FE $length-encoding         # 下一个库开始,库的编号用 length encoding 编码
----------------------------
...                         # 继续存储这个数据库的 Key-Value 对
FF                          ## FF:RDB文件结束的标志

下面我们对上面的内容进行详细讲解

Magic Number

第一行就不用讲了,REDIS字符串用于标识是Redis的RDB文件

版本号

用了4个字节存储版本号,以大端(big endian)方式存储和读取

数据库编号

以一个字节的0xFE开头,后面存储数据库的具体编号,数据库的编号是一个数字,通过 “Length Encoding” 方式编码存储,“Length Encoding” 我们后面会讲到。

Key-Value值对

值对包括下面四个部分 1. Key 过期时间,这一项是可有可无的 2. 一个字节表示value的类型 3. Key的值,Key都是字符串,通过 “Redis String Encoding” 来保存 4. Value的值,通过 “Redis Value Encoding” 来根据不同的数据类型做不同的存储

Key过期时间

过期时间由 0xFD 或 0xFC开头用于标识,分别表示秒级的过期时间和毫秒级的过期时间,后面的具体时间是一个UNIX时间戳,秒级或毫秒级的。具体时间戳的值通过“Redis Length Encoding” 编码存储。在导入RDB文件的过程中,会通过过期时间判断是否已过期并需要忽略。

Value类型

Value类型用一个字节进行存储,目前包括以下一些值:

  • 0 = “String Encoding”

  • 1 = “List Encoding”

  • 2 = “Set Encoding”

  • 3 = “Sorted Set Encoding”

  • 4 = “Hash Encoding”

  • 9 = “Zipmap Encoding”

  • 10 = “Ziplist Encoding”

  • 11 = “Intset Encoding”

  • 12 = “Sorted Set in Ziplist Encoding”

Key

Key值就是简单的 “String Encoding” 编码,具体可以看后面的描述

Value

上面列举了Value的9种类型,实际上可以分为三大类

  • type = 0, 简单字符串

  • type 为 9, 10, 11 或 12, value字符串在读取出来后需要先解压

  • type 为 1, 2, 3 或 4, value是字符串序列,这一系列的字符串用于构建list,set,hash 和 zset 结构

Length Encoding

上面说了很多 Length Encoding ,现在就为大家讲解。可能你会说,长度用一个int存储不就行了吗?但是,通常我们使用到的长度可能都并不大,一个int 4个字节是否有点浪费呢。所以Redis采用了变长编码的方法,将不同大小的数字编码成不同的长度。

  1. 首先在读取长度时,会读一个字节的数据,其中前两位用于进行变长编码的判断

  2. 如果前两位是 0 0,那么下面剩下的 6位就表示具体长度

  3. 如果前两位是 0 1,那么会再读取一个字节的数据,加上前面剩下的6位,共14位用于表示具体长度

  4. 如果前两位是 1 0,那么剩下的 6位就被废弃了,取而代之的是再读取后面的4 个字节用于表示具体长度

  5. 如果前两位是 1 1,那么下面的应该是一个特殊编码,剩下的 6位用于标识特殊编码的种类。特殊编码主要用于将数字存成字符串,或者编码后的字符串。具体见 “String Encoding”

这样做有什么好处呢,实际就是节约空间:

  1. 0 – 63的数字只需要一个字节进行存储

  2. 而64 – 16383 的数字只需要两个字节进行存储

  3. 16383 - 2^32 -1 的数字只需要用5个字节(1个字节的标识加4个字节的值)进行存储

String Encoding

Redis的 String Encoding 是二进制安全的,也就是说他没有任何特殊分隔符用于分隔各个值,你可以在里面存储任何东西。它就是一串字节码。下面是 String Encoding 的三种类型

  1. 长度编码的字符串

  2. 数字替代字符串:8位,16位或者32位的数字

  3. LZF 压缩的字符串

长度编码字符串

长度编码字符串是最简单的一种类型,它由两部分组成,一部分是用 “Length Encoding” 编码的字符串长度,第二部分是具体的字节码。

数字替代字符串

上面说到过 Length Encoding 的特殊编码,就在这里用上了。所以数字替代字符串是以 1 1 开头的,然后读取这个字节剩下的6 位,根据不同的值标识不同的数字类型:

  • 0 表示下面是一个8 位的数字

  • 1 表示下面是一个16 位的数字

  • 2 表示下面是一个32 位的数字

LZF压缩字符串

和数据替代字符串一样,它也是以1 1 开头的,然后剩下的6 位如果值为4,那么就表示它是一个压缩字符串。压缩字符串解析规则如下:

  1. 首先按 Length Encoding 规则读取压缩长度 clen

  2. 然后按 Length Encoding 规则读取非压缩长度

  3. 再读取第二个 clen

  4. 获取到上面的三个信息后,再通过LZF算法解码后面clen长度的字节码

List Encoding

Redis List 结构在RDB文件中的存储,是依次存储List中的各个元素的。其结构如下:

  1. 首先按 Length Encoding 读取这个List 的长度 size

  2. 然后读取 size个 String Encoding的值

  3. 然后再用这些读到的 size 个值重新构建 List就完成了

Set Encoding

Set结构和List结构一样,也是依次存储各个元素的

Sorted Set Encoding

todo

Hash Encoding

  1. 首先按 Length Encoding 读出hash 结构的大小 size

  2. 然后读取2×size 个 String Encoding的字符串(因为一个hash项包括key和value两项)

  3. 将上面读取到的2×size 个字符串解析为hash 和key 和 value

  4. 然后将上面的key value对存储到hash结构中

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/322601.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

实验进行中:.NET WebAssembly支持

目前四大主流浏览器都默认支持WebAssembly,而.NET社区也在继续推动为.NET开发者提供相关能力,来将他们的代码编译成WebAssembly,然后在浏览器上运行。WebAssembly是一种二进制web格式,旨在以接近原生的性能运行不是用JavaScript语…

Js对象如何添加方法、查看Api

js万物皆对象,要带着观察对象的眼观去看待每一个函数、变量。 为什么要用到原型? Es6以前,js中没有如ooa编程当中的class,但是要用到类,怎么办呢,构造函数就应运而生,但是构造函数里面添加方法…

Java web文件下载断点续传

一、下载文件请求 RequestMapping(value "/file/download")ResponseBodypublic Res download(HttpServletRequest request, HttpServletResponse response) {File file new File(request.getParameter("fileName"));if (file.exists()) {String range …

ajax面试技术回答模板

ajax是什么? 缩写、核心 1.ajax就是异步的 JS 和 XML 的缩写,目前我们一般用 JSON 代替 XML。 2.该技术最核心概念是 XMLHttpRequest 对象,该对象可发起 HTTP 请求,我们可以监听其 readystate 的变化获得响应。 怎么用&#xff…

微软人工智能和对话平台--知识商城体验

前言微软最新发布 知识商城了!这是一个人工智能和对话平台应用的场景。他可以让开发者带着想法 出做天马行空的创造性工作!你只需要稍微动动手,如:拖拽板块,就可以做到极致对答、代码自动生成!想象一下&…

P1375-小猫【卡特兰数】

正题 题目链接:https://www.luogu.org/problemnew/show/P1375 题目大意 东西两两绑在一起,要求绳子不能交叉,求方案数。 解题思路 0表示压入第i只猫,1表示弹出栈顶的猫并且和第i只猫绑在一起,这样就能保证不会交叉。 也就是卡特…

Spring @Import注解配置类方法内部调用没有注入属性值的坑

一、场景复现 application.yaml spring:application:name: config-testprofiles:active: devconfig:config-01:name: zhansancode: 001config-02:name: lisicode: 002导入配置类 Configuration Import(ImportConfig.class) public class Config {BeanConfigurationPropertie…

使用Xamarin开发手机聊天程序 -- 基础篇(大量图文讲解 step by step,附源码下载)

如果是.NET开发人员,想学习手机应用开发(Android和iOS),Xamarin 无疑是最好的选择,编写一次,即可发布到Android和iOS平台,真是利器中的利器啊!而且,Xamarin已经被微软收购…

P3441-[POI2006]MET-Subway【图论,贪心】

正题 题目链接:https://www.luogu.org/problemnew/show/P3441 题目大意 求III条路径最多可以覆盖树上多少个点。 解题思路 我们先只考虑叶子节点,显然可以覆盖min{num叶,I∗2}min\{num_叶,I*2\}min{num叶​,I∗2}。 然后网上递推,发现依旧是min{numi,…

ssm创建一个查询接口

注解: controller Autowiredprivate UserService userService;service实体类 Service("userService")Autowiredprivate UserMapper userMapper;mapper Repositorycontroller 接收数据 > service 逻辑中转 > dao 数据库查询 > domain bean类映…

Spring Boot 数据库连接池入门

转载自 芋道 Spring Boot 数据库连接池入门 本文在提供完整代码示例,可见 https://github.com/YunaiV/SpringBoot-Labs 的 lab-19 目录。 原创不易,给点个 Star 嘿,一起冲鸭! 1. 概述 在我们的项目中,数据库连接池基…

.net core 实现简单爬虫—抓取博客园的博文列表

一.介绍一个Http请求框架HttpCode.CoreHttpCode.Core 源自于HttpCode(传送门),不同的是 HttpCode.Core是基于.net standard 2.0实现的,移除了HttpCode与windows相耦合的api,且修改了异步实现,其余特性完全与…

P3216-[HNOI2011]数学作业【矩阵乘法,数学】

正题 题目链接:https://www.luogu.org/problemnew/show/P3216 题目大意 求1∼n1\sim n1∼n连起来%m\% m%m之后的值。 解题思路 我们可以考虑矩乘&#xff0c;但是当xxx位数时每次乘上10x10^x10x&#xff0c;所以我们对于不同位分开处理就好了。 codecodecode #include<c…

spring boot使用注解的方式整合mybaits

使用注解整和mybatis&#xff0c;不需要任何的xml注释&#xff0c;只需要在 SpringBootApplication 加上一行mapper的扫描文件即可 MapperScan("com.k1998.mybatis.mapper")在application.properties配置 server.port8000 server.context-path/test#编码格式 serv…

SpringBoot2.1.9 Mybatis由于@Mapper注解多数据源配置不生效问题

一、场景复现 &#xff08;1&#xff09;项目 目录 配置文件 spring:application:name: multi-datasourceprofiles:active: dev1datasource:type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://localhost:3306/base?…

使用Windows兼容包简化向.NET Core的迁移

从.NET迁移到.NET Core的一个主要原因&#xff0c;在于后者具备在Linux上运行的能力。但是对于大型企业应用&#xff0c;不可能实现一步迁移到位。由此&#xff0c;Microsoft推荐采用一种逐步迁移做法&#xff1a;第一步&#xff0c;迁移到ASP.NET Core&#xff08;依然使用.NE…

nssl1304-最大正方形【二分答案】

正题 题目大意 一个N∗NN*NN∗N的01矩阵&#xff0c;求一个面积最大的全为1的正方形 解题思路 先O(n2)O(n^2)O(n2)预处理hi,jh_{i,j}hi,j​表示在(i,j)(i,j)(i,j)这个位置向右有多少个连续的1。然后二分边长。 时间复杂度:O(n2logn):O(n^2\ log\ n):O(n2 log n) codecodecode…

springboot使用xml配置mybatis

前面用注解配置了mybatis&#xff0c;非常的简单&#xff0c;但是在写动态sql语句的时候会非常的麻烦&#xff0c;所以这边我们用xml来重新配置一下 在resource目录下新建 SqlMapConfig.xml 主配置文件 <?xml version"1.0" encoding"UTF-8" ?> &…

SpringBoot2.1.9 Mybatis多数据源配置

一、配置文件 目录 application.yaml spring:application:name: multi-datasourceprofiles:active: devdatasource:type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://localhost:3306/base?autoReconnecttrue&ze…

自动类型安全的REST .NET标准库refit

在SCOTT HANSELMAN 博客上看到一个好东西《Exploring refit, an automatic type-safe REST library for .NET Standard》&#xff0c;他推荐了一个.NET标准1.4 的自动类型安全的REST库refit。 refit 类似于Java的Retrofit&#xff0c;是一套RESTful架构的.NET客户端实现&#x…