《Redis设计与实现》读书笔记(十四) ——Redis RDB文件创建、载入与自动保存原理

《Redis设计与实现》读书笔记(十四) ——Redis RDB文件创建、载入与自动保存原理

(原创内容,转载请注明来源,谢谢)

一、概述

redis是一个键值对服务器,服务器中包含若干个非空数据库,数据库中包含若干个非空键值对。将非空数据库及其键值对统称为数据库状态。如下图所示:

由于redis是内存型数据库,必须要将数据保存到磁盘,才能保证数据不丢失。RDB持久化就是将数据库保存到磁盘的方式之一(另一种叫做AOF)。rdb可以手动执行,也可以根据服务器的配置定期执行,持久化后会将整个数据库备份成一个二进制文件存在磁盘,而还原则是将该二进制文件重新转成数据库存在内存。

二、rdb文件创建与载入

1、创建

有两个命令可以手动生成rdb文件——save和bgsave。

save会阻塞redis进程,直到save命令执行完毕;bgsave会创建一个子进程,由子进程处理rdb任务,父进程继续处理客户端请求。

保存rdb文件的过程,如果是bgsave命令,会先检查是否当前有还未完成的子进程,如果有的话会等待,待当前子进程完成任务后,才会开始执行bgsave。

1)save

由于save命令是阻塞的,因此当执行save命令期间,服务器会拒绝其他命令的请求,直到save命令执行完毕。

2)bgsave

bgsave是通过子进程进行创建rdb文件的工作,因此bgsave执行期间,服务器可以正常处理大部分的redis客户端请求,除了以下内容有所不同:

save:redis子进程在处理bgsave命令期间,会拒绝客户端发来的save命令,目的是为了避免父进程和子进程同时在创建rdb文件,也避免产生竞争条件。

bgsave:同样会被拒绝,同save。

bgwriteaof:bgsave执行期间,bgwriteaof命令会被延迟到bgsave命令执行完毕后才会执行; bgwriteaof执行期间,bgsave命令会直接被服务器拒绝。这两个命令都是由子进程进行,拒绝同时进行是为了考虑性能,并发处理两个大量写入磁盘的子进程是应当被避免的。

2、载入

载入比较简单,redis没有专门载入rdb文件的命令,每当redis服务器开启的时候,就会检查,如果存在rdb文件则自动载入。

但是由于aof的执行频率比rdb高,所以如果同时存在aof文件,则会载入aof文件,只有aof功能除以关闭状态,才会载入rdb文件。

redis服务器载入rdb文件期间,会一直处于阻塞状态,直到载入完毕。

如下所示:

三、自动保存

由于bgsave命令具有非阻塞特性,因此redis服务器运行用户通过配置文件中的save选项,让数据库每隔一段时间执行一次bgsave命令。save选项保存的是执行bgsave命令的条件,可以保存多个,只要有一个条件满足,服务器就执行bgsave命令。

save设置的示例如下:

         save900 1
         save300 10
         save60 10000

表示的含义是,下列情况发生一种就执行bgsave:redis服务器900秒内至少执行1次修改;300秒内至少执行10次修改;60秒内至少执行10000次修改。

上述的save条件也是redis配置save的默认值,即没有特意指定save条件,则都会按上述设置执行bgsave。

1、保存结构

服务器启动时,会读取save条件,并写入其redisServer结构的saveparams属性中。

         structredisServer{
         //…其他属性
         struct saveparam *saveparams;
}

由上可知,saveparams是一个数组,由saveparam结构元素组成。

         structsaveparam{
         time_t seconds;
         int changes;
}

由上结构可知,saveparam保存了时间和改变次数,即对应上述每一行save后面跟的两个参数。

上面默认的save条件配置的存储方式如下图所示:

2、dirty计数器和lastsave属性

