Skip to main content

Redis宕机数据会丢失么?

作者:程序员马丁

在线博客:https://open8gu.com

note

大话面试,技术同学面试必备的八股文小册,以精彩回答应对深度问题,助力你在面试中拿个offer。

回答话术

先说结论,如果我们没开启任何持久化机制,那么会丢失全部数据,否则只会丢失部分数据,丢失数据的多少取决于持久化配置。Redis 提供了两套持久化机制,RDB 快照和 AOF 日志文件追加。

RDB 它会根据情况定期的 Fork 出一个子进程,生成当前数据库的全量快照。对于 RDB 快照,假如我们在 RDB 快照生成后宕机,那么会丢失快照生成期间全部增量数据,如果在连快照都没成功生成,那么就会丢掉全部数据

image.png

另一个是 AOF,它通过向 AOF 日志文件追加每一条执行过的指令实现。而当我们仅开启了 AOF 时,丢失数据的多少取决于我们设置的刷盘策略:当设置为每条指令执行后都刷盘 Always,我们最多丢失一条指令;当设置为每秒刷一次盘的 Eversec 时,最多丢失一秒内的数据;当设置为非主动刷盘的 No 时,则可能丢失上次刷盘后到现在的全部数据。

image.png

考虑到两种模式各有优缺点,没有一个适中的解决方案,为此,Redis 在 4.0 以后允许通过 aof‐use‐rdb‐preamble 配置开启混合持久化。

在开启混合持久化模式时,AOF 重写过程中,Redis 会将持久化数据以 RDB 格式写入 AOF 文件的开头,随后将后续的数据以 AOF 格式追加到文件末尾。恢复数据时,Redis 首先加载 RDB 数据,然后加载 AOF 增量数据。

image.png

问题详解

1. RDB

RDB 是 Redis 提供的持久化机制之一,它通过将内存中的数据保存到磁盘中的二进制文件来实现。

我们可以通过 SAVEBGSAVE 指令主动触发快照的生成,也可以通过配置文件中的 save 配置快照的自动生成条件。

在现实中出于性能考虑,我们不可能非常频繁的保存快照,因此要防止数据丢失,最终还是主要依靠 AOF 实现。

关于 RDB,具体可参照:✅ Redis 的 RDB 是怎么实现的?

2. AOF

AOF 是 Redis 提供的另一套持久化机制。当每个写命令被执行完毕后,它们会被追加写入 AOF 日志文件的末尾。当 Redis 宕机以后,就可以通过 AOF 日志重放这些命令来恢复数据。

不过,每次命令执行后,数据会先写入 AOF 缓存,然后再写入操作系统缓存,最后才会根据刷盘策略真正的写入磁盘。因此刷盘策略真正决定了 Redis 宕机时会丢失多少数据:

  • Always:每执行一条指令就刷一次盘,宕机时最多丢失一条指令。
  • Eversec:每秒刷一次盘,宕机时最多丢失一秒内的数据。
  • No:不主动刷盘,由操作系统自己完成,宕机时最多丢失从上一次刷盘到宕机时的全部数据。

关于 AOF,具体可参照:✅ Redis 的 AOF 是怎么实现的?

3. 混合持久化

混合持久化是在 AOF 基础上的优化措施,严格来说还是 AOF,Redis 官方文档里面持久化方式其实还是只有 AOF 和 RDB 两种。

由于 RDB 快照模式会丢失增量数据,AOF 文件较大会影响 Redis 数据恢复的时间,因此 Redis 在 4.0 以后允许通过 aof‐use‐rdb‐preamble 配置开启混合持久化。

当 AOF 重写时,它将会先生成当前时间的 RDB 快照,然后将其写入新的 AOF 文件头部位置,接着再把增量数据追加到这个新 AOF 文件中。如此一来,当 Redis 通过 AOF 文件恢复数据时,将会先加载 RDB,然后再重放后半部分的增量数据。这样就可以大幅度提高数据恢复的速度。

3.1. 查看混合持久化是否打开

根据 Redis 版本的不同,有些默认是开启的,有些默认是关闭状态,我们可以通过两种方式开启混合持久化配置。

127.0.0.1:6379> config get aof-use-rdb-preamble
1) "aof-use-rdb-preamble"
2) "no"

3.2. 通过命令行开启

可以通过 config set aof-use-rdb-preamble yes 命令行的方式开启混合持久化配置,注意开启后再查一次配置。

127.0.0.1:6379> config get aof-use-rdb-preamble
1) "aof-use-rdb-preamble"
2) "no"
127.0.0.1:6379> config set aof-use-rdb-preamble yes
OK
127.0.0.1:6379> config get aof-use-rdb-preamble
1) "aof-use-rdb-preamble"
2) "yes"

3.3. 文件配置开启

我们可以在 Redis 的配置文件 redis.conf 中开启,开启后确保万无一失需要再通过 config get aof-use-rdb-preamble 查询下。

# Redis can create append-only base files in either RDB or AOF formats. Using
# the RDB format is always faster and more efficient, and disabling it is only
# supported for backward compatibility purposes.
aof-use-rdb-preamble yes