Redis支持RDB和AOF两种持久化机制,持久化功能有效地避免因进程退出造成地数据丢失问题,当下次重启时利用之前持久化单位文件即可实现数据恢复。
1、RDB持久化是把当前进程数据生成快照保存到硬盘的过程,触发RDB持久化过程分为手动触发和自动触发。手动触发分别对应save和bgsave命令:save命令,阻塞当前Redis服务器,直到RDB过程完成为止,对于内存较大的实例会造成长时间阻塞,线上环境不建议使用;bgsave命令,Redis进程执行fork操作创建子进程,RDB持久化过程由子进程负责,完成后自动结束,阻塞只发生在fork阶段,一般时间很短。显然bgsave命令是针对save阻塞问题做的优化。
1.1、Redis默认采用LZF算法对生成的RDB文件做压缩处理,压缩后的文件远小于内存大小,默认开启,可以通过命令config set rdbcompression{yes | no} 动态修改,可以使用Redis提供的redis-check-dump工具检测RDB文件并获取对应的错误分析报告。
1.2、RDB的优点:
a、RDB是一个紧凑的压缩的二进制文件,代表Redis在某个时间点上的数据快照。非常适用于备份,全量复制等场景,比如每8小时执行bgsave备份,并把RDB文件拷贝到远程机器或文件系统中,用于灾难恢复。
b、Redis加载RDB恢复数据远远快于AOF的方式。
1.3、RDB的缺点
a、RDB方式数据没办法做到实时持久化/秒级持久化。因为bgsave每次运行都要执行fork操作创建子进程,属于重量级操作,频繁执行成本过高。
2、AOF(append only file)持久化,以独立日志的方式记录每次写命令,重启时再重新执行AOF文件中的命令达到恢复数据的目的。AOF的主要作用是解决了数据持久化的实时性,目前已是Redis持久化的主流方式。开启AOF功能需要设置配置:appendonly yes,默认不开启。AOF文件名通过appendfilename配置设置,默认文件名是appendonly.aof。AOF的工作流程操作:命令写入(append)、文件同步(sync)、文件重写(rewrite)、重启加载(load)。流程如下:
a、所有的写入命令会追加到aof_buf(缓冲区)中,AOF命令写入的内容直接是文本协议格式;
b、AOF缓冲区根据对应的策略向硬盘做同步操作;
c、随着AOF文件越来越大,需要定期对AOF文件进行重写,达到压缩文件的目的;
d、当Redis服务器重启时,可以加载AOF文件进行数据恢复。
2.1、文件同步,Redis提供了多种缓冲区同步文件策略,由参数appendfsync控制
a、配置为always时,每次写入aof_buf后调用系统fsync操作同步到AOF文件,不建议配置;
b、配置为no,命令写入aof_buf后调用系统write操作,不对AOF文件做fsync同步,同步硬盘操作由操作系统负责,每次同步AOF文件的周期不可控,而且会加大每次同步硬盘的数据量,无法保证数据安全性;
c、配置为everysec,是建议的同步策略,也是默认配置,做到兼顾性能和数据安全性,理论上只有在系统突然宕机的情况下会丢失1秒的数据。
2.2、重写机制,随着命令不断写入AOF,文件会越来越大,为了解决该问题,Redis引入了AOF重写机制压缩文件体积。AOF文件重写是把Redis进程内的数据转化为写命令同步到新AOF文件的过程。重写后的AOF文件变小的原因如下:
a、进程内已经超时的数据不再写入文件;
b、旧的AOF文件含有无效命令,重写使用进程内数据直接生成,这样新的AOF文件只保留最终数据的写入命令;
c、多条写命令可以合并一个,如rpush list a、rpush list b可以转化为rpush list a b;
2.2.1、AOF重写过程分为手动触发和自动触发:
a、手动触发:调用bgrewriteaof命令;
b、自动触发:根据auto-aof-rewrite-min-size和auto-aof-rewrite-percentage参数确定自动触发时机,其中auto-aof-rewrite-min-size表示运行AOF重写时文件最小体积,默认为64MB;auto-aof-rewrite-percentage代表当前AOF文件大小和上一次重写后AOF文件大小的比值。
3、当Redis做RDB或AOF重写时,一个必不可少的操作就是执行fork操作创建子进程,对于很多操作系统来说fork是个重量级操作,虽然fork创建的子进程不需要拷贝父进程的物理内存空间,但是会复制父进程的空间内存页表。