Redis系列 —— (三)Redis的持久化
什么是持久化
持久化就是把内存的数据写入到磁盘中去,防止服务宕机导致内存数据丢失。一旦内存数据丢失,可以使用磁盘中的数据进行恢复。
持久化的机制
Redis提供了不同级别的持久化方式,RDB 和 AOF 机制。
-
RDB
是Reids DataBase 缩写快照。Redis默认的持久化方式。按照指定的时间间隔将内存数据以快照形式存储到硬盘中。生成数据文件为dump.rdb。通过配置save参数定义时间间隔。快照
在默认情况下,Redis 将数据库快照保存在名字为 dump.rdb 的二进制文件中。你可以对 Redis 进行设置,让它在“ N 秒内数据集至少有 M 个改动”这一条件被满足时,自动保存一次数据集。你也可以通过调用 SAVE 或者 BGSAVE ,手动让 Redis 进行数据集保存操作。比如说,以下设置会让 Redis 在买组“ 60 秒内至少有 1000 个键被改动”这一条件时,自动保存一次数据集:
save 60 1000
这种持久化方式被称为快照 snapshotting。工作方式
当 Redis 需要保存 dump.rdb 文件时,服务器执行以下操作:- Redis 调用 forks ,同时拥有父进程和子进程。
- 子进程将数据集写入到一个临时 RDB 文件中。
- 当子进程完成对新 RDB 文件的写入时,Redis 用新 RDB 文件替换原来的 RDB 文件,并删除旧的 RDB 文件。
这种工作方式使得 Redis 可以从写是复制(copy-on-write)机制中获益。
优点
- dump.rdb 是一个紧凑单一的文件,非常方便.
- 可以保存到安全的服务器或数据中心,非常适用于灾备。
- IO性能最大化,fork子进程进行写操作,主进程继续处理命令。
- 恢复大的数据集时,比 AOF 方式更快。
缺点
- 数据安全性低。在redis意外停止工作的情况下丢失的数据最好的话,RDB不适合。可能会丢失指定时间间隔时段内的数据。
- RDB 需要经常fork子进程来保存数据集到硬盘,当数据集较大时,fork的过程是非常耗时的,可能导致redis在一些毫秒级内不能响应客户端的请求。
-
AOF
即 Append Only File 持久化。将redis执行的每次写命令记录到单独的日志文件中,当重启redis会重新将持久化的日志文件恢复数据。
当 RDB 和 AOF 两种方式同时开启时,数据恢复优先选择 AOF 方式。
你可以在配置文件中打开AOF方式:
appendonly yes
开启后,每当 Redis 执行一个改变数据集的命令时(比如 SET),这个命令就会被追加到 AOF 文件的末尾。这样的话,当 Redis 重新启动时,程序就可以通过重新执行 AOF 文件中的命令来达到重建数据集的目的。日志重写
因为 AOF 的运作方式是不断的将命令追加到文件的末尾,所以随着写入命令的不断增加,AOF 文件的体积也会变得越来越大。为了处理这种情况,Redis 支持一种有趣的特性:可以在不打断服务客户端的情况下,对 AOF 文件进行重建(rebuild)。执行 BGREWRITEAOF 命令,Redis 将生成一个新的 AOF 文件,这个文件包含重建当前数据集所需要的最少命令。Redis 2.2 需要自己手动执行 BGREWRITEAOF 命令;Redis 2.4 则可以自动触发 AOF 重写。fsync
你可以配置 Redis 多久才将数据 fsync 到磁盘一次。有三种方式:- 每次有新命令追加到 AOF 文件时就执行一次 fsync :非常慢,也非常安全。
- 每秒 fsync 一次:足够快(和使用 RDB 持久化差不多),并且在故障时只会丢失 1 秒的数据。
- 从不 fsync :将数据交给操作系统来处理。更快,也更不安全。
- 推荐(并且也是默认)的措施为每秒 fsync 一次,这种 fsync 策略可以兼顾速度和安全性。
工作方式
AOF 重写和 RDB 创建快照一样,都巧妙的利用了写是复制机制:- Redis 执行 fork(),现在同时拥有父进程和子进程。
- 子进程开始将新 AOF 文件的内容写入到临时文件。
- 对于所有新执行的写入命令,父进程一边讲他们累计到一个内存缓存中,一边将这些改动追加到现有 AOF 文件的末尾。 这样即使在重写的中途发生停机,现有的 AOF 文件也还是安全的。
- 当子进程完成重写工作时,它给父进程发送一个信号,父进程在接收到信号后,将内存缓存中的所有数据追加到新 AOF 文件的末尾。
- Redis 原子的用新文件替换旧文件,之后所有命令都会直接追加到新 AOF 文件的末尾。
优点
- 数据安全,让redis更加耐久,可以使用不同的fsync策略,无fsync,每秒fsync,每次写的时候fsync,使用默认每秒fsync,性能依然很好。
- aof文件是一个只进行追加的日志文件,即使中途服务器宕机,也可以通过 redis-check-aof 工具解决数据一致性问题。
- aof 的 rewrite模式可以在文件体积变得过大时,redis自动在后台对aof文件进行重写以及继续追加。也可以删除执行过的错误命令。
缺点
- aof文件体积通常要大于rdb文件体积。
- 数据集大时,比rdb 启动效率低。
如何选择哪种持久化方式
一般来说,如果想达到足以高的数据安全性,应该同时使用两种持久化机制。
过去你非常关心你的数据,但仍然可以承受数分钟以内的数据丢失,那么你可以只是用rdb机制。
有很多用户都只使用aof机制,但并不推荐这种方式。rdb定时生成快照,非常便于进行数据备份,并且rdb恢复的速度也要比aof要快。