一、RDB
1. RDB介绍
快照持久化也就做RDB持久化。快照持久化的实现方式简单来说就是:Redis将当前内存中存储的数据写入到一个文件中,将这个文件作为Redis当前的一个快照,保存在磁盘中。当Redis重启时,将这个快照文件中存储的内容加载进内存,即可恢复Redis之前的状态。
2. RDB的触发方式
2.1. 手动触发
-
save
该命令会阻塞当前Redis服务器,执行save命令期间,Redis不能处理其他命令,直到RDB过程完成为止。 -
bgsave
Redis进程执行fork操作创建子进程,RDB持久化过程由子进程负责,完成后自动结束。阻塞只发生在fork阶段,一般时间很短。基本上 Redis 内部所有的RDB操作都是采用 bgsave 命令。
命令 | save | bgsave |
---|---|---|
IO类型 | 同步 | 异步 |
阻塞 | 是 | fork时阻塞 |
复杂度 | O(n) | O(n) |
优点 | 不会消耗额外内存 | 不阻塞 |
缺点 | 阻塞客户端命令 | 需要fork,消耗内存 |
2.2 自动触发
在redis.conf文件中的SNAPSHOTTING下,我们可以对RDB的自动触发进行配置
-
save
这里是用来配置触发 Redis的 RDB 持久化条件,也就是什么时候将内存中的数据保存到硬盘。比如“save m n”。表示m秒内数据集存在n次修改时,自动触发bgsave
当然如果你只是用Redis的缓存功能,不需要持久化,那么你可以注释掉所有的 save 行来停用保存功能。可以直接一个空字符串来实现停用:save "" -
stop-writes-on-bgsave-error
默认值为yes。当启用了RDB且最后一次后台保存数据失败,Redis是否停止接收数据。这会让用户意识到数据没有正确持久化到磁盘上,否则没有人会注意到灾难(disaster)发生了。如果Redis重启了,那么又可以重新开始接收数据了 -
rdbcompression
默认值是yes。对于存储到磁盘中的快照,可以设置是否进行压缩存储。 -
rdbchecksum
默认值是yes。在存储快照后,我们还可以让redis使用CRC64算法来进行数据校验,但是这样做会增加大约10%的性能消耗,如果希望获取到最大的性能提升,可以关闭此功能。 -
dbfilename
设置快照的文件名,默认是 dump.rdb -
dir
设置快照文件的存放路径,这个配置项一定是个目录,而不能是文件名
3. RDB的优劣势
3.1 优势
RDB文件紧凑,非常适合尽心备份和灾难恢复
生成RDB文件时,redis主进程会fork一个子进程来处理所有的保存工作,主进程不需要进行任何磁盘IO操作
RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快
3.2 劣势
RDB方式数据没办法做到实时持久化/秒级持久化。因为bgsave每次运行都要执行fork操作创建子进程,属于重量级操作,如果不采用压缩算法(内存中的数据被克隆了一份,大致2倍的膨胀性需要考虑),频繁执行成本过高(影响性能)
RDB文件使用特定二进制格式保存,Redis版本演进过程中有多个格式的RDB版本,存在老版本Redis服务无法兼容新版RDB格式的问题(版本不兼容)
在一定间隔时间做一次备份,所以如果redis意外down掉的话,就会丢失最后一次快照后的所有修改(数据有丢失)
二、AOF
1. AOF介绍
AOF全称为只追加文件(append-only file),它的实现方式简单来说就是:AOF持久化机制,会将Redis执行的所有写指令,追加到到AOF的末尾,当服务器发生宕机,或者由于某些原因需要重启时,在重启后,读取AOF文件,重新执行其中记录的写操作,以此达到恢复数据的目的。
2.触发方式
在APPEND ONLY MODE下对appendonly进行yes配置即可开启AOF
-
appendfsync always
Redis每次执行写指令,都会立即将这个写指令同步到AOF中;使用这个选项时,Redis发生异常,则最多只会丢失一次写操作(也就是在同步的过程中宕机,没同步完成),但是这也会导致Redis的响应速度变慢,因为此选项会造成频繁的IO操作 -
appendfsync everysec
每秒同步一次,使用此选项,速度足够快,而且发生宕机时也只会丢失1s内的写操作 -
appendfsync no
让操作系统来决定什么时候进行同步,这个选项速度更快,但是不安全,宕机时丢失数据的多少是不确定的
推荐(也是默认),使用第二个选项everysec,每秒进行一次同步,因为这个选项兼顾了速度与安全性,而第一个选项太慢,第三个选项无法保证安全性
3. AOF重写
AOF持久化的执行机制就是,不断地将写指令追加到AOF的末尾,这样就会导致AOF越来越大。为了解决AOF越来越大的问题,Redis实现了一种优化机制——AOF重写。当Redis检查到AOF已经很大时,就会触发重写机制,优化其中的内容,将它优化为能够得到相同结果的最小的指令集合。
经过了重写后,AOF的大小将会大大减小,而且也去除了不必要的操作,优化了恢复数据的指令集。而AOF重写的过程与生成一个快照文件类似,如下:
Redis执行fock(),创建一个子进程用来执行后续操作,而父进程继续处理发送到Redis的执行请求;
子进程重写旧AOF文件,将重写后的内容写入到一个临时文件;
如果这个过程中,有新的写指令到达,那么Redis会将这些写指令依旧追加到旧的AOF中,同时也会将这些指令加入到内存的一个缓冲区中。这样做的目的是,如果服务器发生异常,AOF重写失败,这些指令依然能够保存在旧AOF,不会丢失;
当子进程完成重写工作时,它给父进程发送一个信号,父进程在接收到信号之后,将内存缓存中的所有写指令追加到新 AOF 文件的末尾;
使用新AOF替换旧的AOF,这之后执行的所有写指令都将追加到新的AOF中;
4. AOF的优缺点
4.1 优点
- 使用 AOF 持久化会让 Redis 变得非常耐久,意思就是说,当发生异常导致需要重启服务器时,只会丢失很少的一部分数据,因为AOF持久化默认1s同步一次,也就是说,Redis最多只会丢失1s中所做的修改
- Redis 可以在 AOF 文件体积变得过大时,自动地在后台对 AOF 进行重写: 重写后的新 AOF 文件包含了恢复当前数据集所需的最小命令集合
- AOF 文件有序地保存了对数据库执行的所有写入操作, 这些写入操作以 Redis 协议的格式保存, 因此 AOF 文件的内容非常容易被人读懂, 对文件进行分析(parse)也很轻松。
- AOF 文件是一个只进行追加操作的日志文件(append only log), 因此对 AOF 文件的写入不需要进行 seek , 即使日志因为某些原因而包含了未写入完整的命令(比如写入时磁盘已满,写入中途停机,等等), redis-check-aof 工具也可以轻易地修复这种问题。
4.2 缺点
- 对于相同的数据集来说,AOF 文件的体积通常要大于快照RDB文件的体积大,因为RDB只存储数据,而AOF中的写指令,既包含指令,也包含数据;
- 如果AOF体积太大,那么恢复数据将要花费较长的时间,因为需要重做指令;
三、 RDB or AOF?
- 如果希望自己的数据库有很高的安全性,则应该两者同时使用,AOF用作精确记录,而快照用作数据备份,前面也说过,快照非常适合用来做数据备份,因为它只存储数据库中的数据,并且经过了压缩,而且它恢复Redis数据的速度一般要快于AOF;
- 如果可以容忍一段时间内的数据丢失,则可以考虑只使用RDB,减小服务器的开销;