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持久化的更多相关文章

  1. redis源码分析(三)--rdb持久化

    Redis rdb持久化 Redis支持两种持久化方式:rdb与aof.rdb将一个节点上的内存数据序列化后存储到磁盘中,序列化的数据以尽可能节约空间的方式存储,并非完全的ascii表示.它的优点在于 ...

  2. 深入剖析 redis RDB 持久化策略

    简介 redis 持久化 RDB.AOF redis 提供两种持久化方式:RDB 和 AOF.redis 允许两者结合,也允许两者同时关闭. RDB 可以定时备份内存中的数据集.服务器启动的时候,可以 ...

  3. Redis数据持久化之RDB持久化

    因为Redis服务器将数据存储在内存里面,而一旦服务器被关闭或者运行服务器的主机本身被关闭的话,存储在内存里面的数据就会消失不见: 如果我们仅仅是将redis用作缓存的话,那么这种数据丢失带来的问题并 ...

  4. 第二部分之RDB持久化(第十章)

    RDB持久化功能所生成的RDB文件是一个经过压缩的二进制文件,通过该文件可以还原生成RDB文件时的数据库状态.(数据库状态:服务器中的非空数据库以及它们的键值对统称为数据库状态) 一.RDB文件的创建 ...

  5. Redis详解(六)------ RDB 持久化

     前面我们说过,Redis 相对于 Memcache 等其他的缓存产品,有一个比较明显的优势就是 Redis 不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,has ...

  6. 使用AOF持久化文件实现还原Redis数据库并得到RDB持久化文件

    目录 1 编写本文的初衷 2 具体实施 2.1 Redis持久化概念简介 2.2 获取指定Redis的AOF持久化文件 2.3 把Redis的持久化AOF文件转换为RDB文件 1 编写本文的初衷 因为 ...

  7. redis之RDB持久化与AOF持久化

    Redis是一个键值对数据库服务器,服务器中通常包含着任意个非空数据库,而每个非空数据库中又可以包含任意个键值对,为了方便起见,我们将服务器中的非空数据库以及它们的键值对统称为数据库状态. 因为Red ...

  8. redis 笔记03 RDB 持久化、AOF持久化、事件、客户端

    RDB 持久化 1. RDB文件用于保存和还原Redis服务器所有数据库中的所有键值对数据. 2. SAVE命令由服务器进程直接执行保存操作,所以该命令会阻塞服务器. 3. BGSAVE由子进程执行保 ...

  9. 《Redis设计与实现》- RDB持久化

    Redis RDB持久化功能可以将Redis内存中的数据库状态保存到磁盘里面,避免数据意外丢失. 1. 手动生成 RDB 文件 有两个Redis命令可以用于生成RDB文件: SAVE,该命令会阻塞Re ...

随机推荐

  1. 在html中使用特殊字体

    目的:一首诗,要求从右往左读,垂直排列,类似古文 效果图: html内容: <!doctype html><html lang="en"><head& ...

  2. Django下自定义标签和过滤器

    ---恢复内容开始--- 第一步:确保setting中的INSTALL_APPS配置当前的app,要不然Django无法找到自定义的simple_tag. 第二步:在app中创建templatetag ...

  3. sublime text2 中标签高亮效果BracketHighlighter插件

    1.打开package Control,选择install Package 2.输入BracketHighlighter,回车 3.这样该插件会自动安装,安装后所有的提示高亮都是白色或没有提示.按 p ...

  4. CSS3布局之多列布局columns详解

    columns语法:columns:[ column-width ] || [ column-count ]设置或检索对象的列数和每列的宽度 其中:[ column-width ]:设置或检索对象每列 ...

  5. Markdown简单上手

    标题 # +内容 一级标题 二级标题 三级标题 四级标题 五级标题 六级标题 字体 1. 加粗(Ctrl+B) **加粗** 2. 斜体(Ctrl+I) *斜体* 3. 斜体加粗(Ctrl+B+I) ...

  6. Sublime Text 2 2.0.2 序列号

    ----- BEGIN LICENSE -----Andrew WeberSingle User LicenseEA7E-855605813A03DD 5E4AD9E6 6C0EEB94 BC9979 ...

  7. Spring的原理性总结

    一.Bean的生命过程 Bean的生命过程可以借鉴Servlet的生命过程,了解其生命过程对于不管是思想还是以后的使用都很有帮助: Bean可以通过两种方式进行加载,分别是使用BeanFactory ...

  8. testNG安装一直失败解决方法

    1.在eclipse界面选择“Help”--"Eclipse Marketplace"中进行查找TestNG 然后进“install” (成功) 2.在eclipse界面选择“He ...

  9. Android Studio手动打包

    项目写完了,现在需要把应用上传到市场上面,那么怎么把项目打包成apk?(Android的可安装文件). 1. 创建签名文件 2. 填写好签名参数 3. 生成APK 注意:签名的密码和密匙的密码注意保管 ...

  10. Linux 最小化安装后IP的配置(手动获取静态IP地址)

    一.图形化界面配置(假设为电脑A) 如果你的Linux安装有图形化界面,那么通过以下方式来配置: 我这里是有两块网卡,第一个网卡在上篇中已经通过DHCP来配置了:Linux 最小化安装后IP的配置(D ...