1. 什么是持久化
持久化(Persistence),即把数据(如内存中的对象)保存到可永久保存的存储设备中(如磁盘)。 持久化Redis所有数据保持在内存中,对数据的更新将异步地保存到磁盘上。
2. 持久化的实现方式
快照方式持久化
快照方式持久化就是在某时刻把所有数据进行完整备份。
例:Mysql的Dump方式、Redis的RDB方式。
写日志方式持久化
写日志方式持久化就是把用户执行的所有写指令(增删改)备份到文件中,还原数据时只需要把备份的所有指令重新执行一遍即可。
例:Mysql的Binlog、Redis的AOF、Hbase的HLog。
二、RDB
1. 什么是RDB、
RDB持久化方式能够在指定的时间间隔能对你的数据进行快照存储。 在默认情况下, Redis 将数据库快照保存在名字为 dump.rdb的二进制文件中。 在 Redis 运行时, RDB 程序将当前内存中的数据库快照保存到磁盘文件中, 在 Redis 重启动时, RDB 程序可以通过载入 RDB 文件来还原数据库的状态。
2. RDB相关配置
# RDB自动持久化规则 # 当 900 秒内有至少有 1 个键被改动时,自动进行数据集保存操作 save 900 1 # 当 300 秒内有至少有 10 个键被改动时,自动进行数据集保存操作 save 300 10 # 当 60 秒内有至少有 10000 个键被改动时,自动进行数据集保存操作 save 60 10000 # RDB持久化文件名 dbfilename dump-<port>.rdb # 数据持久化文件存储目录 dir /var/lib/redis # bgsave发生错误时是否停止写入,通常为yes stop-writes-on-bgsave-error yes # rdb文件是否使用压缩格式 rdbcompression yes # 是否对rdb文件进行校验和检验,通常为yes rdbchecksum yes
3. RDB的优点
-
RDB是一个非常紧凑的文件,它保存了某个时间点得数据集,非常适用于数据集的备份,比如你可以在每个小时报保存一下过去24小时内的数据,同时每天保存过去30天的数据,这样即使出了问题你也可以根据需求恢复到不同版本的数据集。
-
RDB是一个紧凑的单一文件,很方便传送到另一个远端数据中心或者亚马逊的S3(可能加密),非常适用于灾难恢复。
-
RDB在保存RDB文件时父进程唯一需要做的就是fork出一个子进程,接下来的工作全部由子进程来做,父进程不需要再做其他IO操作,所以RDB持久化方式可以最大化redis的性能。
-
与AOF相比,在恢复大的数据集的时候,RDB方式会更快一些。
4. RDB的缺点
-
耗时、耗性能。RDB 需要经常fork子进程来保存数据集到硬盘上,当数据集比较大的时候,fork的过程是非常耗时的,可能会导致Redis在一些毫秒级内不能响应客户端的请求。如果数据集巨大并且CPU性能不是很好的情况下,这种情况会持续1秒,AOF也需要fork,但是你可以调节重写日志文件的频率来提高数据集的耐久度。
-
不可控、丢失数据。如果你希望在redis意外停止工作(例如电源中断)的情况下丢失的数据最少的话,那么RDB不适合你。虽然你可以配置不同的save时间点(例如每隔5分钟并且对数据集有100个写的操作),是Redis要完整的保存整个数据集是一个比较繁重的工作,你通常会每隔5分钟或者更久做一次完整的保存,万一在Redis意外宕机,你可能会丢失几分钟的数据。
三、AOF
1. 什么是AOF
快照功能(RDB)并不是非常耐久(durable): 如果 Redis 因为某些原因而造成故障停机, 那么服务器将丢失最近写入、且仍未保存到快照中的那些数据。 从 1.1 版本开始, Redis 增加了一种完全耐久的持久化方式: AOF 持久化。 你可以在配置文件中打开AOF方式:
appendonly yes
打开AOF后, 每当 Redis 执行一个改变数据集的命令时(比如 SET), 这个命令就会被追加到 AOF 文件的末尾。这样的话, 当 Redis 重新启时, 程序就可以通过重新执行 AOF 文件中的命令来达到重建数据集的目的。
2. AOF持久化的三种策略
always、everysec、no对比
命令 | 优点 | 缺点 |
---|---|---|
always | 不丢失数据 | IO开销大,一般SATA磁盘只有几百TPS |
everysec | 每秒进行与fsync,最多丢失1秒数据 | 可能丢失1秒数据 |
no | 不用管 | 不可控 |
推荐(并且也是默认)的措施为每秒 fsync 一次, 这种 fsync 策略可以兼顾速度和安全性。
3. AOF相关配置
# 开启AOF持久化方式 appendonly yes # AOF持久化文件名 appendfilename appendonly-<port>.aof # 每秒把缓冲区的数据同步到磁盘 appendfsync everysec # 数据持久化文件存储目录 dir /var/lib/redis # 是否在执行重写时不同步数据到AOF文件 # 这里的 yes,就是执行重写时不同步数据到AOF文件 no-appendfsync-on-rewrite yes # 触发AOF文件执行重写的最小尺寸 auto-aof-rewrite-min-size 64mb # 触发AOF文件执行重写的增长率 auto-aof-rewrite-percentage 100
4. AOF的优点
-
使用AOF 会让你的Redis更加耐久: 你可以使用不同的fsync策略:无fsync,每秒fsync,每次写的时候fsync。使用默认的每秒fsync策略,Redis的性能依然很好(fsync是由后台线程进行处理的,主线程会尽力处理客户端请求),一旦出现故障,你最多丢失1秒的数据。
-
AOF文件是一个只进行追加的日志文件,所以不需要写入seek,即使由于某些原因(磁盘空间已满,写的过程中宕机等等)未执行完整的写入命令,你也也可使用redis-check-aof工具修复这些问题。
-
Redis 可以在 AOF 文件体积变得过大时,自动地在后台对 AOF 进行重写: 重写后的新 AOF 文件包含了恢复当前数据集所需的最小命令集合。 整个重写操作是绝对安全的,因为 Redis 在创建新 AOF 文件的过程中,会继续将命令追加到现有的 AOF 文件里面,即使重写过程中发生停机,现有的 AOF 文件也不会丢失。 而一旦新 AOF 文件创建完毕,Redis 就会从旧 AOF 文件切换到新 AOF 文件,并开始对新 AOF 文件进行追加操作。
-
AOF 文件有序地保存了对数据库执行的所有写入操作, 这些写入操作以 Redis 协议的格式保存, 因此 AOF 文件的内容非常容易被人读懂, 对文件进行分析(parse)也很轻松。 导出(export) AOF 文件也非常简单: 举个例子, 如果你不小心执行了 FLUSHALL 命令, 但只要 AOF 文件未被重写, 那么只要停止服务器, 移除 AOF 文件末尾的 FLUSHALL 命令, 并重启 Redis , 就可以将数据集恢复到 FLUSHALL 执行之前的状态。
5. AOF的缺点
-
对于相同的数据集来说,AOF 文件的体积通常要大于 RDB 文件的体积。
-
根据所使用的 fsync 策略,AOF 的速度可能会慢于 RDB 。 在一般情况下, 每秒 fsync 的性能依然非常高, 而关闭 fsync 可以让 AOF 的速度和 RDB 一样快, 即使在高负荷之下也是如此。 不过在处理巨大的写入载入时,RDB 可以提供更有保证的最大延迟时间(latency)。
四、RDB和AOF的抉择
1. RDB 和 AOF 对比
- | RDB | AOF |
---|---|---|
启动优先级 | 低 | 高 |
体积 | 小 | 大 |
恢复速度 | 快 | 慢 |
数据安全性 | 丢数据 | 根据策略决定 |
2. 如何选择使用哪种持久化方式?
一般来说, 如果想达到足以媲美 PostgreSQL 的数据安全性, 你应该同时使用两种持久化功能。
3.如何同时启用RDB和AOF方法:
Redis 4.x 开始提供的心的混合持久化功能
将配置参数
aof-use-rdb-preamble yes
设置完以后,在重写AOF文件时,Redis首先会把数据集以RDB的格式转储到内存中并作为AOF文件的开始部分。
在重写之后,Redis继续使用传统的AOF格式在AOF文件中记录写入命令。
你可以通过观察重写后的AOF文件头部在同时启用了RDB和AOF方法后,你可以通过观察重写后的AOF文件头部和尾部清楚地了解这种混合格式。
如果启用了混合持久化,那么在AOF文件的开头首先使用的是RDB格式。因为RDB的压缩格式可以实现更快速地重写和加载数据文件,同时也保留了AOF数据致性更好的优点, 所以Redis可以从混合持久化中获益。