Redis提供了多种持久化选择

  • RDB:RDB是以指定间隔时间将Redis进行快照
  • AOF:AOF记录每一次写操作,当Redis服务重启后,会通过日志重新恢复数据集。命令被以一种Redis规定的格式记录。
  • No persistence:可以完全禁止持久化
  • RDB+AOF:可以复合使用,当有AOF时,Redis会优先使用AOF

    优缺点分析

    |
    | RDB | AOF | | —- | —- | —- | | 优点 |
    1. RDB持久化方式是一个紧凑方式,方便传输
    2. 主线程不参与持久化,也就是不参与I/O操作
    3. 比AOF更快的恢复时间
    |
    1. AOF更可靠,默认1秒持久化一次,可以设置具体策略
    2. 有工具修复AOF
    3. AOF记录的东西可以看得懂
    | | 缺点 |
    1. RDB可能会丢失一些数据
    2. 数据集很大时fork()会花很多时间
    |
    1. 比RDB的文件大(相同数据量)
    2. AOF可能会损失Redis一些性能
    3. 有个别bug
    |

通常我们会将RDB和AOF都进行开启,如果你能忍受几分钟的数据丢失情况,可以单独使用RDB。
很多人单独使用AOF,但是这不被推荐。

RDB官方介绍

默认RDB是开启的,默认记录一个二进制文件dump.rdb。触发刷盘的行为有以下三个:

  • 执行save命令
  • 执行bgsave命令
  • 配置文件中指定save 规则

当需要进行刷盘时,Redis会执行的动作:

  • Redis会开启子进程
  • 子进程将数据先刷到一个临时的RDB文件中
  • 当子进程将数据同步到临时RDB后,替换旧的

    尚硅谷说: save:会阻塞,就是说执行完save后,才能执行其他命令 bgsave:则会fork子进程,不阻塞

RDB操作

  1. 生成RDB文件
    1. 手动save or bgsave
    2. 触发配置文件中的条件
  2. 使用RDB文件
    1. redis重启后自动使用RDB,前提AOF未开启

RDB的配置项梳理

  1. save 配置
    1. save N秒之后 至少N个key发生变化
    2. save “” 禁用save或者 注释所有save配置
  2. stop-writes-on-bgsave-error
    1. 若刷盘错误,直接禁止写操作
  3. rdbcompression
    1. 是否压缩rdb
  4. rdbchecksum
    1. 校验rdb文件

AOF

AOF持久化大体流程

  1. 客户端将写命令先追加到AOF缓冲区(内存中)
  2. 根据配置的AOF持久化策略,将AOF缓冲区刷到磁盘上
  3. 若AOF文件过大的话会依据配置的重写,缩减AOF大小。也可以手动重写

    AOF配置

  4. appendfsync 追加存盘 策略

    1. always:每次写操作都会直接入盘
    2. everysec:每秒同步一次
    3. no:redis不主动同步而是将同步时机交给操作系统
  5. no-appendfsync-on-rewrite
    1. 当重写操作进行时,是否进行AOF的刷盘操作。
    2. yes:客户端依旧可以执行写命令,但是这段写命令暂时不会刷盘
    3. no:就是可以继续向旧AOF中写,客户端写命令可能会阻塞(注意是可能会阻塞,可能会阻塞)
  6. auto-aof-rewrite-percentage
    1. 当前文件时上次rewrite后大小的 N倍后执行 rewrite
  7. auto-aof-rewrite-min-size

    1. 可以进行rewrite的最小文件大小,默认64MB

      AOF的重写流程

  8. 判断是否有bgsave或者bgrewriteaof在运行,有则等待

  9. fork出一个子进程,并开始同步一个新的aof
  10. 此时客户端的写请求同时写入 aof_buf 和 aof_rewrite_buf
  11. aof_buf用于旧的aof文件同步,aof_rewrite_buf用于将新的命令同步到rewrite的新的aof中
  12. fork的子进程完成新aof 对 旧aof文件的重写和 aof_rewrite_buf中新命令,两部分的重写后。通知主进程。
  13. 主进程将新AOF替换旧AOF

image.png
其中aof_buf到旧的AOF文件中的这一步,看如何设了(no-appendfsync-on-rewrite)。若是yes的话就不会进行旧AOF的更新。若是no的话,会进行旧AOF的更新操作。

AOF修复工具

Redis为我们提供了修复aof文件的工具,比如我们使用flushall命令清空Redis时,我们想恢复Redis数据。
可以打开AOF将flushall删除,之后,通过redis-check-aof工具修复,重启Redis后即可。

尚硅谷优化建议

  • rdb配置只保留 save 900 1
  • 尽量减少rewrite的频率,rewrite的基准设置大一点 5GB

    特别强调

    AOF的Rewrite的客户端阻塞的点是:
  1. 当新的AOF生成完成后。
  2. 在将新AOF替换旧AOF动作完成前
  3. 所有的客户端写操作时不被执行的。所以可能阻塞

参考文章