Redis持久化原理

一、RDB
原理: redis数据保存在内存中,为避免数据丢失,将某个时间节点的数据快照保存至一个二进制文件(经过压缩),通过该文件可以还原生成RDB文件时的数据库状态。
重写时机:
1、手动执行:手动调用save命令,bgsave命令;
2、自动间隔性保存:通过save选项配置的多个保存条件,只要其中任意一个条件满足,服务器就会执行bgsave命令;
默认:
save 900 1
save 300 10
save 60 10000
当redis服务器启动时,会通过配置文件或传入启动参数的方式读取save选项存入redisServer;Redis服务器周期性操作函数 serverCron默认每隔100ms会执行一次,它其中的一项任务就是检查save选项是否满足条件,满足则执行bgsave命令;

struct redisServer {
	// ...
	// 修改计数器(服务器成功执行一个修改命令,就会对dirty计数器进行更新)
	long long dirty;
	// 上一次执行保存的时间
	time_t lastsave;
	// 记录了保存条件的数组
	struct saveparam * saveparams;	
	// ...
}
/**
 * saveparams属性是一个数组,数组中每个元素的就是一个saveparam结构,每个saveparam结构都保存了
 * 一个save选项
 */ 
 struct saveparam {
 	// 秒数
 	time_t seconds;
 	// 修改数
 	int changes;
 }

服务器状态中的保存条件如下图:
(注:save命令会阻塞服务器进程,直到rdb文件创建完毕为止,在服务器进程阻塞期间,服务器不能处理任何命令请求,bgsave命令会派生出一个子进程,由子进程负责创建rdb文件,父进程继续处理命令请求, 在bgsave命令执行期间,在bgsave执行期间,客户端发送的save命令会被服务器拒绝。另外,bgrewriteaof和bgsave命令不能同时执行,bgsave命令执行期间,客户端发送的bgrewriteaof命令会被延迟至bgsave命令执行完之后,bgrewriteaof命令执行期间,bgsave命令会被拒绝)
RDB文件结构:
如下图所示:
1、REDIS:5个字节,用于标识该文件为rdb文件;
2、db_version:4个字节,值为一个字符串表示的整数,记录了rdb文件的版本号;
3、databases:包含0个或任意多个数据库,以及各个数据库中的键值对数据,如果服务器所有数据库都是空的,这个部分也为空长度为0字节,否则该部分长度根据数据库表村的键值对数量、类型、内容不同,该部分长度也有所不同;
4、EOF:常量,1字节,标志这rdb文件正文内容结束;
5、check_sum:8字节长的无符号整数,保存这一个校验和,该校验和是程序根据前四部分计算得出,用于载入时检查rdb文件是否损坏;
在这里插入图片描述
二、AOF
原理: aof持久化通过保存redis服务器所有的写命令来记录数据库状态,服务器启动时,通过载入和执行aof保存的命令来还原服务器关闭之前的数据库状态。
实现过程:
1、命令追加(append)
将被执行的写命令(遵从redis协议)追加到服务器状态的aof_buf缓冲区末尾;

struct redisServer {
	// ...
	// aof缓冲区
	sds aof_buf;
	// ...

2、文件写入
redis服务器进程是一个时间循环,其中文件事件负责接收客户端命令请求,以及发送命令回复。时间时间负责执行serverCron这样的定期执行的函数。
服务器在处理文件事件时会执行写命令,并将一些内容追加到aof_buf缓冲区中,在每次结束事件循环前,都会调用flushAppendOnlyFile函数,考虑将aof_buf缓冲区的内容写入aof文件中。flushAppendOnlyFile函数的追加行为由服务器配置的 appendfsync决定:
always:每次写入命令结束后都同步;
everysec(默认): 每秒同步一次;
no:何时同步由操作系统决定;
3、文件同步(sync)

AOF文件载入过程:
aof文件载入过程
AOF重写:
aof是通过保存被执行过的写命令来记录数据库状态,随服务器运行时间的越来越长,aof文件也会越来越大,这会对redis服务器造成影响,并且,载入数据的时间就会越多。为了解决这个问题,redis提供了文件重写功能。
redis会根据当前数据的数据快照,重写aof文件(无冗余命令),完成后进行aof文件的替换。
注意:为了避免在执行命令时造成客户端输入缓冲区溢出,重写程序在处理哈希表,集合,有序集合这四种可能带有多个元素的键时,会先检查键所包含的元素个数,若超过64(不同版本可能不同)重写程序会用多余的sadd(对于list集合)来记录这个集合。
AOF后台重写:
aof重写函数aof_rewrite包含大量的写入操作,若由服务器直接调用aof_rewrite会造成在aof重写期间,无法处理客户端发送的命令请求(redis单线程),因此redis将这个重写程序放到子进程中执行,这样既可以重写同时提供命令请求,还可以在避免使用锁的情况下,保证数据安全;
AOF重写缓冲区:
为了防止在aof重写期间,同时处理客户端请求造成数据不一致,Redis服务器设置了一个aof重写缓冲区,这个缓冲区在服务器创建子进程之后开始使用,当Redis服务器执行完一个写命令后,它会同时将这个写命令发送至aof缓冲区和aof重写缓冲区。
当子进程完成aof文件的重写后,它会向父进程发送一个信号,父进程收到信号后调用信号处理函数,将aof重写缓冲区的数据写入新的aof文件中,并将新的aof文件进行改名,原子的替换现有的aof文件。(注:调用信号处理函数期间,会对服务器进程造成阻塞)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值