• 极客文库-知识库上线!
  • 极客文库小编@勤劳的小蚂蚁,为您推荐每日资讯,欢迎关注!
  • 每日更新优质编程文章!
  • 更多功能模块开发中。。。

进阶的Redis之数据持久化RDB与AOF

大家都知道,Redis 之所以性能好,读写快,是因为Redis是一个内存数据库,它的操作都几乎基于内存。但是内存型数据库有一个很大的弊端,就是当数据库进程崩溃或系统重启的时候,如果内存数据不保存的话,里面的数据就会丢失不见了。这样的数据库并不是一个可靠的数据库。
所以数据的持久化是内存型数据库的重中之重。它不仅提供数据保存硬盘的功能,还可以借此用硬盘容量扩展数据存储空间,使得Redis的可以存储超过机器本身内存大小的数据。
Redis对于数据持久化提供了两种持久化的方案,RDB 与 AOF。它们的原理和使用场景都大不相同,下面我们来详细地了解下。
RDB—数据快照(Snapshot)
RDB,提供一个某个时间点的数据的 Snapshot,保存在 RDB 文件中。它可以通过SAVE/BGSAVE命令手动执行,把数据 Snapshot 写到 RDB 文件,也可以通过配置,定时执行。
Redis也可以通过加载 RDB 文件,把数据从磁盘加载读取到Redis中。
RDB 文件创建
连上Redis,设值一些值,然后执行SAVE命令。
然后可以查看下 redis.conf 的持久化工作目录。进入目录可以看到保存了一个 dump.rdb 文件。该文件是一个二进制文件,无法直接正常打开。
至于SAVE/BGSAVE的区别,就是前置是阻塞执行,此时服务不会接受请求,后者是 Fork 一个子进程出来,由该进程去执行保存 RDB 文件的操作,不影响用户请求。
P.S. Redis 是单进程的,所以BGSAVE只能 Fork 一个子进程,而不是创建一个线程处理。
以上是手动执行的过程。但在生产我们很少会手动登上服务去执行操作,所以更多的时候是依赖 Redis 的配置,定时保存 RDB 文件。
打开redis.conf配置文件,找到SNAPSHOTTING的配置,Save Point 的设置。
图中的配置意思是,当至少有一个 key 变更时,900 秒后会执行一次 SAVE。其他配置同理,有 10 次变更,300 秒后保存一次…..
在 Redis 中,这个自动保存 RDB 的功能是默认开启的。
RDB 文件加载
先 kill 掉 Redis 进程,再重新启动 Redis Server,会发现日志会有这样的一行,
并且 Redis 中,依然有之前设置的三个值。说明 Redis 在启动的时候,会加载数据初始化。
不过,这里加载的初始化数据不一定是 RDB 的。如果 Redis 开启了 AOF,会优先从 AOF 初始化数据,否则才会加载 RDB 的数据。
RDB 优缺点
优点
RDB 是某一时间点的快照,是一个紧凑的单文件,更多用于数据备份。可以按每小时或每日来备份,方便从不同的版本恢复数据。
单文件容易传输到远程服务做故障恢复。
RDB 可以 Fork 子进程进行持久化,使 Redis 可以更好地处理用户请求。
在大量数据的情况下,RDB 相比较于 AOF 会更快的加载。

缺点
如果 Redis 不及时保存 RDB 文件,会造成数据的丢失。例如系统突然断电,但未来得及保存数据。即使你设置更多的 Save point,也无法保证 100%的数据不丢失。
RDB 经常需要 fork 子进程去执行,但如果再大量数据的情况下,这个 fork 操作会非常耗 CPU 资源的。对比 AOF 虽然也是 fork,但是它的数据保存处理是可以控制的,不需要全量保存。
AOF—日志追加
Redis 的另外一种持久化方案就是 AOF,Append Only File。AOF 相当于一个操作的日志记录,每次对于数据的变更都会记录追加到 AOF 日志。当服务启动的时候就会读这些操作日志,重新执行一次操作,从而恢复原始数据。
AOF 启用
AOF 默认是关闭的。打开 redis.conf 配置文件,找到appendonly no改成appendonly yes
AOF 和 RDB 是可以共存的,只要保存的文件名不冲突。
fsync 同步规则
配置文件往下拉,看到fsync的配置。
fsync()是一个系统调用函数,告诉操作系统把数据写到硬盘上,而不是缓存更多数据才写到硬盘。这样的调用可以及时保存数据到硬盘上。
Redis 提供了三种 fsync 的调用方式
  • appendfsync always,每次操作记录都同步到硬盘上,最低效,最安全。
  • appendfsync everysec,每秒执行一次把操作记录同步到硬盘上。默认选项。
  • appendfsync no,不执行 fysnc 调用,让操作系统自动操作把缓存数据写到硬盘上,不可靠,但最快。
