《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 条评论
登录 后参与评论

相关文章

来自专栏一个爱瞎折腾的程序猿

sqlserver使用存储过程跟踪SQL

USE [master] GO /****** Object: StoredProcedure [dbo].[sp_perfworkload_trace_s...

2070
来自专栏陈仁松博客

ASP.NET Core 'Microsoft.Win32.Registry' 错误修复

今天在发布Asp.net Core应用到Azure的时候出现错误InvalidOperationException: Cannot find compilati...

4868
来自专栏java 成神之路

使用 NIO 实现 echo 服务器

4687
来自专栏落花落雨不落叶

canvas画简单电路图

62511
来自专栏张善友的专栏

Miguel de Icaza 细说 Mix 07大会上的Silverlight和DLR

Mono之父Miguel de Icaza 详细报道微软Mix 07大会上的Silverlight和DLR ,上面还谈到了Mono and Silverligh...

2717
来自专栏杨龙飞前端

scrollto 到指定位置

2514
来自专栏pangguoming

Spring Boot集成JasperReports生成PDF文档

由于工作需要,要实现后端根据模板动态填充数据生成PDF文档,通过技术选型,使用Ireport5.6来设计模板,结合JasperReports5.6工具库来调用渲...

1.2K7
来自专栏C#

DotNet加密方式解析--非对称加密

    新年新气象,也希望新年可以挣大钱。不管今年年底会不会跟去年一样,满怀抱负却又壮志未酬。(不过没事,我已为各位卜上一卦,卦象显示各位都能挣钱...)...

4928
来自专栏张善友的专栏

Silverlight + Model-View-ViewModel (MVVM)

     早在2005年,John Gossman写了一篇关于Model-View-ViewModel模式的博文,这种模式被他所在的微软的项目组用来创建Expr...

2978
来自专栏张善友的专栏

Mix 10 上的asp.net mvc 2的相关Session

Beyond File | New Company: From Cheesy Sample to Social Platform Scott Hansel...

2587

扫码关注云+社区