第10章 RDB持久化
Redis是一种内存数据库,掉电即失,为了解决这个问题Redis提供了RDB持久化功能,该功能可以把Redis中的内容以RDB文件的形式存储在硬盘上,并且每次RedisServer启动的时候都会尝试从RDB文件中恢复内容。
10.1 RDB文件的创建与载入
创建RDB文件可以使用SAVA BGSAVE,前者是主进程直接创建RDB并保存内容,后者是新建子进程去持久化Redis内容,所以前者是阻塞后者是非阻塞的。
RDB文件的载入是自动的,只要Redis服务器启动的时候能够发现RDB文件的存在就会载入RDB文件。
10.1.1 SAVE命令执行时的服务器状态
SAVA命令会阻塞Redis服务器,直到SAVA命令执行完毕才会处理客服端的新的请求。
10.1.2 BGSAVE命令执行时的服务器状态
BGSAVA执行的时候不会阻塞Redis服务器,但是SAVA BGSAVA BGREWRITEAOF会有所不同
- 禁止SAVA命令执行,避免Redis进程,和用于执行BGSAVA的子进程同时执行rdbSAVE产生竞态条件
- 机制BGSAVA,同样是为了避免静态条件
- BGREWRITEAOF会被延迟到BGSAVA执行完毕,这是出于磁盘性能考虑,两个命令同时执行会执行大量的磁盘读写操作
10.2 自动间隔保存
因为BGSAVA不会阻塞Redis服务器,所以Redis会按照一定的时间间隔自动的保存Redis内容并生成RDB文件。
保存时间间隔可以在config文件中设置,如果没有设置将会使用默认的保存间隔。save 900 1代表如果900秒内执行了一次修改,就会执行BGSAVA命令。

config文件中的关于BGSAVE间隔的设置最终会体现在redisServer中,可以看到关于保存时间的设置是针对整个服务器的,而非数据库的。其中savaparams数组记录着所有的保存条件,每一个savaparams记录着秒数和修改数。


除了保存数和秒数外,redisServer结构还会记录上一次保存的时间,和上一次保存后服务器修改了多少次,从而判断当前Redis的状态是否满足savaparams的保存条件。从savaparams和dirty lastsave的存储位置可以看到,Redis使用RDB持久化是针对整个Redis服务器的,而非某个具体的数据库。因为对16个数据库无论哪个修改都会使dirty增加。
有了保存条件和记录当前Redis状态的字段后,Redis会执行一个周期性的函数,默认间隔是100毫秒,去轮询查询当前的条件是否满足保存的条件。
10.3 RDB文件结构

一个RDB文件主要由两部分组成,一部分是常量:REDIS魔数、EOF文件结束标志、db_version代表当前数据库的版本,也可以认为是一个常数。另一部分是database,真正用来存储数据库中的键值对和过期时间。
10.3.1 databases部分

一个完整的结构如上所示,databases部分由SELECTDB开始,紧接着是数据库的编号,最后pairs里面存储着真正的键值对。
10.3.2 key_value_pairs
根据键值对是否带有过期时间key_value_pairs的结构有所不同。


- TYPE,记录着value的类型,根据TYPE的不同Redis会用不同的方法去解释读进来的value字段
- key,键值对中的key,一定是String类型的
- value,键值对中的value,其类型由TYPE字段决定
10.3.3 value的编码
10.3.3.1 字符串对象
字符串对象对应的TYPE是REDIS_RDB_TYPE_STRING,即使是字符串也有两种编码REDIS_ENCODING_INT 和 REDIS_ENCODING_RAW。
如果字符串的编码是REDIS_ENCODING_INT说明此时字符串内存储的是一个整数。
如果字符型的编码是REDIS_ENCODING_RAW,说明字符串此时存储的是一个字符串,而又根据字符串的长度不同分为压缩表示和非压缩表示。
当字符串的长度小于20个字节的时候会采用下面的方式存储。

当Redis开启了字符串压缩表示且字符串的长度大于20个字节,字符串会被使用LZF算法压缩并存储。

10.3.3.2 列表对象
列表对象对应的TYPE是REDIS_RDB_TYPE_LIST,结构如下。其中list_lenght代表列表的长度,itemx代表列表中的每一项。Redis会用解析字符串的方式处理List中的每一个元素。

如一个存储了三个元素的链表如下所示,可见整数和字符串在Redis中都是使用String类型来存储的。

10.3.3.3 集合对象
集合对象对应的KEY是REDIS_RDB_TYPE_SET,结构和list看起来差不多。集合中每一个元素也都是String类型。


10.3.3.4 哈希表集合
哈希表对应的TYPE是REDIS_RDB_TYPE_HASH,也没啥特殊的,开头用来记录长度,后续用String类型来记录key-value。


