Redis设计与实现:第十章 - RDB持久化

参考:《Redis设计与实现》

1、RDB文件左右

数据库状态:
       服务器中非空数据库以及它们的键值对。

数据库状态磁盘化:
       Redis是 内存数据库,它将自己的数据库状态存在内存中,所以如果不想办法将存储在内存中的数据库状态保存到磁盘,一旦进程退出,服务器中的数据库状态也会消失不见。
       为了解决上述问题,Redis提供了RDB持久化功能,这个功能可以将Redis在内存中的数据库状态保存到磁盘,避免数据的意外丢失

RDB持久化:
       可以手动触发,也可以根据服务器配置选项周期性执行,将某个时间点上的数据库状态保存到RDB文件中。

RDB文件:
       是一个经过压缩的二进制文件,通过改文件可以还原生成RDB文件时的数据库状态。RDB文件是保存在磁盘上的,所以即使Redis服务器进程退出,只要RDB文件存在,Redis服务器就可以还原数据库状态。

       

2、RDB文件的创建和载入

       有两个命令可以生成RDB文件,分别是SAVEBGSAVE
       

1、SAVE-RDB文件创建

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

SAVE的代码处理实现:

	def SAVE():
		//创建RDB文件
		rdbSave()

       

2、BGSAVE-RDB文件创建

       BGSAVE命令会派生出一个子进程,通过子进程创建RDB文件,服务器进程(父进程)继续处理命令请求。

BGSAVE的代码处理实现:

	def BGSAVE():
		pid = fork()  //fork子进程
		if pid == 0 :
			rdbSave() //RDB文件保存
			signal_parent() //给父进程发送信号
		else if pid > 0:
			handle_request_and_wait_signal() //处理客户端请求,并轮训等待子进程的信号
		else:
			handle_fork_error() //处理错误的情况

BGSAVE命令执行期间其他命令的可执行性

  • 如果客户端发送SAVE命令会被服务器拒绝,原因是:避免父进程和子进程同时执行两个rdbSave调用,产生竞争关系
  • 如果客户端发送BGSAVE命令会被服务器拒绝,原因是:两个BGSAVE命令也可能产生竞争关系
  • 如果客户端发送BGREWRITEAOF(AOF)命令,会被延迟到BGSAVE命令执行结束之后执行,原因:虽然两个子进程之间不冲突,但是为了避免两个子进程同时执行大量的磁盘写入操作
  • 如果服务器正在执行BGREWRITEAOF命令,客户端发送BGSAVE命令会被服务器拒绝。
           

3、RDB文件载入

       RDB文件的载入是在服务器启动时自动执行的,Redis并没有专门用于载入RDB文件的命令,只要redis服务器启动时检测到RDB文件,就会自动载入。

       因为AOF文件的更新频率比RDB文件更高,所以如果服务器开启AOF持久化功能,会优先通过AOF文件来还原数据库状态。所以整个的执行过程如下:
在这里插入图片描述

       服务器在载入RDB文件的过程中,会一直处于阻塞状态,直到载入工作完成为止。
       

3、RDB文件自动间隔性保存

1、save选项配置

       Redis允许用户通过设置服务器配置save选项,服务器隔一段时间之后会执行一次BGSAVE命令。

save选项对应的代码结构:

	{
		struct saveparam *saveparams //保存对应配置的数组
		
		struct saveparam{
			time_t seconds  //秒数
			int changes //修改数
		}
	}

save选项默认值和意义:

	save 900 1
	save 300 10
	save 60 10000
	
	##含义
	#第一行:服务器在900秒之内至少进行了1次修改
	#第二行:服务器在300秒之内至少进行了10次修改
	#第三行:服务器在60秒内至少进行了10000次修改
	#只要满足其中一个条件就会触发BGSAVE操作	

       

2、具体实现

       Redis服务器通过dirty计数器(操作了多少个数据库数字就加上多少的值)和lastsave最后一次保存时间,来实现是否执行BGSAVE命令的判断:

具体的数据结构如下:

	struct redisServer{
		long long dirty  //dirty计数器	
		time_t lastsave  //上一次进行保存的时间信息
	}

       Redis 的服务器周期性函数serverCron默认每隔100毫秒执行一次,通过检查save选项的条件是否满足,来判断是否进行BGSAVE函数的执行。

4、RDB文件结构

       RDB文件结构如下,键值对的value存储可能采用压缩,存储的类型也会导致value的多样化,可参考原书:
在这里插入图片描述
地址:RDB文件结构图解

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章