Redis持久化策略
AOF(Append Only File)
AOF的三种写回策略
AOF把命令写入磁盘的时机
AOF 机制给我们提供了三个选择,也就是 AOF 配置项 appendfsync 的三个可选值。
-
Always:同步回写:每个命令执行完,立马同步的将日志写回磁盘
-
Everysec,每秒写回,每一个写命令,先写入日志到AOF文件的内存缓冲区,每间隔1秒写入一次
-
No,每个命令执行完,先把日志写入到AOF文件的内存缓冲区,由操作系统控制写入. to do 操作系统是如何控制的?
配置项 | 写回时机 | 优点 | 缺点 |
---|---|---|---|
Always | 同步写回 | 可靠,最多丢失一条数据 | 每个写命令都要落盘,性能影响大 |
Everysec | 每秒写回 | 性能适中 | 宕机丢失一秒内的数据 |
No | 操作系统控制写回 | 性能最高 | 宕机可能会丢失大量数据 |
AOF日志重写机制
减小AOF日志文件的大小,如三个命令 set key 1 ;set key 2 ;set key 3 ;只需要保留set key 3 即可
AOF重写触发机制
-
手动执行bgrewriteaof命令。
-
Redis自动触发重写,触发规则
当aof-current-size>=auto-aof-rewrite-min-size且(aof-current-size-aof-base-size)/aof-base-size>=auto-aof-rewrite-percentage时,就会触发AOF重写。
auto-aof-rewrite-min-size:表示AOF重写时的最小文件大小。 :上次重写后的文件大小 auto-aof-rewrite-percentage:表示当前文件大小(aof-current-size)和上次重写后文件大小(aof-base-size)的比值
AOP日志重写的实现流程
-
fork 出一个子进程(bgrewriteaof)进行重写,这样就不会影响主进程,
-
fork使用写时复制(Copy On Write)
-
-
创建一份新的AOF日志文件,使用子进程把新的AOF日志进行重写
-
使用新的AOF日志文件是因为
-
重写失败不影响旧的AOF日志文件
-
多个进程对一个文件操作会出现竞争问题.
-
-
-
同时redis的每次新的操作都会,都会给到新的AOF日志的缓冲中,保证重写的日志不会丢失最新的操作
-
重写成功后使用新的AOF文件代替旧的
AOF日志重写解决的问题
AOF日志文件太大会出现性能问题
-
文件系统本身对文件大小有限制,无法保存过大的文件;
-
如果文件太大,之后再往里面追加命令记录的话,效率也会变低;
-
如果发生宕机,AOF 中记录的命令要一个个被重新执行,用于故障恢复,如果日志文件太大,整个恢复过程就会非常缓慢,这就会影响到 Redis 的正常使用。
RDB快照
快照文件就称为 RDB 文件,RDB 是 Redis DataBase
RDB快照触发机制
-
save命令,其会堵塞主线程直到RDB快照生成完成,故一般很少使用。
-
bgsave命令,同aof重写类似,通过fork子进程来完成,fork子进程的过程往往很快,堵塞的时间比较短
-
Redis自动触发,其主要通过如下的三种方式触发:
-
save m n配置,表示m秒内有n次修改操作,自动触发
-
主从全量复制
-
执行shutdown命令关闭redis,如果没有开启aof日志,则触发。
-
全量快照bgsave
-
fork 一个bgsave的子进程
-
fork使用写时复制(Copy-On_Write ,COW),主进程中内存的数据发生了修改,子进程就会copy一份副本数据,这样主进程的写入和bgsave子进程快照就不会相互影响
-
-
bgsave子进程读取主进程的内存数据,并把它们写入 RDB 文件。
-
快照时可以进行修改,保存的RDB文件还是开始进行快照时的数据
增量快照
做了一次全量快照后,后续的快照只对修改的数据进行快照记录,这样可以避免每次全量快照的开销。
第一次做完全量快照后,T1 和 T2 时刻如果再做快照,我们只需要将被修改的数据写入快照文件就行。但是,这么做的前提是,我们需要记住哪些数据被修改了。你可不要小瞧这个“记住”功能,它需要我们使用额外的元数据信息去记录哪些数据被修改了,这会带来额外的空间开销问题。如下图所示:
如果我们对每一个键值对的修改,都做个记录,那么,如果有 1 万个被修改的键值对,我们就需要有 1 万条额外的记录。而且,有的时候,键值对非常小,比如只有 32 字节,而记录它被修改的元数据信息,可能就需要 8 字节,这样的画,为了“记住”修改,引入的额外空间开销比较大。这对于内存资源宝贵的 Redis 来说,有些得不偿失。
RDB快照+AOF混合持久化
混合持久化从Redis4.0开始,内存快照以一定的频率执行,在两次快照之间,使用 AOF 日志记录这期间的所有命令操作。
配置
开启混合持久化
# aof-use-rdb-preamble yes
混合持久化流程
-
每隔一段时间进行全量快照,快照完成后清空AOF日志文件
-
每个操作通过AOF日志进行记录
持久化方式对比
对比项 | RDB | AOF | AOF+RDB混合 |
---|---|---|---|
占用空间 | 小(数据压缩) | 大(指令级未进行压缩) | 略大于RDB |
存储一次速度 | 慢 | 快 | |
恢复速度 | 快 | 慢 | 略快与AOF |
数据安全性 | 丢数据 | 根据策略决定 | 根据使用的AOF策略决定 |
开启状态 | 默认开启 | 默认关闭 | 默认关闭 |
数据不能丢失时,内存快照和 AOF 的混合使用是一个很好的选择;
如果允许分钟级别的数据丢失,可以只使用 RDB;
如果只用 AOF,优先使用 everysec 的配置选项,因为它在可靠性和性能之间取了一个平衡。