10.3.3.5 有序集合
REDIS_RDB_TYPE_ZSET。
第10章 RDB持久化的更多相关文章
- redis源码分析(三)--rdb持久化
Redis rdb持久化 Redis支持两种持久化方式:rdb与aof.rdb将一个节点上的内存数据序列化后存储到磁盘中,序列化的数据以尽可能节约空间的方式存储,并非完全的ascii表示.它的优点在于 ...
- 深入剖析 redis RDB 持久化策略
简介 redis 持久化 RDB.AOF redis 提供两种持久化方式:RDB 和 AOF.redis 允许两者结合,也允许两者同时关闭. RDB 可以定时备份内存中的数据集.服务器启动的时候,可以 ...
- Redis数据持久化之RDB持久化
因为Redis服务器将数据存储在内存里面,而一旦服务器被关闭或者运行服务器的主机本身被关闭的话,存储在内存里面的数据就会消失不见: 如果我们仅仅是将redis用作缓存的话,那么这种数据丢失带来的问题并 ...
- 第二部分之RDB持久化(第十章)
RDB持久化功能所生成的RDB文件是一个经过压缩的二进制文件,通过该文件可以还原生成RDB文件时的数据库状态.(数据库状态:服务器中的非空数据库以及它们的键值对统称为数据库状态) 一.RDB文件的创建 ...
- Redis详解(六)------ RDB 持久化
前面我们说过,Redis 相对于 Memcache 等其他的缓存产品,有一个比较明显的优势就是 Redis 不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,has ...
- 使用AOF持久化文件实现还原Redis数据库并得到RDB持久化文件
目录 1 编写本文的初衷 2 具体实施 2.1 Redis持久化概念简介 2.2 获取指定Redis的AOF持久化文件 2.3 把Redis的持久化AOF文件转换为RDB文件 1 编写本文的初衷 因为 ...
- redis之RDB持久化与AOF持久化
Redis是一个键值对数据库服务器,服务器中通常包含着任意个非空数据库,而每个非空数据库中又可以包含任意个键值对,为了方便起见,我们将服务器中的非空数据库以及它们的键值对统称为数据库状态. 因为Red ...
- redis 笔记03 RDB 持久化、AOF持久化、事件、客户端
RDB 持久化 1. RDB文件用于保存和还原Redis服务器所有数据库中的所有键值对数据. 2. SAVE命令由服务器进程直接执行保存操作,所以该命令会阻塞服务器. 3. BGSAVE由子进程执行保 ...
- 《Redis设计与实现》- RDB持久化
Redis RDB持久化功能可以将Redis内存中的数据库状态保存到磁盘里面,避免数据意外丢失. 1. 手动生成 RDB 文件 有两个Redis命令可以用于生成RDB文件: SAVE,该命令会阻塞Re ...
随机推荐
- 在html中使用特殊字体
目的:一首诗,要求从右往左读,垂直排列,类似古文 效果图: html内容: <!doctype html><html lang="en"><head& ...
- Django下自定义标签和过滤器
---恢复内容开始--- 第一步:确保setting中的INSTALL_APPS配置当前的app,要不然Django无法找到自定义的simple_tag. 第二步:在app中创建templatetag ...
- sublime text2 中标签高亮效果BracketHighlighter插件
1.打开package Control,选择install Package 2.输入BracketHighlighter,回车 3.这样该插件会自动安装,安装后所有的提示高亮都是白色或没有提示.按 p ...
- CSS3布局之多列布局columns详解
columns语法:columns:[ column-width ] || [ column-count ]设置或检索对象的列数和每列的宽度 其中:[ column-width ]:设置或检索对象每列 ...
- Markdown简单上手
标题 # +内容 一级标题 二级标题 三级标题 四级标题 五级标题 六级标题 字体 1. 加粗(Ctrl+B) **加粗** 2. 斜体(Ctrl+I) *斜体* 3. 斜体加粗(Ctrl+B+I) ...
- Sublime Text 2 2.0.2 序列号
----- BEGIN LICENSE -----Andrew WeberSingle User LicenseEA7E-855605813A03DD 5E4AD9E6 6C0EEB94 BC9979 ...
- Spring的原理性总结
一.Bean的生命过程 Bean的生命过程可以借鉴Servlet的生命过程,了解其生命过程对于不管是思想还是以后的使用都很有帮助: Bean可以通过两种方式进行加载,分别是使用BeanFactory ...
- testNG安装一直失败解决方法
1.在eclipse界面选择“Help”--"Eclipse Marketplace"中进行查找TestNG 然后进“install” (成功) 2.在eclipse界面选择“He ...
- Android Studio手动打包
项目写完了,现在需要把应用上传到市场上面,那么怎么把项目打包成apk?(Android的可安装文件). 1. 创建签名文件 2. 填写好签名参数 3. 生成APK 注意:签名的密码和密匙的密码注意保管 ...
- Linux 最小化安装后IP的配置(手动获取静态IP地址)
一.图形化界面配置(假设为电脑A) 如果你的Linux安装有图形化界面,那么通过以下方式来配置: 我这里是有两块网卡,第一个网卡在上篇中已经通过DHCP来配置了:Linux 最小化安装后IP的配置(D ...