AOF日志:宕机了,Redis如何避免数据丢失?

Redis持久化机制

  • AOF append on file
  • RDB 快照

AOF实现原理

  • 写后日志
  • 先写内存数据,再记录日志
  • 命令执行后才记录日志,不会阻塞当前的写操作。

记录内容

  • AOF 里记录的是 Redis 收到的每一条命令,这些命令是以文本形式保存的。
  • 以 “set testkey testvalue”命令后记录的日志为例,“*3”表示当前命令有三个部分,每部分都是由“$+数字”开头,后面紧跟着具体的命令、键或值。这里,“数字”表示这部分中的命令、键或值一共有多少字节。例如,“$3 set”表示这部分有 3 个字节,也就是“set”命令
    在这里插入图片描述

AOF缺陷

  • AOF 虽然避免了对当前命令的阻塞,但可能会给下一个操作带来阻塞风险
  • AOF 日志也是在主线程中执行的,如果在把日志文件写入磁盘时,磁盘写压力大,就会导致写盘很慢,进而导致后续的操作也无法执行

AOF写回策略

  • Always:同步写回,每个写命令执行完,马上日志同步的写到磁盘
  • Everysec:每秒写回,每个写命令执行完,只是先把日志写到 AOF 文件的内存缓冲区,每隔一秒把缓冲区中的内容写入磁盘
  • No:操作系统控制的写回,每个写命令执行完,只是先把日志写到 AOF 文件的内存缓冲区,由操作系统决定何时将缓冲区内容写回磁盘。

AOF文件过大问题

  • 文件系统本身对文件大小有限制,无法保存过大的文件
  • 文件太大,之后再往里面追加命令记录的话,效率也会变低
  • 发生宕机,AOF 中记录的命令要一个个被重新执行,用于故障恢复,日志文件太大,整个恢复过程非常缓慢,影响Redis 的正常使用

AOF重写机制

  • 读取数据库所有键值对,然后完成键值设定语句的写入,将记录重写到aof文件
  • 旧日志文件中的多条命令,在重写后的新日志中变成了一条命令

AOF重写过程

  • 重写过程是由后台子进程 bgrewriteaof 来完成的,这也是为了避免阻塞主线程,导致数据库性能下降
  • 每次执行重写时,主线程 fork 出后台的 bgrewriteaof 子进程。此时,fork 会把主线程的页表拷贝一份给 bgrewriteaof 子进程,形成虚实映射关系,这样子进程也就能访问父进程的内存数据了。然后bgrewriteaof 子进程就可以在不影响主线程的情况下,逐一把内存的数据写成操作,记入重写日志
  • 主线程如果有写操作,会先操作记录到缓冲区
  • 子进程完成记录重写操作后,重写日志记录的新操作也会合入到新的AOF文件

AOF重写过程风险

  • Redis主进程fork创建bgrewriteaof子进程时,内核会把主进程pcb拷贝给子进程,创建和拷贝的过程由内核执行,会阻塞主线程。拷贝时,redis实例越大,主线程的页表就越大,fork阻塞的时间就会越长
  • bgrewriteaof子进程和主线程共享内存,主线程如果写大key会去申请新内存,操作系统会为其分配大空间,有查找和锁的开销,导致阻塞

AOF重写为什么不共享现有AOF文件

  • 主进程写,子进程也要写,就会产生锁,对主线程造成影响
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值