RDB和AOF持久化
RDB是redis的默认选择,
启动redis --> 定时任务(默认60s,一万条数据等作为阈值,触发线程)(把内存数据写入磁盘)-->产生持久化文件 -->关机(内存数据丢失)-->开机会读取磁盘回到内存。 大概流程
RDB持久化原理:
redis会单独创建一个fork子进程,它与当前进程一模一样(所有数据,变量,环境变量,程序计数器等)都和原进程一样,会先把数据写到临时文件(dump.rdb),待持久化行为结束,再将新的临时文件替换上次的旧持久化文件,整个过程,主进程不进行任何IO操作,保证性能。
什么时候触发RDB持久化:
1 ,手动shutdown时,如果没有开启AOF,会触发RDB持久化 。(触发配置文件中默认配置的快照配置) (意外断电等宕机则不会。)
2, 执行save命令或者bgsave ,save只管保存,其他不管,全部阻塞,使用主进程进行持久化。
bgsave:redis会在后台异步操作快照,同时可以相应客户端的请求。
3. 执行flushall命令 ,会清空内存里全部的数据,然后触发写快照机制。
缺点:
还没有来得及触发RDB持久化,redis出现了意外宕机,会导致数据丢失。
AOF持久化:
AOF持久化就是为了解决RDB数据丢失的情况诞生的,
RDB -->基于内存数据,产生持久化
AOF -->基于命令字符串 (记录写操作,不记录读操作)
开启AOF配置,就会创建一个缓冲区,主进程将操作指令存储进缓冲区,然后有专门的线程去写入aof持久化文件。缓冲区写入磁盘有三种方式,根据配置来的
-->1 .等操作系统自行判断写入磁盘时机(效率快,持久化没保证)
-->2. 同步持久化,每次发生缓冲区数据变更,立刻刷盘(效率不行,但是安全有保障)
-->3. 每秒同步一次,效率和安全都还可以,但是宕机时会丢失一秒数据。(默认的就是这个方式)
感觉这个和mysql的redo.log刷磁盘的方式超级像。
AOF的瘦身逻辑:
比如 先有指令 set k1 v1 ,再有指令del k1 ,那么相互抵消。会根据内存数据生成新的AOF(重写AOF文件会folk子进程去完成,不会用主进程)。新的AOF文件会替换旧的AOF文件,,,folk子进程就类似复制一个redis,资源开销非常大。
什么时候会触发重写?
auto-aof-rewrite-min-size参数 :当AOF文件大小大于配置文件中配置的大小时,会触发,默认64M,生产环境起码给很多个G。
auto-aof-rewrite-percentage参数:当AOF文件大小的增长率大于这个配置时,自动开启重写。
Redis4.0版本之后,支持两者混合模式。为了优化AOF的重写, 重写之前,全部用RDB的方式保存数据,重写后用AOF保存。 主要是为了节约AOF文件的大小。
总结 :
RDB更适合数据恢复 (因为是基于内存数据生成的快照,AOF回滚数据还需要逐一执行指令),缺点 :容易丢数据
AOF更适合保证数据安全。 保证安全,但是数据恢复慢。
AOF和RDB文件如果出现损坏,redis里也是有内置恢复工具的。