AOF 文件格式解析
开启 AOF 后,会再工作目录看到appendonly.aof文件。
在客户端上执行一些命令后,打开 AOF 文件,可以观察到有对应的操作的记录日志。
文件解析说明:
  • *,表示命令的参数个数,例如set a 1是三个参数,所以是*3
  • $,表示参数的字节数,例如set这个参数是三字节,所以是$3,key 值 a 是一个字节,所以是$1
  • 无符号,表示是参数的数据,例如set,a,1就是具体的数据
AOF 日志重写
AOF 虽然比 RDB 更可靠,但缺点也是比较明显的,就是每次写操作都要把操作日志写到文件上,这样会导致文件非常冗余。
假若你要自增一个计数器 100 次,如果不重写,AOF 文件就就会有这 100 次的自增记录,如INCR a。如果执行了日志重写,那么文件只会保留set a 100而不是 100 条INCR a。这样拥有相同的结果,但可以大大减少 AOF 的文件大小,并且可以让 AOF 载入的时候提升载入的效率。
看回redis.conf配置,有两项控制 rewrite 的选项。
  • auto-aof-rewrite-percentage 100,当文件增长 100%(一倍)时候,自动重写。
  • auto-aof-rewrite-min-size 64mb,日志重写最小文件大小,如果小于该大小,不会自动重写。

来实验一下重写的结果,我们先设定一个 a 值,然后自增多次,查看 AOF 文件内容。里面有很多 INCR 的语句记录。
然后我们手动执行下BGREWRITEOF,执行日志重写。
可以看到,多个 incr 语句,变成了一个set a 6语句,减少了 5 个incr a语句的操作日志。
AOF 优缺点
优点
AOF 可以设置 完全不同步、每秒同步、每次操作同,默认是每秒同步。因为 AOF 是操作指令的追加,所以可以频繁的大量的同步。
AOF 文件是一个值追加日志的文件,即使服务宕机为写入完整的命令,也可以通过 redis-check-aof 工具修复这些问题。
如果 AOF 文件过大,Redis 会在后台自动地重写 AOF 文件。重写后会使 AOF 文件压缩到最小所需的指令集。
AOF 文件是有序保存数据库的所有写入操作,易读,易分析。即使如果不小心误操作数据库,也很容易找出错误指令,恢复到某个数据节点。例如不小心 FLUSHALL,可以非常容易恢复到执行命令之前。

缺点
相同数据量下,AOF 的文件通常体积会比 RDB 大。因为 AOF 是存指令的,而 RDB 是所有指令的结果快照。但 AOF 在日志重写后会压缩一些空间。
在大量写入和载入的时候,AOF 的效率会比 RDB 低。因为大量写入,AOF 会执行更多的保存命令,载入的时候也需要大量的重执行命令来得到最后的结果。RDB 对此更有优势。
如何选择
以上已经基本了解过 RDB 和 AOF 的使用、基本原理以及对应的优缺点。那么在实际当中,我们到底怎么去选择用哪种持久化方式呢?
一般来说,不考虑硬盘大小,最安全的做法是 RDB 与 AOF 同时使用,即使 AOF 损坏无法修复,还可以用 RDB 来恢复数据。
如果 Redis 的数据在你的服务中并不是必要的数据,例如只是当简单的缓存,没有缓存也不会造成缓存雪崩。说明数据的安全可靠性并不是首要考虑范围内,那么单独只使用 RDB 就可以了。
不推荐单独使用 AOF,因为 AOF 对于数据的恢复载入来说,比 RDB 慢。并且 Redis 官方也说明了,AOF 有一个罕见的 bug。出了问题无法很好的解决。所以使用 AOF 的时候,最好还是有 RDB 作为数据备份。

根据官方的意愿描述,在未来可能会有一种 RDB 与 AOF 相结合的持久化模型。到时 Redis 持久化就不再如此麻烦费劲了,我们拭目以待吧。


丨极客文库, 版权所有丨如未注明 , 均为原创丨
本网站采用知识共享署名-非商业性使用-相同方式共享 3.0 中国大陆许可协议进行授权
转载请注明原文链接:进阶的 Redis 之数据持久化 RDB 与 AOF
喜欢 (0)
[247507792@qq.com]
分享 (0)
勤劳的小蚂蚁
关于作者:
温馨提示:本文来源于网络,转载文章皆标明了出处,如果您发现侵权文章,请及时向站长反馈删除。

欢迎 注册账号 登录 发表评论!

  • 精品技术教程
  • 编程资源分享
  • 问答交流社区
  • 极客文库知识库

客服QQ

247507792

工作时间:09:00-23:00

新浪微博:点我访问

个人博客:点我访问