• 我知道点redis-单机数据库(RDB持久化)


    我知道点redis-单机数据库(RDB持久化)

    10.1 RDB文件的创建和载入

    有两个Redis命令可以用于生成RDB文件,一个是SAVE,另一个是BGSAVE

    10.1.1 创建

    SAVE

    SAVE命令会阻塞Redis服务器进程,直到RDB文件创建完毕,在服务器进程阻塞期间,服务器不能处理任何请求。

    BGSAVE

    BGSAVE命令会派生一个subprocess,然后由子进程负责创建RDB文件,父进程继续处理命令请求。

    因为BGSAVE命令的保存工作是由subprocess执行的,所以在subprocess创建RDB file的过程中,Redis server仍然可以继续处理client的命令请求。但是在BGSAVE命令执行期间,server处理SAVEBGSAVEBGREWRITEAOF三个命令的方式会和平时有所不同。

    • 首先,在BGSAVE命令执行期间,SAVEBGSAVE命令将被reject。
    • 其次,在BGSAVE命令执行期间,BGREWRITEAOFBGSAVE两个命令不能同时执行。

    10.1.2 载入

    RDB文件的载入工作是在服务器启动时自动执行的,所以Redis没有专门用于载入RDB文件的命令。

    另外,值得一提的是,因为AOF文件的更新频率通常比RDB文件的更新频率高,所以:

    • 如果服务器开启了AOF持久化功能,那么server会优先使用AOF file来reduction db status;
    • 只有在AOF 持久化功能处于close状态时,server才会使用RDB file 来 reduction db status。

    10.2 自动间隔性保存

    因为BGSAVE命令可以在不阻塞server process的情况下执行,所以Redis允许用户通过设置server配置的save选项,让服务器每隔一段时间自动执行一次BGSAVE则不会。

    user可以通过save选项设置多个保存条件,但只要其中任意一个条件被满足,server就会执行BGSAVE命令。

    save 900 1表示服务器在900s内,对db进行了至少1次就修改。

    10.2.1 设置保存条件

    当Redis server启动时,用户可以通过指定配置文件或者传入启动参数的方式配置save选项。server根据save选项所设置的保存条件,设置server状态redisServersaveparams属性:

    struct redisServer {
    
    	// ...
    	
    	// 记录保存条件的数组
    	struct saveparam *saveparams;
    	
    	// ...
    
    }
    

    saveparams属性是个数组,数组中的每个元素都是一个saveparam结构,每个saveparam结构都保存了一个save选项设置的保存条件:

    struct saveparam {
    
    	// 秒数
    	time_t seconds;
    	
    	// 修改数
    	int changes;
    
    }
    

    10.2.2 dirty计数器和lastsave属性

    除了saveparams数组之外,服务器状态还维持着一个dirty计数器,以及一个lastsave属性:

    • dirty计数器记录着距离上一次成功SAVE命令或者BGSAVE命令之后,服务器对db status进行了多少次修改。
    • lastsave属性属于一个UNIX时间戳,记录了服务次上一次成功执行SAVE命令或者BGSAVE命令的时间.
    code
    struct redisServer {
    	
    	// ...
    	
    	// 修改计数器
    	long long dirty;
    	
    	// 上一次执行保存的时间
    	time_t lastsave;
    	
    	// ...
    }
    

    当Server成功执行一次db修改命令,dirty就会更新:命令修改了多少次db,dirty值就是多少。

    10.2.3 检查保存条件是否满足

    Redis的服务器周期性操作函数serverCron默认每隔100ms就会执行一次,该函数用于对正在运行的server进行维护,它的其中一项工作就是检查save现象所设置的保存条件是否已经满足,如果满足的话,就执行BGSAVE命令。

    // 伪代码
    def serverCron() :
    	
    	# ...
    	
    	# 遍历所有保存条件
    	for saveparam in server.saveparams:
    	
    		# 计算距离上次执行保存操作有多少秒
    		save_interval = unixtime_now() - server.lastsave
    		
    		# 如果数据库状态的修改次数超过条件所设置的次数
    		# 并且距离上次保存的时间超过条件所设置的时间
    		# 那么执行保存操作
    		if server.dirty >= saveparam.changes and 
    			save_interval > saveparam.seconds:
    				
    				BGSAVE()
    	# ...
    

    程序会遍历病检查saveparams数组中的所有保存条件,只要有任意一个条件被满足,那么server就会执行BGSAVE命令。

    以上就是Redis server根据save选项所设置的保存条件,自动执行BGSAVE命令,进行间隔性数据保存的实现原理。

  • 相关阅读:
    Java的特性和优势
    MyBatis
    SpringBoot简介
    Liunx
    MySql简介与入门
    Volatile
    MySQL简介
    Redis
    Spring IoC
    什么是springboot
  • 原文地址:https://www.cnblogs.com/wangxin201492/p/4762234.html
Copyright © 2020-2023  润新知