为何须要持久化,以及Redis持久化的RDB方式在这篇文章讲的已经很透彻了,足以吊打面试官了。并且此篇内容须要RDB文章的内容支持,因此建议先看下完全搞懂Redis持久化之RDB原理mysql
它也是Redis持久化的重要手段之一,aof-》Append Only File,只追加文件,也就是每次处理完请求命令后都会将此命令追加到aof文件的末尾。而RDB是压缩成二进制等时机开子进程去干这件事。web
就是每次都在aof文件后面追加命令。他与主进程收到请求、处理请求是串行化的,而非异步并行的。图示以下
因此aof的频率高的话绝逼会对Redis带来性能影响,由于每次都是刷盘操做。跟mysql同样了。Redis每次都是先将命令放到缓冲区,而后根据具体策略(每秒/每条指令/缓冲区满)进行刷盘操做。若是配置的always,那么就是典型阻塞,若是是sec,每秒的话,那么会开一个同步线程去每秒进行刷盘操做,对主线程影响稍小。面试
其实Redis每次在写入AOF缓冲区以前,他都会调用flushAppendOnlyFile(),判断是否须要将AOF缓冲区的内容写入和同步到AOF文件中。这个决策是由配置文件的三个策略来控制的redis
好比我有业务很简单,就来回delete set 同一个key。就这个业务运行了10年,那么aof文件将记录无数个delete k1, set k1 xxx。其实都是重复的,可是我aof每次都追加,文件变成了1T大小。这时候Redis宕机了,要恢复,你想一想1TB大小的aof文件去恢复,累死了。最主要的是1TB大小只记录了两个命令,因此压缩其实就是来处理这件事的。sql
Redis4.0以前和Redis4.0的rewrite(重写)方式不同,Redis4.0以前就是将aof文件中重复的命令给去掉。保留最新的命令。进而减小aof文件大小。好比编程
set k1 123 set k1 345 del k1 set k1 789
通过rewrite后(Redis4.0以前),只会变成以下微信
set k1 789
4.0以前的作法效率非常低下,须要逐条命令对比。4.0开始的rewrite支持混合模式(也是就是rdb和aof一块儿用),直接将rdb持久化的方式来操做将二进制内容覆盖到aof文件中(rdb是二进制,因此很小),而后再有写入的话仍是继续append追加到文件原始命令,等下次文件过大的时候再次rewrite(仍是按照rdb持久化的方式将内容覆盖到aof中)。可是这种模式也是配置的,默认是开,也能够关闭。多线程
经过如下两个配置协做触发app
AOF文件最小重写大小,只有当AOF文件大小大于该值时候才可能重写,4.0默认配置64mb。异步
当前AOF文件大小和最后一次重写后的大小之间的比率等于或者等于指定的增加百分比,如100表明当前AOF文件是上次重写的两倍时候才重写。
前两点也就是说只容许同时fork()一个子进程出来干活。
4.0以前版本的,和4.0以及以后关闭混合模式的状况下。
redis4.0以后才支持,默认开启
混合持久化结合了RDB持久化 和 AOF 持久化的优势,采起了rdb的文件小易于灾难恢复,同时结合AOF,增量的数据以AOF方式保存了,数据更少的丢失。
兼容性差,一旦开启了混合持久化,在4.0以前版本都不识别该aof文件,同时因为前部分是RDB格式,须要专业的工具来阅读,由于是二进制,因此阅读性较差。
须要先掌握完全搞懂Redis持久化之RDB原理和此篇幅的aof
混合持久化也是经过bgrewriteaof完成的,因此基本流程和上述同样。不一样的是当开启混合模式时,fork出的子进程先将共享的内存副本全量以RDB的方式写入aof。这样提升了速度也极大的缩小了aof文件(毕竟都是二进制)。写完仍是通知主进程,而后再将重写缓冲区的内容以AOF方式写入到文件,而后替换旧的aof文件。也就是说这种模式下的aof文件发生rewrite后前半部分是rdb格式(REDIS开头的二进制数据),后半部分是正常的aof追加的命令(重写缓冲区里的)。
会优先看是否存在aof文件,若存在则先按照aof文件恢复,由于aof毕竟比rdb全。若aof不存在,则才会查找rdb是否存在。这是默认的机制。毕竟aof文件也rewrite成rdb二进制格式,文件小,易于回复。因此redis会优先采起aof。
此篇都是重点,废话不多。没啥可总结的。
必定要看完全搞懂Redis持久化之RDB原理会让你收获更多,还有,这只是开始,rdb&aof持久化并没完成。两者对比总结篇以及实战篇在向你我招手。
微信公众号【Java码农社区】