Redis支持RDB(快照)和AOF(日志)两种持久化机制,持久化能有效的避免因进程退出造成的数据丢失的问题,重启后利用持久化文件做数据恢复。
一、RDB
RDB是把当前进程数据生成快照保存到硬盘的过程。利用子进程做数据持久化,不会修改现有的内存数据结构,只是序列化到磁盘中。父进程需要持续服务客户端的请求,对内存数据结构进行不间断的更改。触发RDB持久化过程分为手动和自动触发两种。
手动触发:使用save(阻塞当前redis服务器线程,一直到RDB完成,内存大会造成长时间的阻塞)命令和bgsave(使用fork操作创建子进程,RDB持久化过程有子进程负责,完成后自动结束。阻塞发生在fork阶段,耗时短)命令。bgsave命令是save命令的一个优化,save命令目前已经被废弃了。
自动触发:使用save命令 ,如save m n,标识m秒内数据集存在n次修改触发一次bgsave。从节点执行全量复制操作,主节点自动执行bgsave生成RDB文件给从节点。
bgsave工作流程图:
操作流程:
- 执行bgsave命令,父进程需要校验当前是否有正在执行的子进程(比如RDB、AOF),如果存在bgsave直接返回。
- 不存在正在执行的子进程,父进程执行fork操作创建子进程,fock操作中父进程会阻塞。
- 父进程fork完成后,bgsave命令会返回"Background saving started" 信息并不再阻塞父进程,父进程才可以继续响应其他的命令。
- 子进程创建RDB文件,根据父进程内存生成的临时快照文件,完成后对原有文件进行替换。
- 替换完成,子进程发送信号给父进程,父进程更新统计信息。
RDB优点:RDB能够保存某个时间节点的一个二进制的压缩文件,适合备份,全量复制等场景用于数据恢复。比如n个小时执行一次bgsava命令数据进行备份。
RDB缺点:
- RDB数据不能保持实时持久化,重启可能会有数据丢失。
- 每次要fork子进程会导致主进程停顿,频繁执行成本过高,数据比较大会导致停顿时间较长。
二、AOF
AOF持久化是以独立日志的方式记录每次写命令,重启时在重新执行AOF文件中的命令达到恢复数据的目的。主要作用是解决了数据实时持久化。单独使用AOF持久化耗时久。AOF 持久化默认关闭,通过配置appendonly yes开启。
1.使用AOF:
AOF工作流程图:
操作流程:
- 所有的操作命令都会追加到aof_buf(缓冲区)中。
- AOF缓冲区根据设置的策略向磁盘做同步操作。
- AOF文件越来越大,需要定期对AOF文件进行重写,达到压缩的目的。
- 当redis服务重启时,可以加载AOF文件进行数据恢复。
2.同步磁盘策略:使用参数appendfsync控制,值分别为always(每次,性能低),no(系统控制,最长30s,不可控),everysec(默认配置,1s一次,性能高)。
3.重写机制:避免AOF文件越来越大,AOF文件瘦身,开辟子进程对内存进行遍历转换成一系列redis的操作指令(超时数据删除,文件中包含无效命令,多条写命令合并为一个),序列化到新AOF文件,序列化后将操作起劲的AOF日志,追加到新AOF文件。替换旧文件。重写机制可以手动触发和自动触发。
手动触发:直接调用bgrewriteaof命令。
自动触发:根据auto-aof-rewrite-min-size(运行AOF重写时文件最小体积默认64MB)和auto-aof-rewrite-percentage(代表当前AOF文件空间和上一次重写后AOF文件空间的比值)参数确定自动触发时机。
AOF重写流程:
流程说明:
- 执行AOF重写的请求。
- 父进程执行fork创建子进程
- 主进程操作完成后,继续相应其他的命令。修改命令写入缓冲区根据appendfsync策略同步到旧的aof文件。
- fork操作采用copy-on-write方式,子进程只能共享fork操作当时的内存数据。父进程相应命令,redis使用AOF重写缓冲区(aof_rewrite_buf)保存这部分新数据,防止新的AOF文件丢失这部分数据。
- 子进程根据内存快照,按照命令合并规范写入新的AOF文件,写入硬盘数据量由aof-rewrite-incremental-fsync配置,默认32MB(防止单词刷盘数据过多造成硬盘阻塞)。
- 新AOF文件写入成功后,子进程发送信号给父进程,父进程更新统计信息。
- 父进程把AOF重写缓冲区的数据写入到新的AOF文件。
- 使用新的AOF文件替换老的AOF文件,完成AOF重写。
4.重启加载
AOF和RDB文件都可以用于服务器重启时的数据恢复。redis重启优先加载AOF文件。
持久化文件重启加载流程图:
AOF优点:
- AOF文件是一个纯追加的日志文件。
- AOF文件过大,会自动在后台进行重写。
- AOF文件有序保存对数据的执行顺序以命令的方式保存。
AOF缺点:
- 相同的内容AOF会比RDB文件大。
- 根据使用的appendfsync策略,AOF的写入速度可能会比RDB慢。关闭缓冲区,效率没区别。
三、混合持久化
重启redis,如果使用RDB恢复数据可能会丢失部分数据,通常使用AOF日志重放,重放AOF日志性能相比RDB要慢很多,如果数据量大很耗时。为了解决这个问题redis4.0提供了新的持久化方式混合持久化。 在AOF 重写过程才会使用混合持久化。重写后新的AOF文件的前半部分是RDB格式的全量数据,后半部分AOF格式的增量数据。
混合持久化流程图:
操作说明:混合持久化是通过AOF后台重写(bgrewriteaof命令)完成的,开启持久化时候,fock出的子进程将RDB文件的内容以RDB的存储方式和增量的AOF日志文件放在一起生成新的AOF文件,新的AOF文件写入完成通知主进程将包含RDB格式和AOF格式的新的AOF文件替换掉旧的AOF文件。AOF保存的是appendonly.aof(RDB格式+AOF格式)文件。
开启混合持久化配置参数:aof-use-rdb-preamble=yes 4.0版本默认关闭,5.0版本默认打开。
数据恢复过程:
- AOF文件开始是RDB格式,先RDB格式内容在加载AOF格式内容。
- AOF文件开头不是RDB格式,直接用AOF格式加载整个文件。