Redis持久化

  • AOF日志

      • AOF日志记录的是redis收到的操作命令,以文本形式保存,由主线程写回
      • AOF日志采用先执⾏命令再记⽇志的方式(为避免额外的检查开销,不阻塞当前写操作)
      • 用AOF方法进行故障恢复时,需要逐一把操作日志都执行一遍
      • Always,同步写回:每次执行写操作后立马同步将日志写回磁盘
      • Everysec,每秒写回:先把日志写到AOF文件的内存缓冲区,每隔一秒将缓冲区的内容写回磁盘
      • No,操作系统控制写回:先把日志写到AOF文件的内存缓冲区,有操作系统决定写回时机
      • 写回方式 写回时机 优点 缺点
        Always 同步写回 可靠度高,数据基本不会丢失 每次写操作都要落盘,性能影响较大
        Everysec 每秒写回 性能适中 宕机时丢失1s内的数据
        No 系统控制写回 性能好 宕机会丢失较多数据
      • 主线程fork重写子进程,子进程将新的内容写到临时文件中
      • 重写并不阻塞主线程,主线程对于新的写入操作,一边将他们累积到内存缓冲中,一边追加到现有的AOF文件中(避免重写时宕机引起数据丢失)
      • 子进程完成重写后发送信号给父进程,父进程接收信号后将内存缓存中的所有内容追加到新的AOF文件中(阻塞)
      • 最后redis原子地用新文件替换旧文件,之后的命令将直接追加到新的AOF文件末尾

  • 内存快照

      • save:在主线程中执行,会导致阻塞
      • bgsave:创建子线程专门用于写入RDB文件,避免主线程阻塞,是redis默认配置
      • 主线程fork⽣成bgsave⼦进程,两者共享同一物理内存,子线程将redis内存中的数据全量记录到磁盘文件中,该快照文件成为RDB文件
      • 主线程对数据进行写操作时,会将该部分内存复制一份副本(写时复制),主线程可直接修改原来的数据而不用担心子进程的数据污染问题
      • 优:可以快速恢复数据库(避免了AOF需要顺序,逐一执行命令带来的低效性能的问题)
      • 劣:频繁的快照会造成性能的消耗,主要是将全量数据写入磁盘的消耗和主线程进行fork操作的消耗

  • 总结

    • 数据不能丢失时,内存快照和AOF的混合使⽤是⼀个很好的选择
    • 如果允许分钟级别的数据丢失,可以只使⽤RDB
    • 如果只⽤AOF,优先使⽤everysec的配置选项,因为它在可靠性和性能之间取了⼀个平衡