什么是数据库状态
redis是一个键值对的数据库服务器,服务器中通常包含中任意个非空的数据库,而每个数据库又可以包含任意个键值对,为了方便起见,我们将服务器中的非空数据库以及他们的键值对统称为数据库状态。
RDB持久化的逻辑
RDB持久化就可以手动执行也可以根据服务器配置选项定期的执行,该功能可以将某个时间点上的数据库状态保存到一个RDB文件中,这个文件其实是一个二进制的文件,通过这个文件可以还原生成RDB文件时的数据库状态。
RDB文件的创建
有两个生成redisRDB文件的命令,一个是SAVE,一个是BGSAVE。SAVE命令是使用服务器进程来生成RDB文件,在生成RDB文件的时候,会阻塞所有的读写操作,服务器不能处理任何命令请求。BGSAVE命令是同过服务器进程派生出来一个子进程,然后有子进程负责创建RBD文件,服务器进程可以继续处理命令请求。
其实创建RDB文件的工作都是通过rdbsave函数实现的是不过两种命令以不同的方式调用这个函数。
SAVE命令执行时的服务器状态
其实这个很简单,我们上面已经提到过SAVE命令或阻塞一切请求,当然拥抱口BGSAVE请求了,所以在执行SAVE期间,再次执行BGSAVE命令会被直接拒绝。
BGSAVE命令执行时的服务器状态
我们知道BGSAVE命令是服务器的子进程来完成的,服务器进程可以继续接收和执行命令,但是再BGSAVE命令执行期间服务器处理SAVE、BGSAVE、BGREWRITEAOF三个命令的方式和平时有所不同,主要有一下几种情形:
1.在BGSAVE命令执行期间,客户端发起的SAVE命令会被服务器拒绝。服务器禁止SAVE命令和BGDAVE命令同时执行是为了避免父进程和子进程同时执行两个rdbsave调用,防止产生竞争条件。
2.在BGSAVE命令执行期间客户端发起BGSAVE命令会被服务器拒绝,因为同时执行两个BGSAVE命令也会产生竞争条件
3.在BGSAVE命令执行期间,客户端发起BGREWRITEAOF命令会被延迟到BGSAVE命令执行完毕之后执行
4.在BGREWRITEAOF命令执行期间,客户端发起BGSAVE命令会被服务器直接拒绝,主要是因为BGREWRITEAOF和BGSAVE命令都是由子进程来完成的,禁止他们同时执行知识一个性能方面的考虑,因为并发出两个子进程,并且这两个子进程同时进行大量的磁盘写入操作,并不是什么好事情。
RDB文件的载入
对于RDB文件的载入就相对简单了,RDB文件的载入工作是在服务器启动的时候自动执行的,并且在服务器载入RDB文件期间,会一直处于阻塞状态,直到载入工作完成为止。
RDB自动间歇性保存
上面我们讲了如何创建RDB文件,但是什么时候来创建RBD文件呢?除了手动的执行命令之外,我们还可以通过配置来让服务器自动来创建RDB文件,我们可以在redis的配置文件中通过以下配置来实现:
save 900 1 save 300 10 save 60 10000
用户可以通过save选项设置多个保存条件(当然可以超过三个了,十个八个都可以,因为这些保存条件其实是保存在一个数组中的),但是只要其实任意一个条件满足,服务器就会执行BGSAVE命令。而上面的三条保存配置其实也是在我们开启了RDB持久化但是没有配置相关保存条件下时服务器给的默认的配置。
RDB自动保存的触发原理
我们知道了如何配置保存条件的,但是这个保存条件是怎么触发的呢?
其实服务器除了通过一个数据存储我们的保存条件外,还会维持一个dirty的计数器,以及一个lastsave属性,其中dirty计数器用来统计距离上一次成功执行SAVE命令或者BGSAVE命令后服务器对数据库状态进行了多少次修改(包括写入,删除,更新等操作),而lastsave属性是一个UNIX的时间戳,记录了服务器上一次成功执行SAVE命令或者BGSAVE命令的时间。这两个值都会在成功执行完BGSAVE命令后重置:dirty重置成0,lastsave更新为当前时间。
而对于条件的判断则是Redis服务器会周期性的操作函数serverCron默认每隔100毫秒执行一次,该函数用于对正在运行的服务器进行维护,它的其中一项工作就是检查save选项所设置的保存条件是否满足,如果满足则执行BGSAVe命令。必须同时满足的条件是:1.距离上一次成功执行保存的时间超过设置的时间,2.数据库状态的修改次数超过设置的修改次数
RDB的文件结构
暂略
原文地址:https://www.cnblogs.com/htyj/p/11731396.html