RDB & AOF持久化
1,RDB持久化
1.1 RDB文件的创建和载入
文件创建
SAVE和BGSAVE都可用于生成RDB文件
SAVE命令(阻塞式创建文件):阻塞Redis服务进程,直到RDB文件创建完毕,期间不能处理任何命令请求
BGSAVE命令(非阻塞式创建文件):派生一个子进程,由子进程负责创建RDB文件,父进程可继续处理命令请求
文件载入
服务器载入RDB文件期间,会一直处于阻塞状态,直到载入完成
1.2 自动间隔性保存
由于BGSAVE命令使用子进程持久化文件,Redis可以通过用户设置服务器配置的save ,让服务器每隔一段时间自动执行BGSAVE命令
save 900 1 --> 900s至少有一次修改
save 300 10 --> 300s至少有10次修改
save 60 10000 --> 60秒至少有10000次修改
设置保存条件
服务器根据配置的save选型设置服务器状态redisServer的saveparams属性(saveparams是数组)
saveparams[0] | saveparams[1] | saveparams[2] |
---|---|---|
seconds 900 | seconds 300 | seconds 60 |
changes 1 | changes 10 | changes 10000 |
dirty 与 lastsave
dirty计数器:记录距离上一次执行成功SAVE或BGSAVE命令后,服务器进行了多少次修改(含写入、删除、更新等),服务器成功执行一次修改,dirty就会对应增加
lastsave属性:unix时间戳,记录服务器上一次执行成功SAVE或BGSAVE命令的时间
serverCron定时检查
redis服务器会周期性的操作函数serverCron默认每隔100毫秒执行一次
检查save的选项值saveparams数组是否有满足条件的,有任意一个满足就会执行BGSAVE命令
2,AOF持久化
2.1 AOF持久化实现
-
命令追加
AOF持久化功能开启情况下,服务器在执行完一个写命令后,会以协议格式将被执行的写命令追加到aof_buf缓冲区尾端
-
文件写入
Redis服务进程是一个事件循环;文件事件负责接收客户端命令请求,以及向客户端发送命令回复。时间事件负责执行serverCron函数这种定时任务函数 服务器在文件事件时可能会执行写命令,会被追加到aof_buf缓冲区, 在服务器每次结束事件循环之前,会调用flushAppendOnlyFile函数, 根据appendfsync参数决定如何将aof_buf缓冲区内容刷入AOF文件中;
-
文件同步
为了提高文件写入效率,通常先将写入的数据暂存到内存缓存区,等缓冲区超过指定时限或者填满,才会刷入磁盘; 为了防止系统停机导致缓冲区数据丢失,系统提供fsync和fdatasync两个同步函数,可以强制让操作系统立即将缓冲区数据刷入到磁盘,确保写入数据的安全性;
2.2 AOF文件载入与数据还原
由于AOF包含了重建数据库状态所需的所有写命令,只要读入并从新执行一遍AOF文件的保存命令就可以还原数据
流程
创建一个不带网络连接的伪客户端(fake client)
从AOF文件中分析并读取一条写命令
使用伪客户端执行被读取的写命令
重复2,3步骤,直到AOF文件所有写命令执行完;
2.3 AOF重写
执行BGREWRITEAOF命令时,redis服务器会维护一个AOF重写缓冲区,在子进程创建新AOF文件期间,记录服务器执行的所有写命令。当子进程完成创建新的AOF文件后,服务器会将重写缓冲区的所有内容追加到新AOF文件末尾,使新旧AOF文件内容一致,最后AOF文件新旧原子替换,完成AOF文件重写操作
redis服务器调用aof_rewrite函数,创建一个新AOF文件替换现有AOF文件,新旧两个AOF文件保存的数据库状态相同,新AOF文件不会包含任何冗余的命令,比原AOF文件添加小很多,从而解决AOF文件膨胀问题;
redis服务器使用单线程处理命令请求,采用子进程方式执行AOF重写
子进程进行AOF重写时,父进程可以继续处理请求,不会被写阻塞
使用子进程而不是线程,可以在不加锁情况下保证数据安全
子进程执行AOF重写时,为了避免服务器进程写入新数据导致的数据不一致问题,服务器进程需要执行三步:
1,执行客户端发送的命令
2,执行后的写命令追加到AOF缓冲区
3,执行后的写命令追加到AOF重写缓冲区
子进程完成AOF重写后,通知父进程执行(确保子进程AOF重写一致性):
1,父进程将AOF重写缓冲区内容写入到新AOF文件,保证数据一致性
2,对新AOF文件改名,原子覆盖现有AOF文件,完成新旧AOF替换,而后才可以正常接收命令,从而保证了子进程执行AOF重写的一致性
3,AOF vs RDB
对比项 | AOF | RDB |
---|---|---|
记录方式 | 保存所执行的写命令来记录数据库状态 | 保存数据库的键值对来记录数据库状态 |
参考链接:
学习《Redis设计与实现》 笔记