0%

redis备份和持久化

[toc]


redis持久化是做什么的?就是为了做备份, 避免redis重启后要重新从数据库里拿缓存。
redis当前有两种持久化机制: RDB和AOC


RDB(Redis DataBase) redis快照#

Q: RDB有哪两种触发方式?#

A:

  • 手动触发。 调用save或者bgsave命令进行快照和备份。

    也可以配置redis.conf,做一个周期性快照,但本质上是使用上面这2个命令

  • 自动触发。m秒内有n次修改,或者主从复制时会触发。


Q: save命令和bgsave命令有什么区别?#

A:

  • save命令会阻塞当前redis线程,导致缓存暂时不可用(stopwolrd), 只能在开发环境或者测试环境使用。

  • bgsave 会fork创建一个子进程,在子进程中做RDB操作。

    RDB快照存盘完成后,会通知主进程,主进程更新统计信息。


Q: 如果一次执行好几个bgsave命令会怎么样?#

A:
当检测到有子进程时, 后面几个bgsave命令会直接返回,不会做创建。


Q: bgsave的过程中,如果主进程收到新的写数据怎么办?#

A:
主进程会把写数据生成一个副本,交给bgsave子进程, 子进程会把这个修改作为最新修改写入RDB文件。


Q: 这个同步副本给子进程的时候进程崩溃怎么办?导致没有落盘到RDB#

A:
RDB完全写入成功,才算成功。
写一半的RDB文件,被认为无效文件,因此会用上一次的有效RDB文件进行恢复。


Q: 每秒做一次bgsave会有什么问题?如果数据量比较大的话#

A:

  1. 磁盘压力比较大,频繁竞争磁盘通过(注意每次快照的文件都是不同的文件,但磁盘写入器会共用)
  2. 创建fork子线程的操作,本身会阻塞一定的主进程时间。

Q: 如何解决上面的问题, 又能尽可能保证备份的实时可靠性?#

A:
做增量快照(只备份新增的修改),而增量快照的话RDB无法支持。


Q: RDB的优缺点?#

A:
优点:

  • 使用了LZF算法做了压缩,数据量小于内存大小,很适合备份、全量复制。

  • 备份恢复速度比AOF快。

    缺点:

  • 效率不高,如果数据量太大的话。

  • fork子进程操作比较重

  • 文件属于二进制文件,可读性差。

AOF(append only file)持久化方式#

Q: AOF采用 ”先更新内存缓存, 再写备份日志“, 和”mysql日志先行“的思想不同,为什么?#

A:

  • 错误命令得调用redisobject方法的时候才能感知,写日志时不方便做检查。

    如果写了错误命令的日志,再执行命令,就不好恢复了(那mysql为什么没有这个顾虑?)

  • 尽快加速写操作的响应

    风险就是正巧写的时候挂了,那日志也丢了。


Q: AOF记录时的3个步骤是怎样的?#

A:

  1. 命令追加

    把写命令写道aof_buf缓冲区

  2. 文件写入和同步

    什么时候写入文件,有3种策略

  • always:每次写入缓冲区后,都马上写入文件
  • everySec:每秒把缓冲区里的数据写一次到文件(可能丢失1秒)
  • no:由操作系统控制合何时写文件

Q: 随着写入操作越来越多, AOF文件会越来越大,怎么办?#

A:
当大到一定成都时, redis会创建一个新的AOF文件, 对老文件里的命令进行重写,去除一些冗余命令,只保留每个键的最后状态。
重写操作也是fork了一个子线程进行重写


Q: 重写时,由新的数据写入怎么办?#

A:
同步2份写操作, 老AOF文件写一份, 新AOF文件的缓冲区同步一份。

  1. 主线程fork出子进程重写aof日志

  2. 子进程重写日志完成后,主线程追加aof日志缓冲

  3. 替换日志文件

    860816c7e75a0e58e1850249253f77bdd72ff327


Q: 如果重写的时候 redis重启了怎么办?#

A:
没写完的AOF文件默认失效, 使用老的AOF文件。


Q: 主进程如何拷贝数据给子进程?#

A:
使用操作系统的copy on write
子进程时会拷贝父进程的页表,即虚实映射关系(虚拟内存和物理内存的映射索引表),而不会拷贝物理内存
36b01fbc65c4c5b78e1f61f26f11766dc5a56407


一般都采用RDB和AOF混合的方式, 先全量快照, 然后一段时间内增量AOF。


Q: 恢复时, 如果同时有RDB文件和AOF文件,怎么选择?#

A:
优先选择AOF文件,AOF不存在再RDB。
219bd9996098a234c7a2534fa4e5d24c2a0525c2


Q: 那么为什么会优先加载AOF呢?#

A:
因为AOF保存的数据更完整,通过上面的分析我们知道AOF基本上最多损失1s的数据。


Q: 线上高压环境如何进行备份机制的调优,减少阻塞?#

A:

  • 关闭非敏感、重要性数据的备份
  • 通过一些其他补数据机制进行恢复,例如自己写一些缓存重新载入的补数据功能。
  • redis集群实现滚动备份,避免全部同时在备份。
  • redis主从复制时, 让从节点做备份,主节点不做部分。