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

你们都知道,Redis之因此性能好,读写快,是由于Redis是一个内存数据库,它的操做都几乎基于内存。可是内存型数据库有一个很大的弊端,就是当数据库进程崩溃或系统重启的时候,若是内存数据不保存的话,里面的数据就会丢失不见了。这样的数据库并非一个可靠的数据库。redis

因此数据的持久化是内存型数据库的重中之重。它不只提供数据保存硬盘的功能,还能够借此用硬盘容量扩展数据存储空间,使得Redis的能够存储超过机器自己内存大小的数据。数据库

Redis对于数据持久化提供了两种持久化的方案,RDB与AOF。它们的原理和使用场景都大不相同,下面咱们来详细地了解下。缓存

RDB——数据快照(Snapshot)

RDB,提供一个某个时间点的数据的Snapshot,保存在RDB文件中。它能够经过SAVE/BGSAVE命令手动执行,把数据Snapshot写到RDB文件,也能够经过配置,定时执行。安全

Redis也能够经过加载RDB文件,把数据从磁盘加载读取到Redis中。微信

RDB文件建立

连上Redis,设值一些值,而后执行SAVE命令。 app

而后能够查看下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优缺点

优势:

  1. RDB是某一时间点的快照,是一个紧凑的单文件,更多用于数据备份。能够按每小时或每日来备份,方便从不一样的版本恢复数据。
  2. 单文件容易传输到远程服务作故障恢复。
  3. RDB能够Fork子进程进行持久化,使Redis能够更好地处理用户请求
  4. 在大量数据的状况下,RDB相比较于AOF会更快的加载。

缺点:

  1. 若是Redis不及时保存RDB文件,会形成数据的丢失。例如系统忽然断电,但将来得及保存数据。即便你设置更多的Save point,也没法保证100%的数据不丢失。
  2. RDB常常须要fork子进程去执行,但若是再大量数据的状况下,这个fork操做会很是耗CPU资源的。对比AOF虽然也是fork,可是它的数据保存处理是能够控制的,不须要全量保存。

AOF——日志追加(Append-Only)

Redis的另一种持久化方案就是AOF,Append Only File。AOF至关于一个操做的日志记录,每次对于数据的变动都会记录追加到AOF日志。当服务启动的时候就会读这些操做日志,从新执行一次操做,从而恢复原始数据。

AOF启用

AOF默认是关闭的。打开redis.conf配置文件,找到appendonly no改为appendonly yes

AOF和RDB是能够共存的,只要保存的文件名不冲突。

AOF 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虽然比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优缺点

优势:

  1. AOF能够设置 彻底不一样步、每秒同步、每次操做同,默认是每秒同步。由于AOF是操做指令的追加,因此能够频繁的大量的同步。
  2. AOF文件是一个值追加日志的文件,即便服务宕机为写入完整的命令,也能够经过redis-check-aof工具修复这些问题。
  3. 若是AOF文件过大,Redis会在后台自动地重写AOF文件。重写后会使AOF文件压缩到最小所需的指令集。
  4. AOF文件是有序保存数据库的全部写入操做,易读,易分析。即便若是不当心误操做数据库,也很容易找出错误指令,恢复到某个数据节点。例如不当心FLUSHALL,能够很是容易恢复到执行命令以前。

缺点

  1. 相同数据量下,AOF的文件一般体积会比RDB大。由于AOF是存指令的,而RDB是全部指令的结果快照。但AOF在日志重写后会压缩一些空间。
  2. 在大量写入和载入的时候,AOF的效率会比RDB低。由于大量写入,AOF会执行更多的保存命令,载入的时候也须要大量的重执行命令来获得最后的结果。RDB对此更有优点。

如何选择

以上已经基本了解过RDB和AOF的使用、基本原理以及对应的优缺点。那么在实际当中,咱们到底怎么去选择用哪一种持久化方式呢?

通常来讲,不考虑硬盘大小,最安全的作法是RDB与AOF同时使用,即便AOF损坏没法修复,还能够用RDB来恢复数据。

若是Redis的数据在你的服务中并非必要的数据,例如只是当简单的缓存,没有缓存也不会形成缓存雪崩。说明数据的安全可靠性并非首要考虑范围内,那么单独只使用RDB就能够了。

不推荐单独使用AOF,由于AOF对于数据的恢复载入来讲,比RDB慢。而且Redis官方也说明了,AOF有一个罕见的bug。出了问题没法很好的解决。因此使用AOF的时候,最好仍是有RDB做为数据备份。

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

更多技术文章、精彩干货,请关注
博客:zackku.com
微信公众号:Zack说码

相关文章
相关标签/搜索