Redis支持RDB和AOF两种持久化机制。
RDB持久化就是把当前进程数据生成快照保存到硬盘的过程,触发RDB持久化过程分为手动触发和自动触发。

手动触发分别对应save和bgsave命令:
save命令:阻塞当前Redis服务器,知道RDB过程完成为止。对于内存比较大的实例会造成长时间的阻塞,线上环境不建议使用。

bgsave命令:Redis进程执行fork操作创建子进程,RDB持久化过程由子进程负责,完成后自动结束,阻塞只发生在fork阶段,一般时间很短。

redis主库报slave是什么情况 redis save m n_后端

除了手动,Redis内部还存在自动触发RDB持久化的机制。
1)使用save相关配置,如“save m n”。表示m秒内数据集存在n次修改,自动触发bgsave。
2)如果从节点执行全量复制,主节点自动执行bgsave生成RDB文件发送给从节点。
3)执行debug reload命令重新加载Redis时,也会自动触发save操作。
4)默认执行shutdown时,如果没有开启AOF持久化则自动执行bgsave。

redis主库报slave是什么情况 redis save m n_redis主库报slave是什么情况_02


1)执行bgsave,父进程判断是否存在执行的子进程(如RDB,AOF),如果存在bgsave命令直接返回。

2)父进程执行fork操作创建子进程。fork会阻塞。

3)fork完成后,父进程不在阻塞,可以相应其他命令。

4)子进程创建RDB文件。

5)进程发信号给父进程表示完成。

RDB优点:
RDB是一个紧凑压缩的二进制文件,代表Redis在某个时间点上的数据快照。适用于备份,全量复制等。
Redis加载RDB恢复数据快于AOF。

缺点:
RDB方式没办法做到实时持久化,因为bgsave每次运行都要执行fork创建子进程。

针对RDB不适合实时持久化的问题,Redis提供了AOF方式来解决。

AOF:以独立日志的方式记录每次写命令,重启时重新执行AOF文件的命令达到恢复数据的目的。解决了数据持久化的实时性。

redis主库报slave是什么情况 redis save m n_持久化_03


1)所有写入命令都会追加到aof_buf(缓冲区)中。

2)AOF缓冲区根据对应的策略向硬盘做同步操作。

3)随着AOF文件越来越大,需要定时对AOF进行重写,达到压缩的目的。

4)Redis重启后,可以加载AOF文件进行数据恢复。

重写机制:
随着命令不断写入AOF,文件会越来越大,Redis引入重写机制来压缩文件体积。AOF文件重写是把Redis进程内的数据转化为写命令同步到新AOF文件的过程。
为什么AOF文件可以变小?
1)已经过时的数据不再写入。
2)旧的AOF文件含有无效命令。
3)多条写命令可以合并为一个。

AOF重写过程可以手动触发和自动触发。
手动触发:直接调用bgrewriteaof命令。
自动触发:根据auto-aof-rewrite-min-size和auto-aof-rewrite-percentage参数确定自动触发时机。

redis主库报slave是什么情况 redis save m n_redis主库报slave是什么情况_04


1)执行AOF重写请求。

如果当前进程正在执行AOF重写,请求不执行并直接返回。

redis主库报slave是什么情况 redis save m n_持久化_05


如果当前进程正在执行bgsave操作,重写命令延迟到bgsave完成之后在执行。

redis主库报slave是什么情况 redis save m n_Redis_06


2)父进程执行fork创建子进程,开销等于bgsave过程。

3.1)主进程fork完成后,继续响应其他命令。所有修改命令依然写入AOF缓冲区并同步到硬盘,保证了原有AOF机制的正确性。

3.2)fork操作时,子进程只能共享fork操作时的内存。由于父进程依然响应命令,Redis使用AOF重写缓冲区保存这部分数据,防止AOF文件生成期间丢失。

4)子进程根据内存快照,按照命令规则写入到新的AOF文件中。

5.1)写入完成后,子进程发信号给父进程。

5.2 ) 父进程把AOF重写缓冲区数据写入到新的AOF文件。

5.3)使用新的AOF文件替换老文件,完成AOF重写。重启加载

AOF和RDB文件都可以用于服务器重启时的数据恢复。

redis主库报slave是什么情况 redis save m n_持久化_07

1)AOF持久化开启且存在AOF文件时,优先加载AOF文件。
2)AOF关闭或者AOF文件不存在时,加载RDB文件。
3)加载AOF/RDB文件成功后,Redis启动成功。
4)AOF/RDB文件存在错误时,Redis启动失败,并打印错误信息。

Redis持久化的问题定位
fork耗时问题定位:正常情况下fork耗时应该是没GB消耗20毫秒左右。

AOF追加阻塞

当开启AOF持久化时,常用的同步硬盘策略是everysec,对于这种方式,Redis使用另一种线程每秒执行fsync同步硬盘,当系统繁忙时,会造成Redis主线程阻塞。

redis主库报slave是什么情况 redis save m n_Redis_08


1)everysec配置最多可能丢失2秒数据。

2)如果系统fsync缓慢,将会导致Redis主线程阻塞影响效率。

主从复制
一主一从结构
当应用写命令并发量较高且需要持久化时,可以只在从节点开启AOF,这样既保证了数据安全性同时也避免了持久化对主节点的性能干扰。

一主多从结构
一主多从使得应用端可以利用多个从节点实现读写分离。对于读占比较大的场景,可以把读命令发送到从节点来分担压力。一些慢查询操作也可以在从节点进行。

redis主库报slave是什么情况 redis save m n_后端_09


数据同步分为全量复制和部分复制。

全量复制:一般用于初次复制的场景。

部分复制:用于处理在主从复制中因网络闪断等原因造成数据丢失的场景。

主从节点会维护一个复制偏移量的数据,可以判断主从节点数据是否一致。

主从节点建立复制后,他们之间维持着长连接并且彼此发送心跳命令。
主从心跳机制:
1)主从节点彼此都有心跳检测机制。主节点每隔10秒向从节点发送ping命令,判断从节点的存活和连接状态。
2)从节点在主线程中每隔1秒发送replconf命令,给主节点上报自身偏移量,检测数据是否丢失。

读写分离

对于读占比较高的场景,可以通过吧一部分读流量分摊到从节点来减轻主节点的压力。同时注意只对主节点进行写操作。

redis主库报slave是什么情况 redis save m n_持久化_10


读写分离可能会遇到:复制数据过期,读到过期数据,从节点故障等问题。