giftiaのblog

redis数据持久化

· giftia

1. Redis 持久化的目的

Redis 是一款基于内存的键值存储系统,这意味着它的所有数据都存储在 RAM 中,读写速度极快。然而,一旦 Redis 进程因故宕机或服务器重启,内存中的数据就会全部丢失。持久化的目的就是将内存中的数据保存到硬盘上,确保在 Redis 重启后能够恢复到宕机前的状态,从而保障数据的可靠性。

2. RDB (Redis Database) 持久化

RDB 是 Redis 默认的持久化方式,它是一种快照(snapshot)持久化。

核心原理:

  • RDB 会在指定的时间间隔内,将 Redis 在内存中的所有数据以二进制文件的形式写入硬盘。这个文件通常命名为 dump.rdb。整个过程可以理解为对 Redis 内存数据做了一次全量备份。

工作流程:

  • Redis 父进程接收到 BGSAVE 命令(手动执行或配置触发)。
  • 父进程会调用 fork() 创建一个子进程。
  • fork() 之后,父进程继续处理客户端的请求,而子进程则负责将内存中的数据写入临时的 RDB 文件。在 fork() 的瞬间,子进程会和父进程共享内存中的数据,采用了写时复制(Copy-On-Write, COW)机制。这意味着当父进程需要修改某个数据时,操作系统会先将这部分数据复制一份,然后父进程在新复制的数据上进行修改,而子进程继续使用旧的数据进行持久化。
  • RDB 文件写入完成后,子进程会用新的 RDB 文件替换掉旧的 dump.rdb 文件,并向父进程发送信号,父进程得知后即可删除旧文件。

优点:

  • 数据恢复快:RDB 文件是经过压缩的二进制文件,非常紧凑,恢复时直接加载到内存即可,速度远超 AOF。
  • 对父进程影响小:持久化由子进程完成,父进程几乎不阻塞,可以继续响应请求。
  • 适合备份:RDB 文件是一个单一的紧凑文件,非常适合进行异地备份。

缺点:

  • 可能丢失数据:RDB 是定时快照,如果在两次快照之间 Redis 宕机,这期间的数据就会丢失。例如,你配置每 5 分钟做一次快照,如果 Redis 在第 4 分钟宕机,你将丢失这 4 分钟的所有数据。
  • fork() 性能问题:当数据量巨大时,fork() 子进程需要消耗一定的时间,可能导致短暂的阻塞。

3. AOF (Append Only File) 持久化

AOF 是一种增量式的持久化方式。

核心原理:

  • AOF 机制会将 Redis 执行的每一条写命令(例如 SET, INCR)都以纯文本的形式记录到一个文件中,文件通常命名为 appendonly.aof。当 Redis 重启时,它会重新执行这个文件中的所有写命令来恢复数据。

工作流程:

  • 当 AOF 功能开启后,Redis 接收到的写命令,除了执行外,还会被追加到 AOF 缓冲区。
  • 根据配置的同步策略(appendfsync),操作系统会将 AOF 缓冲区的数据同步到磁盘上的 AOF 文件。
  • Redis 重启时,会加载并重新执行 AOF 文件中的命令来恢复数据。

同步策略 (appendfsync):

  • always:每条写命令都同步到磁盘。 优点:最高的持久化级别,几乎不丢数据。 缺点:性能开销最大,对磁盘 I/O 压力大。
  • everysec(默认):每秒同步一次。 优点:性能和持久化之间的一个很好的折衷方案,即使宕机也最多丢失 1 秒的数据。 缺点:极端情况下仍可能丢失 1 秒的数据。
  • no:完全依赖操作系统,由操作系统决定何时同步。 优点:性能最高。 缺点:数据丢失风险最大,不可控。

AOF 重写(AOF Rewrite):

  • 随着时间推移,AOF 文件会越来越大,因为它记录了所有的写命令,包括一些无效的或多余的命令(比如对同一个键多次 SET)。AOF 重写就是压缩 AOF 文件,去掉冗余命令,使文件变小。例如,对一个键执行了 INCR 100 次,重写后可能只保留一个 SET 命令。重写过程同样由子进程完成,以避免阻塞主进程。

优点:

  • 数据完整性高:根据同步策略,可以保证极高的持久化完整性,尤其是在 always 模式下。
  • 易于理解和编辑:AOF 文件是纯文本格式,可读性强,方便我们直接查看或进行简单的修复。

缺点:

  • 文件体积大:AOF 文件通常比 RDB 文件大得多。
  • 数据恢复慢:恢复时需要重新执行所有命令,如果 AOF 文件很大,恢复时间会比较长。

4. 最佳实践:RDB + AOF 混合持久化

从 Redis 4.0 开始,官方推出了RDB + AOF 混合持久化。这是目前最推荐的方式。

核心原理:

  • 在 AOF 文件重写时,新的 AOF 文件不再是纯粹的命令追加,而是以 RDB 格式开头,将内存中的数据以 RDB 快照的形式写入。
  • 快照之后,再将重写期间发生的写命令以 AOF 方式追加到文件的末尾。

优点:

  • 数据恢复速度快:Redis 启动时,先加载 RDB 格式的内容,这比加载纯 AOF 文件快得多。
  • 数据完整性高:在加载完 RDB 快照后,再执行追加的 AOF 命令,可以保证数据基本不丢失。
  • 文件体积小:混合持久化文件的体积通常远小于纯 AOF 文件。

特性RDB (快照)AOF (命令追加)RDB + AOF (混合)
优点恢复快、文件小、适合备份数据完整性高、可读性好综合了两者优点,推荐使用
缺点宕机可能丢失数据恢复慢、文件大略微复杂
适用对数据完整性要求不高的场景对数据完整性要求极高绝大多数生产环境

在实际生产环境中,我通常会推荐开启混合持久化,并使用 appendfsync everysec 的策略。这能在数据恢复速度、完整性和性能之间取得一个非常好的平衡。