前言

Redis 作为一款内存数据库,被广泛使用于缓存,分布式锁等场景,那么假如断电或者因其他因素导致 Reids 服务宕机,在重启之后数据会丢失吗?

Redis 持久化机制

Redis 虽然是定义为一个内存数据库,但是其也支持数据的持久化,在 Redis 中提供了两种持久化机制:RDB 持久化和 AOF 持久化。

RDB 持久化机制

RDB 全称为:Redis DataBase,是 Redis 当中默认的持久化方案。当触发持久化条件时,Redis 默认会生成一个 dump.rdb 文件,Redis 在重启的时候就会通过解析 dump.rdb 文件进行数据恢复。

RDB 机制触发条件

RDB 持久化机制有两种触发方式:自动触发和手动触发。

自动触发

自动触发方式也可以分为三种:

如果想要知道上一次成功执行 save 或者 bgsave 命令的时间,可以执行 lastsave 命令进行查看,lastsave 命令返回的是一个 unix 时间戳。

RDB 机制相关配置文件

除了上面提到的触发生成 rdb 文件的配置参数,RDB 持久化机制还有如下一些相关命令:

AOF 和 RDB 最大的不同是:AOF 记录的是执行命令(类似于 MySQL 中 binlog 的 statement 格式),而RDB 记录的是数据(类似于 MySQL 中 binlog 的 row 格式)。

需要注意的是:假如同时开启了 RDB 和 AOF 两种机制,那么 Redis 会优先选择 AOF 持久化文件来进行数据恢复。

AOF 机制如何开启

AOF 机制默认是关闭的,可以通过以下配置文件进行修改

appendonly no  //是否开启AOF机制,默认是no表示关闭,修改为yes则表示开启
appendfilename "appendonly.aof"  //AOF文件名

PS:和 RDB 机制一样,其生成文件的路径也是通过 dir 属性进行配置。

AOF 机制数据是否实时写入磁盘

AOF 机制下数据是否实时写入磁盘,这个和 MySQL 的 redo log 机制很类似,也是需要通过参数来进行控制。

AOF 数据何时写入磁盘由参数 appendfsync 来进行控制:

appendfsync 描述 备注
always 写入缓存的同时通知操作系统刷新(fsync)到磁盘(但是也可能会有部分操作系统只是尽快刷盘,而不是实时刷盘) Slow, Safest
everysec 先写入缓存,然后每秒中刷一次盘(默认值),这种模式极端情况可能会丢失 1s 的数据 Compromise
no 只写入缓存,什么时候刷盘由操作系统自己决定 Faster

AOF 文件重写

AOF 机制主要是通过记录执行命令的方式来实现的,那么随着时间的增加,AOF 文件不可避免的会越来越大,而且可能会出现很多冗余命令。比如同一个 key 值执行了 10000 次 set 操作,实际上前面 9999 次对恢复数据来说都是没用的,只需要执行最后一次命令就可以把数据恢复,正是为了避免这种问题,AOF 机制就提供了文件重写功能。

重写原理分析

AOF 重写时 Redis 并不会去分析原有的文件,因为如果原有文件过大,分析也会很耗时,所以 Redis 选择的做法就是重新去 Redis 中读取现有的键值对,然后用一条命令记录键值对的值。

只使用一条命令也有一个前提,那就是一个集合键或者列表键或者哈希键内包含的元素不能超过 64 个,一旦超过 64 个,就会使用多条命令来进行记录。

AOF 重写缓冲区

AOF 重写的时候一般都会有大量的写操作,所以为了不阻塞客户端的命令请求,Redis 会把重写操作放入到子进程中执行,但是放入子进程中执行也会带来一个问题,那就是重写期间如果同时又执行了客户端发过来的命令,又该如何保证数据的一致性?

为了解决数据不一致问题,Redis 中引入了一个 AOF 重写缓冲区。当开始执行 AOF 文件重写之后又接收到客户端的请求命令,不但要将命令写入原本的 AOF 缓冲区(根据上面提到的参数刷盘),还要同时写 入 AOF 重写缓冲区:

AOF重写

一旦子进程完成了 AOF 文件的重写,此时会向父进程发出信号,父进程收到信号之后会进行阻塞(阻塞期间不执行任何命令),并进行以下两项工作:

  1. 将 AOF 重写缓冲区的文件刷新到新的 AOF 文件内。
  2. 将新 AOF 文件进行改名并原子的替换掉旧的 AOF 文件。

完成了上面的两项工作之后,整个 AOF 重写工作完成,父进程开始正常接收命令。

AOF 机制触发条件

AOF 机制的触发条件同样也分为自动触发和手动触发。

注意:bgrewriteaof 命令也不能和上面 RDB 持久化命令 bgsave 同时执行,这么做是为了避免同时创建两个子进程来同时执行大量写磁盘操作,影响到 Redis 的性能。

AOF 机制机制优点

总结

本文主要介绍了 Redis 的两种持久化机制:RDB 和 AOF,并分别介绍了两种持久化机制的原理,通过对两种持久化机制的对比分析了两种持久化机制各自的优点和缺点。