Skip to content

Redis是如何实现数据持久化的

Redis为了防止因进程退出或服务器宕机导致内存中的数据丢失,提供了多种持久化机制,将数据写入硬盘。 主要的持久化方式有RDB(Redis Database)、AOF(Append Only File)以及两者的混合持久化。

1. RDB (Redis Database) 快照

RDB是Redis默认的持久化方式,它通过创建内存数据的快照来实现。 RDB文件是一个经过压缩的二进制文件,记录了某个时间点上的数据集。

工作原理

RDB的触发方式分为手动触发和自动触发。

  • 手动触发:

    • SAVE: 这个命令会阻塞Redis主线程,直到RDB文件创建完毕。在生产环境中不建议使用,因为会长时间阻塞客户端请求。
    • BGSAVE: BGSAVE会创建一个子进程来负责生成RDB文件,主进程可以继续处理客户端请求,阻塞只发生在fork子进程的阶段,通常时间很短。这是默认的触发方式。
  • 自动触发: 在redis.conf配置文件中,可以通过save指令设置自动触发BGSAVE的条件。例如:

    • save 900 1: 表示在900秒内,如果至少有1个键发生变化,则自动触发BGSAVE
    • save 300 10: 表示在300秒内,如果至少有10个键发生变化,则自动触发BGSAVE

BGSAVE命令执行时,Redis主进程会利用操作系统的写时复制(Copy-on-Write)机制。 主进程fork出一个子进程,子进程共享主进程的内存数据。在子进程写入RDB文件期间,如果主进程需要修改某块数据,操作系统会复制这块数据的一个副本,主进程修改副本,而子进程继续将原始数据写入RDB文件。

优点

  • 性能好,恢复快: RDB文件是紧凑的二进制格式,体积小,非常适合备份和灾难恢复。 Redis加载RDB文件来恢复数据的速度远快于AOF。
  • 对性能影响小: BGSAVE使用子进程进行持久化,对主进程服务影响较小。

缺点

  • 数据丢失风险高: RDB是间隔性地进行快照,如果在两次快照之间服务器发生故障,那么这期间的数据将会全部丢失。
  • fork子进程开销: 当数据集很大时,fork子进程可能会消耗较多时间和内存,甚至可能导致服务短暂停顿。

2. AOF (Append Only File) 只追加文件

AOF持久化记录了服务器接收到的每一个写操作命令。 当Redis重启时,会重新执行AOF文件中的所有命令来恢复数据。

工作原理

AOF的实现过程可以分为命令追加、文件写入和文件同步。

  1. 命令追加 (Append): 当AOF持久化功能开启后,服务器在执行完一个写命令后,会以协议格式将被执行的命令追加到AOF缓冲区的末尾。
  2. 文件写入 (Write) 和同步 (Sync): AOF缓冲区的数据会根据appendfsync配置策略写入并同步到AOF文件中。 这个策略有三种选择:
    • always: 每个写命令都立即同步到磁盘,最安全但性能最低。
    • everysec: 每秒同步一次,这是默认策略,在性能和数据安全性之间做了很好的平衡,最多只会丢失1秒的数据。
    • no: 完全依赖操作系统来同步,速度最快,但数据丢失风险最高。

AOF重写

随着写操作的不断增加,AOF文件会变得越来越大。为了解决这个问题,Redis引入了AOF重写机制。 AOF重写会创建一个新的AOF文件,这个文件包含了恢复当前数据集所需的最少命令集合。例如,对一个计数器执行了100次INCR,重写后的AOF文件可能只会有一条SET命令。

优点

  • 数据安全性高: 根据同步策略,AOF可以提供更高的数据安全性,最多丢失1秒的数据。
  • 文件可读性强: AOF文件是文本格式,可以方便地查看和处理。

缺点

  • 文件体积大: 对于相同的数 据集,AOF文件通常比RDB文件大。
  • 恢复速度慢: 数据恢复时需要重新执行所有写命令,速度相对RDB较慢。
  • 对性能有一定影响: 频繁的磁盘同步会对系统性能产生一定的影响。

3. 混合持久化

从Redis 4.0开始,引入了混合持久化机制,结合了RDB和AOF的优点。

工作原理

当开启混合持久化后(通过aof-use-rdb-preamble yes配置),在进行AOF重写时,子进程会将当前内存中的数据以RDB的格式写入到新的AOF文件的开头部分,然后将重写期间新增的写命令以AOF格式追加到文件末尾。

这样,在数据恢复时,Redis会先加载RDB部分的数据,然后接着执行AOF部分的增量命令,从而大大提高了恢复速度,同时又降低了数据丢失的风险。

如何选择?

  • 如果数据丢失一些也可以接受,或者主要用作缓存,可以选择只使用RDB。
  • 如果需要高数据安全性,建议同时开启RDB和AOF,或者使用混合持久化。
  • 不建议单独使用AOF,因为RDB更适合用于数据备份。

当RDB和AOF都开启时,Redis在重启时会优先使用AOF文件来恢复数据,因为它通常能保证更完整的数据。