dirty计数器记录距离上一次成功执行save或bgsave命令后,服务器对其中所有数据库进行的修改(增删改)的总次数。lastsave属性是一个UNIX时间戳,记录服务器上一次成功执行save或bgsave的时间。

         structredisServer{
         long long dirty;
         time_t lastsave;
}

结构如下图所示:

每执行一次修改,dirty值就加1,如果是批量修改命令如sadd等,一次修改多个值,则修改几个dirty的值就加多少。

这两个属性分别是用于比较save条件的两个参数——修改次数和时间,是否匹配,以判定是否要执行bgsave命令。

3、检查是否满足保存条件

redis服务器的周期性函数serverCron,默认每隔100毫秒执行一次,用来维护运行中的服务器,其中一项工作就是检查save条件,满足的话就执行bgsave命令。

其判断方式是,循环save配置,分别比较save每一条配置的修改次数与redisServer结构中的dirty属性值、当前时间减去lastsave属性判断经过的时间,有一个符合则执行bgsave命令。

总体结构体如下:

上述情况来看,dirty是123,则当时间经过300秒,就会自动执行bgsave。

执行完成后,dirty属性值清0,并且lastsave属性会被重新写入完成bgsave时间点的unix时间戳。

——written by linhxx 2017.09.04

原文发布于微信公众号 - 决胜机器学习(phpthinker)

原文发表时间:2017-09-04

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏专注数据中心高性能网络技术研发

调整进程的最大linux文件描述符

1.介绍 ---- ulimit 命令提供了针对 shell和或由该 shell 启动的进程占用资源的控制。  持久化修改生效是在/etc/security/l...

2795
来自专栏北京马哥教育

软件测试工程师必知必会Linux命令

Linux系统有着众多的优点,比如开源、非商业版本免费、多任务多用户操作,因此Linux系统在非桌面领域占有压倒性的市场份额。对于互联网技术工作者来说,掌握常用...

38413
来自专栏惨绿少年

Nginx软件优化

1.1 Nginx优化分类 安全优化(提升网站安全性配置) 性能优化(提升用户访问网站效率) 1.2 Nginx安全优化 1.2.1 隐藏nginx版本信息优化...

3968
来自专栏运维一切

ETCD的基本使用 转

原文地址: http://www.csdn.net/article/2015-01-22/2823659

993
来自专栏FreeBuf

闲聊Windows系统日志

最近遇到不少应急都提出一个需求,能不能溯源啊?这个事还真不好干,你把证据,犯案时间都确定的时候,要求翻看监控(日志)对应犯罪嫌疑人时,突然说监控(日志)没有记录...

1300
来自专栏懒人开发

linux:磁盘、文件大小,挂载相关

a:显示全部的档案系统和各分割区的磁盘使用情形 i:显示i -nodes的使用量 k:大小用k来表示 (默认值) t:显示某一个档案系统的所有分割区磁盘使...

988
来自专栏流媒体

Crontab

cron 是一个可以用来根据时间、日期、月份、星期的组合来调度对重复任务的执行的守护进程。cron 假定系统持续运行。如果当某任务被调度时系统不在运行,该任务就...

662
来自专栏程序猿DD

Swagger Starter 1.4.0发布:新增swagger功能开源与全局参数的配置。

该项目主要利用Spring Boot的自动化配置特性来实现快速的将swagger2引入spring boot应用来生成API文档,简化原生使用swagger2的...

3366
来自专栏皮振伟的专栏

[kvm][qemu]CPU虚拟化

前言: 这里作者再次自不量力了,以一点微末的道行分析一下KVM的CPU虚拟化部分的代码。 分析: 1,分析具体代码逻辑之前,可以先使用strace大致看一下...

2817
来自专栏开发与安全

linux网络编程之socket(七):一个进程发起多个连接和gethostbyname等函数

一、在前面讲过的最简单的回射客户/服务器程序中,一个客户端即一个进程,只会发起一个连接,只要稍微修改一下就可以让一个客户端发起多个连接,然后只利用其中一个连接发...

2170

扫描关注云+社区