Redis宕机数据会丢失么?
作者:程序员马丁
在线博客:https://open8gu.com
大话面试,技术同学面试必备的八股文小册,以精彩回答应对深度问题,助力你在面试中拿个offer。
回答话术
先说结论,如果我们没开启任何持久化机制,那么会丢失全部数据,否则只会丢失部分数据,丢失数据的多少取决于持久化配置。Redis 提供了两套持久化机制,RDB 快照和 AOF 日志文件追加。
RDB 它会根据情况定期的 Fork 出一个子进程,生成当前数据库的全量快照。对于 RDB 快照,假如我们在 RDB 快照生成后宕机,那么会丢失快照生成期间全部增量数据,如果在连快照都没成功生成,那么就会丢掉全部数据。
另一个是 AOF,它通过向 AOF 日志文件追加每一条执行过的指令实现。而当我们仅开启了 AOF 时,丢失数据的多少取决于我们设置的刷盘策略:当设置为每条指令执行后都刷盘 Always
,我们最多丢失一条指令;当设置为每秒刷一次盘的 Eversec
时,最多丢失一秒内的数据;当设置为非主动刷盘的 No
时,则可能丢失上次刷盘后到现在的全部数据。
考虑到两种模式各有优缺点,没有一个适中的解决方案,为此,Redis 在 4.0 以后允许通过 aof‐use‐rdb‐preamble
配置开启混合持久化。
在开启混合持久化模式时,AOF 重写过程中,Redis 会将持久化数据以 RDB 格式写入 AOF 文件的开头,随后将后续的数据以 AOF 格式追加到文件末尾。恢复数据时,Redis 首先加载 RDB 数据,然后加载 AOF 增量数据。
问题详解
1. RDB
RDB 是 Redis 提供的持久化机制之一,它通过将内存中的数据保存到磁盘中的二进制文件来实现。
我们可以通过 SAVE
或 BGSAVE
指令主动触发快照的生成,也可以通过配置文件中的 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