1. 概述
Redis 中存储数据的模式有两种:
对于 persistence 模式,也就是持久化存储,redis 提供了两种持久化方法:
下面,我们就重点介绍一下 RDB 与 AOF 的区别
2. RDB
RDB 是默认的 redis 持久化方式,又称为快照模式(SNAPSHOT)
RDB 的持久化方式是在某个时间点将数据写入一个临时文件,持久化结束后,用这个临时文件替换上次持久化文件,从而达到持久化数据的作用
snapshot 过程中并不阻塞客户端请求
snapshot首先将数据写入临时文件,当成功结束后,将临时文件重名为dump.rdb
每次启动 redis 时会自动读取 dump.rdb 完成数据的修复
2.1 RDB 的配置
我们可以通过配置文件指定持久化到文件的时间点
下面是一个 redis 配置,由于 RDB 是默认开启的,所以我们不需要在配置中配置开启的命令
下面的配置文件中介绍了 RDB 相关配置的配置项
需要注意的是,snapshot 触发的时机,是有“间隔时间”和“变更次数”共同决定,同时符合2个条件才会 触发snapshot
否则“变更次数”会被继续累加到下一个“间隔时间”上
#dbfilename:持久化数据存储在本地的文件
dbfilename dump.rdb
#dir:持久化数据存储在本地的路径,如果是在/redis/redis-3.0.6/src下启动的redis-cli,则数据会存储在当前src目录下
dir ./
##snapshot触发的时机,save <seconds> <changes>
##如下为900秒后,至少有一个变更操作,才会snapshot
##对于此值的设置,需要谨慎,评估系统的变更操作密集程度
##可以通过“save “””来关闭snapshot功能
#save时间,以下分别表示更改了1个key时间隔900s进行持久化存储;更改了10个key300s进行存储;更改10000个key60s进行存储。
save 900 1
save 300 10
save 60 10000
##当snapshot时出现错误无法继续时,是否阻塞客户端“变更操作”,“错误”可能因为磁盘已满/磁盘故障/OS级别异常等
stop-writes-on-bgsave-error yes
##是否启用rdb文件压缩,默认为“yes”,压缩往往意味着“额外的cpu消耗”,同时也意味这较小的文件尺寸以及较短的网络传输时间
rdbcompression yes
2.2 client 触发持久化
通过 client 端的命令也可以触发持久化,只需要执行以下两个命令中的一个:
两个命令一个是在前台进行存储,一个是在后台进行存储
由于 redis 使用一个主线程来处理所有 client 请求的,而这种方式会阻塞所有 client 请求,所以十分不推荐使用
2.3 RDB 的优势
这是一种定时执行的持久化策略,并且它的执行过程与 redis 主进程是并行的,从而也就拥有了以下的这些优势:
2.4 RDB 的不足
3. AOF
append-only file 的方式是将“操作 + 数据”以指令化的方式追加到操作日志文件尾部
这种模式下,client 的每次操作都必须在 append 操作返回后再进行内存中数据的变更,从而让日志文件保存有历史所有的操作过程
当 server 需要数据恢复时,直接 replay 整个日志文件,就可以还原所有的操作过程
同时,AOF 文件的内容是字符串,是非常容易阅读和解析的
3.1 AOF 的配置
由于 AOF 默认是关闭的,所以需要在配置文件中显式开启
##只有在“yes”下,aof重写/文件同步等特性才会生效
appendonly yes
##指定aof文件名称
appendfilename appendonly.aof
##指定aof操作中文件同步策略,有三个合法值:always everysec no, 默认为everysec
appendfsync everysec
##在aof-rewrite 期间,appendfsync是否暂缓文件同步,"no"表示“不暂缓”,“yes”表示“暂缓”,默认为“no”
no-appendfsync-on-rewrite no
##aof文件rewrite触发的最小文件尺寸(mb,gb),只有大于此aof文件大于此尺寸是才会触发rewrite,默认“64mb”,建议“512mb”
auto-aof-rewrite-min-size 64mb
##相对于“上一次”rewrite,本次rewrite触发时aof文件应该增长的百分比。
##每一次rewrite之后,redis都会记录下此时“新aof”文件的大小(例如A),那么当aof文件增长到A*(1 + p)之后
##触发下一次rewrite,每一次aof记录的添加,都会检测当前aof文件的尺寸。
auto-aof-rewrite-percentage 100
3.2 刷新机制
由于 linux 文件系统的延迟写入机制,默认情况下并非每次 write 操作都会触发实际的磁盘操作,而是先进入 buffer 中,直到合适的实际才会刷新到磁盘,关于这部分内容,请参看此前日志的介绍:
标准输出、标准输入和标准出错 以及 缓冲
上述 redis 配置中,加入了 appendfsync 选项,有以下三个可选选项:
几乎在所有场景中,everysec 都是最好的选择,如果真的想要去选择 always,那为什么不选择一款关系型数据库呢?
3.3 AOF 的 rewrite
随着操作的进行,AOF 日志文件将会越来越大,这就需要一个“压缩”机制,这就是 AOF 的 rewrite 机制
AOF rewrite 的过程是不依赖已经存在的日志文件的,而是采取了类似snapshot的方式,基于 copy-on-write,全量遍历内存中的数据,然后逐个序列到 AOF 文件中
而在 rewrite 过程中产生的变更操作会被 redis 收集起来,最后追加到新的 aof 文件中
最后,将新的 aof 文件重命名为 appendonly.aof 即完成 rewrite 工作
我们可以通过配置文件指定 rewrite 的时机,也可以通过 bgrewriteaof 指令触发
但是需要注意的是,无论是人工干预还是系统触发,snapshot和rewrite需要逐个被执行
3.4 AOF 的优点
AOF 最大的优点就是他的安全
由于 AOF 机制保证了先写入日志后更新内存,因此可以保证数据的安全性
即使考虑到操作系统的 buffer 缓存,在默认情况下也最多只会丢失一秒的数据
而且文件写入是通过 append 操作,即使写入过程中宕机,也只会丢失本次写入的一个操作,同时,redis-check-aof 工具也可以轻易地修复这种问题,这与依赖 copy on write 的 RDB 机制是完全不同的
同时,rewrite 过程中,新增操作是写回到原 aof 文件的,所以即使宕机也不会有任何影响
另外的一个优势就是 aof 文件格式非常清晰易于理解,十分便于进行日志分析和个性化的回复工作,例如误操作的删除
3.5 AOF 的缺点
4. 总结
一般来说, 如果想达到足以媲美 PostgreSQL 的数据安全性, 你应该同时使用两种持久化功能
如果你非常关心你的数据, 但仍然可以承受数分钟以内的数据丢失, 那么可以只使用 RDB 持久化
官方并不推荐只使用 AOF 持久化
事实上,官方在未来是有将 AOF 与 RDB 合为一个持久化策略的
参考资料
http://redisdoc.com/
http://redisdoc.com/topic/persistence.html
Redis持久化存储(AOF与RDB两种模式) -- https://www.linuxidc.com/Linux/2016-10/136352.htm
redis的持久化方式RDB和AOF的区别 -- https://blog.csdn.net/m0_38110132/article/details/76906422