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 文件,去掉冗余命令,使文件变小。例如,对一个键执行了INCR100 次,重写后可能只保留一个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 的策略。这能在数据恢复速度、完整性和性能之间取得一个非常好的平衡。