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

674 阅读3分钟

1.AOF日志如何实现

  • 一旦服务器宕机,内存中的数据全部丢失

  • 解决办法

    • 从后端数据库恢复数据

      • 对数据压力巨大(缓存雪崩)
      • 导致请求延时增加
  • redis持久化方案\

    • AOF(Append Only File)日志
    • RDB快照
  • 数据的写前日志(Write Ahead Log, WAL),先写日志,数据库崩溃后可以根据日志进行恢复

    • redo log重做日志,记录修改后的数据(直接保存数据)
  • AOF日志刚好相反,是写后日志,把数据写入内存后才记录日志(因为避免检查开销,redis向AOF写日志时避免指令检查)(命令执行成功后写)(不会阻塞当前操作!!!)

    • 记录的是redis的命令,以文本的形式保存

    • set testkey testvalue

    • *3”表示当前命令有三个部分\

    • 每部分都是由“$+数字”开头,后面紧跟着具体的命令、键或值

  • 潜在的风险

    • 执行完命令后宕机,命令和数据有丢失风险\

      • 如果不能通过数据库恢复,就无法恢复了
    • 执行完命令后,写磁盘导致的阻塞

    • 调优方向:redis同步到磁盘的操作

2.三种写回策略

  • Always,同步写回:每个写命令执行完,立马同步地将日志写回磁盘\

    • 数据基本不丢失
    • 落盘操作影响主线程
  • Everysec,每秒写回:每个写命令执行完,只是先把日志写到 AOF 文件的内存缓冲区,每隔一秒把缓冲区中的内容写入磁盘\

    • 其他两种的折中方案
    • 数据量控制在1s以内
    • 主线程性能和避免数据丢失取了一个折中
  • No,操作系统控制的写回:每个写命令执行完,只是先把日志写到 AOF 文件的内存缓冲区,由操作系统决定何时将缓冲区内容写回磁盘\

    • 落盘时机由操作系统掌控,数据丢失不太清楚

\

3.日志文件太大怎么办

  • 随着AOF文件越来越大,存在AOF的性能问题

    • 文件系统对文件大小的控制,无法保存过大文件
    • 文件太大,之后追加命令效率会变低
    • 文件太大导致回放慢
  • AOF重写机制

    • 根据现状创建一个新的AOF文件
    • 重写机制具有多变一的功能,旧日志的多条记录合并成一条命令
  • 即使重写后的日志也很大,会导致主线程的阻塞吗?

\

4.AOF重写会阻塞吗

  • 重写过程是由后台子进程 bgrewriteaof 来完成的,这也是为了避免阻塞主线程,导致数据库性能下降\

  • 重写的过程总结为“一个拷贝,两处日志”\

  • “一个拷贝”就是指,每次执行重写时,主线程 fork 出后台的 bgrewriteaof 子进程。此时,fork 会把主线程的内存拷贝一份给 bgrewriteaof 子进程,这里面就包含了数据库的最新数据。然后,bgrewriteaof 子进程就可以在不影响主线程的情况下,逐一把拷贝的数据写成操作,记入重写日志。\

\

5.总结

  • 所有的设计都是配套的(写后日志+回放+聚合操作)

  • 它提供了 AOF 日志的三种写回策略,分别是 Always、Everysec 和 No\

  • 为了避免日志文件过大,Redis 还提供了 AOF 重写机制,直接根据数据库里数据的最新状态,生成这些数据的插入命令\

  • 三种写回策略体现了系统设计中的一个重要原则 ,即 trade-off,或者称为“取舍”,指的就是在性能和可靠性保证之间做取舍\

  • Redis 的单线程设计,这些命令操作只能一条一条按顺序执行,这个“重放”的过程就会很慢了