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的实现过程可以分为命令追加、文件写入和文件同步。
- 命令追加 (Append): 当AOF持久化功能开启后,服务器在执行完一个写命令后,会以协议格式将被执行的命令追加到AOF缓冲区的末尾。
- 文件写入 (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文件来恢复数据,因为它通常能保证更完整的数据。