redis 持久化方式-AOF&RDB

1. 概述

Redis 中存储数据的模式有两种:

cache-only -- 只做为“缓存”服务,不持久数据,数据在服务终止后将消失,此模式下也将不存““数据恢复”的手段,是一种安全性低/效率高/容易扩展的

persistence -- 为内存中的数据持久备份到磁盘文件,在服务重启后可以恢复,此模式下数据相对安全

对于 persistence 模式,也就是持久化存储,redis 提供了两种持久化方法:

Redis Database (RDB)

Append-only file (AOF)

下面,我们就重点介绍一下 RDB 与 AOF 的区别

2. RDB

RDB 是默认的 redis 持久化方式,又称为快照模式(SNAPSHOT)

RDB 的持久化方式是在某个时间点将数据写入一个临时文件,持久化结束后,用这个临时文件替换上次持久化文件,从而达到持久化数据的作用

snapshot 过程中并不阻塞客户端请求

snapshot首先将数据写入临时文件,当成功结束后,将临时文件重名为dump.rdb

每次启动 redis 时会自动读取 dump.rdb 完成数据的修复

2.1 RDB 的配置

我们可以通过配置文件指定持久化到文件的时间点

下面是一个 redis 配置,由于 RDB 是默认开启的,所以我们不需要在配置中配置开启的命令

下面的配置文件中介绍了 RDB 相关配置的配置项

需要注意的是,snapshot 触发的时机,是有“间隔时间”和“变更次数”共同决定,同时符合2个条件才会 触发snapshot

否则“变更次数”会被继续累加到下一个“间隔时间”上

2.2 client 触发持久化

通过 client 端的命令也可以触发持久化,只需要执行以下两个命令中的一个:

./redis-cli -h ip -p port save

./redis-cli -h ip -p port bgsave

两个命令一个是在前台进行存储,一个是在后台进行存储

由于 redis 使用一个主线程来处理所有 client 请求的,而这种方式会阻塞所有 client 请求,所以十分不推荐使用

2.3 RDB 的优势

这是一种定时执行的持久化策略,并且它的执行过程与 redis 主进程是并行的,从而也就拥有了以下的这些优势:

持久化与主进程并行进行,通常不会对 redis 主进程造成影响,实现了 redis 的高性能

易于异常恢复,由于这种方式中 redis 持久化到一个文件中,我们可以非常容易的去备份和恢复这个文件

相比于 AOF 机制,如果数据集很大,RDB 的启动效率更高

2.4 RDB 的不足

数据丢失 -- 由于 RDB 是间隔一段时间来进行持久化的,所以两次持久化之间如果发生故障,会丢失上一次持久化值后的数据

影响性能 -- 由于每次都是将内存数据完整写入磁盘一次,所以如果数据量巨大,将会造成大量的 IO 操作,从而会严重影响性能

3. AOF

append-only file 的方式是将“操作 + 数据”以指令化的方式追加到操作日志文件尾部

这种模式下,client 的每次操作都必须在 append 操作返回后再进行内存中数据的变更,从而让日志文件保存有历史所有的操作过程

当 server 需要数据恢复时,直接 replay 整个日志文件,就可以还原所有的操作过程

同时,AOF 文件的内容是字符串,是非常容易阅读和解析的

3.1AOF 的配置

由于 AOF 默认是关闭的,所以需要在配置文件中显式开启

3.2 刷新机制

由于 linux 文件系统的延迟写入机制,默认情况下并非每次 write 操作都会触发实际的磁盘操作,而是先进入 buffer 中,直到合适的实际才会刷新到磁盘,关于这部分内容,请参看此前日志的介绍:

标准输出、标准输入和标准出错 以及 缓冲

上述 redis 配置中,加入了 appendfsync 选项,有以下三个可选选项:

always -- 每一条 aof 记录都立即同步到文件,虽然这是最安全的方式,但是也是 IO 开销最大的方式

everysec -- 每秒强制同步到磁盘一次,这是默认操作,也是官方推荐的选项,服务器故障最多损失最近一秒内的操作数据

no -- 从不强制刷新磁盘,而是交给操作系统处理

几乎在所有场景中,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 指令触发

redis-cli -h ip -p port bgrewriteaof

但是需要注意的是,无论是人工干预还是系统触发,snapshot和rewrite需要逐个被执行

3.4 AOF 的优点

AOF 最大的优点就是他的安全

由于 AOF 机制保证了先写入日志后更新内存,因此可以保证数据的安全性

即使考虑到操作系统的 buffer 缓存,在默认情况下也最多只会丢失一秒的数据

而且文件写入是通过 append 操作,即使写入过程中宕机,也只会丢失本次写入的一个操作,同时,redis-check-aof 工具也可以轻易地修复这种问题,这与依赖 copy on write 的 RDB 机制是完全不同的

同时,rewrite 过程中,新增操作是写回到原 aof 文件的,所以即使宕机也不会有任何影响

另外的一个优势就是 aof 文件格式非常清晰易于理解,十分便于进行日志分析和个性化的回复工作,例如误操作的删除

3.5 AOF 的缺点

恢复速度慢 -- AOF 文件相比 RDB 的持久化文件来说会非常大,恢复速度很慢

运行速度慢 -- 由于每次操作都需要记录,势必影响了 redis 的工作效率

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

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180619G0ZN8000?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券