1、简介
Redis的持久化方式有两种,AOF、RDB
2、RDB 持久化
RDB 触发方式有两种:save、bgsave,redis主进程接收到命令后fork子进程负责持久化
- redis主进程判断当前是否存在正在执行的子进程,如RDB、AOF子进程,若存在则直接返回;若不存在fork子进程,这时候主进程会被阻塞
- 主进程fork完成后,返回Background saving started,并恢复主进程
- 子进程创建RDB文件,根据父进程内存生成临时快照文件,完成后对原有文件进行原子替换
- 子进程发送信号通知父进程RDB持久化完成,父进程更新统计信息
- 优点:生成多个数据文件,适合做冷备;对redis读写性能影响小,备份操作由子进程完成;相对于AOF备份,占用空间更小、恢复更快;缺点:不能实时持久化;fork子进程会导致服务暂停数毫秒
3、AOF 持久化
通过append-only开启,有三种模式always、no、everysec,这三种模式的区别在于何时调用fsync命令将数据刷新到磁盘。1)always:每次写请求都会被刷新到磁盘;2)no:由操作系统决定,周期不可控,最长30秒;3)每隔一秒执行fsync,兼顾了数据完整性和redis的性能
- 根据序列化协议将命令序列化,追加到server.aof_buf。判断aof rewrite是否进行:是,内容追加到aof_rewrite_buf_blocks集合中,rewrite结束后,再把aof_rewrite_buf_blocks的缓冲添加到rewrite后的文件中
- 调用flushAppendOnlyFile函数,并根据aof持久化策略判断何时进行fsync,针对everysec:
- 首先判断是否需要强制写入(执行了shutdown、config set appendfsync no等命令),如果是,则调用aofWrite函数将命令写入系统缓冲区,再调用fsync刷新到磁盘,防止数据丢失
- 如果不是,判断fsync是否正在进行;1)是:则推迟当前fync,最多推迟两秒;2)否:先调用aofWrite将命令写入到系统页缓冲区,并在时间满足1秒后(根据server.unixtime以及server.aof_last_fsync),调用fsync将页缓冲区数据刷新到磁盘
- 优点:1)实时持久化缓存,避免数据丢失;2)append-only追加模式,减少磁盘寻址开销,写入性能较高;3)协议序列化,可读性好;
- 缺点:1)相对于rdb,aof备份的文件占用磁盘空间大;2)降低读写效率,主要由fsync导致;
4、AOF Rewrite
压缩、合并命令,以节约磁盘开销
- 主进程通过bgrewriteaof命令,fork一个子进程,由子进程执行压缩
- Rewrite期间,主进程将新命令追加到aof_buf、aof_rewrite_buf两个缓冲区
- 主进程接收到子进程rewrite完成命令后,把aof_rewrite_buf的数据写入到新的aof文件中,以保持aof文件和内存数据的一致
- 重命名新的AOF文件,覆盖掉老文件,完成AOF重写。