持久化

持久化(Persistence),即把内存中的数据保存到磁盘中。

持久化的实现方式

快照式

在某个时刻把所有数据进行完整备份。

例:MySQL 的 Dump 方式、Redis 的 RDB 方式。

日志式

把用户执行的所有写指令(增删改)备份到文件中,还原数据时只需要把备份的所有指令重新执行一遍即可。

例:MySQL 的 Binlog、Redis 的 AOF、Hbase 的 HLog。

AOF 简介

在文章《Redis持久化 - RDB》中提到过,使用 RDB 做持久化,如果 Redis 意外宕机(例如电源中断),可能会丢失上一次备份到宕机前这段时间的数据。

为了避免上述问题,可以使用另一种持久化实现方式:AOF 持久化。

配置 AOF 持久化之后,每当 Redis 执行一个改变数据集的命令, 这个命令就会被追加到 AOF 文件的末尾。当 Redis 重新启时,程序就可以通过重新执行 AOF 文件中的命令来达到重建数据集的目的。

AOF持久化的三种策略

always

每次有新命令执行就刷新缓冲区,将命令追加到 AOF 文件,速度相对其他策略慢、IO开销大,但是安全性非常高。

everysec(默认&推荐)

每秒刷新一次缓冲区,将命令追加到 AOF 文件,速度足够快并且在故障时只会丢失 1 秒钟的数据。

no

不刷新缓冲区内容,由操作系统来决定什么时候同步数据。最快但也最不安全。

AOF 重写

因为 AOF 的运作方式是不断地将命令追加到文件的末尾, 所以随着写入命令的不断增加, AOF 文件的体积也会变得越来越大。但是很多命令的执行实际上会覆盖原有命令的结果(如自增 INCR),导致保留原有命令是多余的。

为此,Redis 可以在不打断服务客户端的情况下, 对 AOF 文件进行重建(rebuild)。手动执行 bgrewriteaof 命令, Redis 将生成一个新的 AOF 文件, 这个文件包含重建当前数据集所需的最少命令。

bgrewriteaof 命令是异步执行的,即使 bgrewriteaof 执行失败,也不会有任何数据丢失,因为旧的AOF文件在 bgrewriteaof 成功之前不会被修改。

Redis 2.4 开始可以通过配置自动触发 AOF 重写。

AOF重写的作用

  • 可以减少磁盘占用量
  • 可以更快地数据恢复

AOF 配置

# 开启AOF持久化
appendonly yes

# AOF持久化文件名
appendfilename appendonly-<port>.aof

# 每秒把缓冲区的数据同步到磁盘
appendfsync everysec

# 数据持久化文件存储目录
dir /var/lib/redis

# 是否在执行重写时不同步数据到AOF文件
# 这里的 yes,就是执行重写时不同步数据到AOF文件
no-appendfsync-on-rewrite yes

# 触发AOF文件执行重写的最小尺寸
auto-aof-rewrite-min-size 64mb

# 触发AOF文件执行重写的文件体积增长率
auto-aof-rewrite-percentage 100

自动触发AOF重写,需要同时满足下面两个条件:

  • aof_current_size > auto-aof-rewrite-min-size
  • (aof_current_size - aof_base_size) * 100 / aof_base_size > auto-aof-rewrite-percentage
aof_current_size:AOF文件当前尺寸(字节)
aof_base_size:AOF文件上次启动和重写时的尺寸(字节)

AOF 重写流程

AOF重写的流程*

AOF的优点

  1. 根据不同的fsync策略,可以兼顾性能和数据安全性。
  2. AOF 文件是一个只进行追加的日志文件,即使由于某些原因(磁盘空间已满,写的过程中宕机等)未执行完整的写入命令,也可以使用 redis-check-aof 工具修复这些问题。
  3. Redis 可以在 AOF 文件体积变得过大时,自动地在后台执行 AOF 重写,重写后的新 AOF 文件包含了恢复当前数据集所需的最小命令集合。Redis 在创建新 AOF 文件的过程中,会继续将命令追加到原有的 AOF 文件里面,即使重写过程中发生宕机,原有的 AOF 文件也不会丢失。一旦新 AOF 文件创建完毕,Redis 就会从旧 AOF 文件切换到新 AOF 文件,并开始对新 AOF 文件进行追加操作。
  4. AOF 文件有序地保存了对数据库执行的所有写操作,这些写操作以 Redis 命令的格式保存, 因此可以很轻松地对 AOF 文件的内容进行分析。 例如,如果不小心执行了 FLUSHALL 命令,只要 AOF 文件未被重写,那么只要停止服务器,移除 AOF 文件末尾的 FLUSHALL 命令,并重启 Redis ,就可以将数据集恢复到 FLUSHALL 执行之前的状态。

AOF的缺点

  1. 对相同的数据集来说,AOF 文件的体积通常要大于 RDB 文件的体积。
  2. 根据不同的 fsync 策略,AOF 的速度可能会慢于 RDB 。

小伍
139 声望4 粉丝