Redis 的持久化机制有两种,第一种是快照,第二种是 AOF 日志。快照是一次全量备份,AOF 日志是连续的增量备份。快照是内存数据的二进制序列化形式,在存储上非常紧凑,而 AOF 日志记录的是内存数据修改的指令记录文本。AOF 日志在长期的运行过程中会变得无比庞大,数据库重启时需要加载 AOF 日志进行指令重放,这个时间就会无比漫长,所以需要定期进行 AOF 重写,给 AOF 日志进行瘦身。

Redis 持久化方式

  1. 快照(snapshotting,RDB)一般用于全量同步

  2. 只追加文件(append-only file, AOF)一般用于增量同步

  3. RDB 和 AOF 的混合持久化(Redis 4.0 新增)

RDB 持久化

通过创建 SnapShotting 快照来获取内存里面的某个时间点上的副本,利用快照可以进行方便的进行主从复制。

默认持久化方式是 RDB,默认文件 dump.rdb。在Redis服务器启动时,会重新加载dump.rdb文件的数据到内存当中恢复数据。

rdb文件生成流程:

  1. 生成临时rdb文件,并写入数据。

  2. 完成数据写入,用临时文代替代正式rdb文件。

  3. 删除原来的db文件。

RDB 持久化方式

  1. save 命令

save 命令是同步保存,会阻塞主进程。

当客户端向服务器发送save命令请求进行持久化时,服务器会阻塞save命令之后的其他客户端的请求,直到数据同步完成。

  1. bgsave 命令

bgsave 利用 Fork 操作,得到子进程,子进程执行,不阻塞主进程,默认用的 bgsave。

将数据保存到rdb文件之后,子进程会退出。

forks子进程是同步的,所以forks子进程时,一样不能接收其他请求。

执行流程:

  1. 检查子进程(检查是否存在 AOF/RDB 的子进程正在进行),如果有返回错误

  2. 触发持久化,调用 rdbsaveBackGroud

  3. 开始 fork,子进程执行 rdb 操作,同时主进程响应其他操作。

  4. RDB 完成后,替换原来的旧 RDB 文件,子进程退出。

  1. 自动触发

Redis配置文件中的save指定到达触发RDB持久化的条件,比如【多少秒内至少达到多少写操作】就开启RDB数据同步

配置文件redis.conf选项示例:

1
2
3
4
5
6
# 900s内至少达到一条写命令
save 900 1
# 300s内至少达至10条写命令
save 300 10
# 60s内至少达到10000条写命令
save 60 10000

AOF 持久化

Redis6.0 版本以前,AOF 持久化没有被默认开启,6.0 以后默认开启。

开启 AOF 持久化后,每次修改 Redis 中的数据,就会将该次命令写入 AOF 缓冲区(Server.aof_buf),然后再写入到 AOF 文件中(此时还在系统内核缓存区未同步到磁盘),最后根据持久化方式(fsync策略)的配置,决定了刷盘的时机。

默认文件名:appendonly.aof。

配置文件redis.conf开启AOF机制:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# 开启aof机制
appendonly yes

# aof文件名
appendfilename "appendonly.aof"

# 写入策略,always表示每个写操作都保存到aof文件中,也可以是everysec或no
appendfsync always

# 默认不重写aof文件
no-appendfsync-on-rewrite no

# 保存目录
dir ~/redis/

AOF 持久化流程

  1. append:写命令追加到 AOF 缓冲区。

  2. write(系统调用):AOF 缓冲区写入 AOF 文件,此时数据到达系统内核缓冲区(非磁盘)

  3. 根据刷盘策略(fsync策略)进行同步机制,此时会阻塞直到写入磁盘完成。

  4. 文件重写机制,AOF 文件变大,定期会对 AOF 做重写,一个参数是超过 X MB,一个参数是百分比(相对于上次重写文件大小)。

  5. 重启加载,检验和机制 (CRC64循环冗余校验)

刷盘策略

  1. always,每次 write 系统调用后,立刻进行同步机制,性能低,安全高

  2. everysec(默认写入策略):调用 write 函数后返回,后台线程每秒钟调用 fsync 函数同步 AOF。因此,最多可能会丢失1s的数据。

  3. no:由操作系统决定同步时机,一般 Linux 为 30 秒。写入更快,但不安全。

RDB 和 AOF 优缺点对比

RDB 优点

  1. 存储二进制压缩数据,文件小,适合数据备份灾难恢复。

  2. RDB 恢复数据,直接解析即可还原数据,速度快,适用大数据量和数据备份。

RDB 缺点

  1. save命令会造成阻塞。

  2. 如果服务器宕机的话,采用RDB的方式会造成某个时段内数据的丢失,比如我们设置10分钟同步一次或5分钟达到1000次写入就同步一次,那么如果还没达到触发条件服务器就死机了,那么这个时间段的数据会丢失。

  3. bgsave 对机器的 CPU 和内存产生影响。使用bgsave命令在forks子进程时,如果数据量太大,forks的过程也会发生阻塞,另外,forks子进程会耗费内存。

  4. RDB 新老版本的兼容性差。

  5. 可读性差,二进制压缩数据。

AOF 优点

  1. AOF只是追加日志文件,因此对服务器性能影响较小,速度比RDB要快,消耗的内存较少。

  2. 命令比较轻量级,丢失数据少

  3. 可读性强,存放的是写命令,可以在没有 AOF 刷盘时,取消某些操作。

AOF 缺点

  1. 大数据量时,恢复比较慢

  2. AOF方式生成的日志文件太大,即使通过AFO重写,文件体积仍然很大。

  3. AOF 重写期间会使用大量内存,可能会有安全问题,需要人工控制参数和具体的流程。

方式 RDB AOF
启动优化级
体积
恢复速度
数据安全性 会丢数据 由策略决定
轻重

当RDB与AOF两种方式都开启时,Redis会优先使用AOF日志来恢复数据,因为AOF保存的文件比RDB文件更完整。

参考