一、RDB(Redis DataBase)
- RDB 全程是 Redis DataBase,它是一种将 Redis 在某一时刻内存中的数据以快照形式保存到磁盘的机制 ,相当于给执行save/bgsave命令时刻的内存数据库数据拍了一张快照
- 我们如果通过save命令来执行快照,由于 Redis 是单线程模型,save命令会阻塞主线程,因为快照生成的过程比执行普通指令耗时更长,在此期间 Redis 无法处理客户端请求。而bgsave命令会 fork 出一个子进程,由子进程在后台执行备份工作,主线程可以继续处理客户端请求,不会造成阻塞。因此在实际应用中,推荐使用bgsave来生成 RDB 快照。需要注意的是,fork 子进程时会有短暂的阻塞,且会占用一定内存(基于写时复制技术,父子进程共享内存,只有在数据发生修改时才会为子进程分配独立内存)
- RDB 的优点是:
- 第一个是 RDB 生成的快照文件经过了二进制压缩,体积相对较小。虽然 Redis 是内存数据库,但数据量可能较大,不过经过压缩处理后的 RDB 文件依然便于存储和传输
- 第二个是它恢复数据的速度很快,因为在数据恢复时,直接将 RDB 文件中的数据一次性加载到内存即可,不需要像 AOF 那样逐条重放日志。所以 RDB 适合做数据备份和灾难恢复
- RDB 的缺点是:
- 第一个,两次快照之间的数据可能会丢失。例如第一次快照后隔了很长时间才进行下一次快照,那么万一数据库宕机,就会丢失这两次快照间隔期间的数据
- 第二个,如果频繁执行快照,即使使用bgsave开启后台线程进行工作,fork 子进程以及子进程进行数据持久化操作都会占用 CPU、内存等系统资源,对服务器性能产生一定影响
二、AOF(Append Only File)
- Redis 会在硬盘上创建一个 AOF(Append Only File)文件,该文件用于记录服务器执行的所有写操作命令
- Redis 提供了三种 AOF 写策略:
- always:每次执行写操作后,Redis 主线程会立即将写操作同步到硬盘上的 AOF 文件中。这种策略能保证数据的最高安全性,因为一旦写操作执行成功,就会被持久化到磁盘,但会对性能产生较大影响,因为每次写操作都涉及磁盘 I/O
- everysec:Redis 会使用一个后台线程(更准确地说是子线程)每秒将这一秒内发生的写操作追加到 AOF 文件中。这种策略在性能和数据安全性之间做了平衡,即使服务器发生故障,最多只会丢失一秒内的数据
- no:将数据写入 AOF 文件的操作完全交给操作系统决定。Redis 只负责将写操作追加到 AOF 缓冲区,由操作系统决定何时将缓冲区的数据刷新到磁盘。这种策略性能最高,但数据安全性最低,因为在操作系统未将数据刷新到磁盘时服务器宕机,可能会丢失较多数据
- AOF 的缺点在于:
- 由于 AOF 文件持续记录写操作,随着时间推移和写操作的增加,AOF 文件会变得越来越大,这会占用大量的磁盘空间
- 在恢复数据时,相较于 RDB 方式,AOF 恢复速度较慢。因为 Redis 单线程需要将 AOF 文件中的所有写操作命令依次重新执行一遍,而 RDB 是直接将数据加载到内存
- 此外,Redis 为了解决 AOF 文件过大的问题,提供了 AOF 重写机制,它可以在不改变数据库状态的前提下,将 AOF 文件中冗余的命令合并,从而减小 AOF 文件的体积
三、RDB vs AOF如何选择?
- 如果需要快速恢复数据,采用 RDB 是比较合适的选择。RDB 是将 Redis 某一时刻的内存数据以快照形式保存到磁盘,恢复数据时直接将 RDB 文件加载到内存,无需像 AOF 那样重新执行大量的写命令,因此恢复速度较快,能在短时间内让 Redis 服务恢复到之前的状态
- 如果需要保证数据的绝对安全,AOF(always)策略是一个好的选择。使用
always
策略时,每次写操作都会立即同步到磁盘上的 AOF 文件中,这样即使 Redis 服务器发生故障或意外宕机,也不会丢失任何已执行的写操作数据,最大程度地保证了数据的完整性和安全性。不过,这种策略会对 Redis 的性能产生较大影响,因为频繁的磁盘 I/O 操作会成为性能瓶颈 - 在高并发场景下,选择 RDB + AOF 结合的策略通常是比较明智的。RDB 可以定期生成数据快照,用于全量数据备份和在需要时快速恢复数据,减轻数据恢复的时间成本;AOF 采用 everysec 策略(而不是 always 策略,因为 always 策略在高并发下性能损耗过大),每秒将写操作同步到 AOF 文件,在保证数据安全性(最多丢失 1 秒的数据)的同时,也不会对性能造成太大的影响。两者结合,既能满足高并发场景下对性能的要求,又能在一定程度上保证数据的安全性和可恢复性
四、总结与持久化配置建议
- 在通用场景下,采用RDB(每天定时执行) + AOF(everysec)结合的策略是较为常见且合理的选择
- 如果对数据安全性要求极高,可以采用 AOF(always)策略