Redis系列(十)、详解Redis持久化方式AOF、RDB以及混合持久化

目录

介绍

RDB

介绍

配置

使用

AOF

介绍

配置

重写

使用

AOF和RDB的区别

RDB优缺点

AOF优缺点

AOF和RDB的恢复顺序

AOF+RDB混合[推荐]

介绍

配置

使用


之前介绍Redis特点的时候其中有一条是Redis支持数据持久化,可以将内存中的数据持久化到磁盘中,重启的时候再次加载使用。Redis4之前的数据持久化有AOF和RDB两种,从Redis4之后新增了AOF+RDB混合持久化的方式,本篇就Redis的三种数据持久化的方式进行详细介绍以及他们的场景和区别。

Redis系列文章:

Redis系列(一)、CentOS7下安装Redis6.0.3稳定版

Redis系列(二)、数据类型之字符串String 

Redis系列(三)、数据类型之哈希Hash

Redis系列(四)、数据类型之列表List

Redis系列(五)、数据类型之无序集合Set

Redis系列(六)、数据类型之有序集合ZSet(sorted_set)

Redis系列(七)、常用key命令

Redis系列(八)、常用服务器命令 

Redis系列(九)、Redis的“事务”及Lua脚本操作


介绍

上面提到Redis持久化存储有两种持久化方案,RDB(Redis DataBase)和 AOF(Append-Only File)。其中RDB是将内存中的数据进行快照存储到磁盘,AOF则为可回放的命令日志记录redis内的所有操作。它们各有特点也相互独立。Redis4之后支持RDB-AOF混合持久化的方式,结合了两者的优点,可以通过 aof-use-rdb-preamble 配置项可以打开混合开关。

RDB

介绍

RDB(Redis DataBase)是将Redis内存中的数据进行Snaptshot快照存储在磁盘内,是Redis的默认持久化方案。使用RDB持久化默认有三种策略,该持久化策略在redis.conf中可配置,会以一段时间内有指定次数据修改的规则触发快照动作,快照文件名为dump.rdb,该文件默认使用LZF压缩算法 。每当Redis服务重启的时候会从该文件中加载数据进内存。

RDB持久化除了可以根据配置中的策略触发,也可以手动触发,使用save和bgsave命令即可。这两个命令的区别的save会阻塞服务器进程,在进行save的过程中,服务器不能处理任何请求,而bgsave会通过一个子进程在后台处理rdb持久化。事实上save和bgsave调用的都是rdbSave函数,因此Redis不允许save和bgsave同时运行,这也是为了避免出现竞争导致rdb文件数据不准确。

bgsave操作使用CopyOnWrite机制进行写时复制,是由一个子进程将内存中的最新数据遍历写入临时文件,此时父进程仍旧处理客户端的操作,当子进程操作完毕后再将该临时文件重命名为dump.rdb替换掉原来的dump.rdb文件,因此无论bgsave是否成功,dump.rdb都不会受到影响。

另外在主从全量同步、debug reload以及shutdown的情况下也会触发RDB数据持久化。

配置

我们可以修改redis.conf文件中的SNAPSHOTTING中修改RDB的默认持久化策略。

vim $REDIS_HOME/bin/redis.conf

#RDB持久化策略 默认三种方式,[900秒内有1次修改],[300秒内有10次修改],[60秒内有10000次修改]即触发RDB持久化,我们可以手动修改该参数或新增策略
save 900 1
save 300 10
save 60 10000

#RDB文件名
dbfilename "dump.rdb"
#RDB文件存储路径
dir "/opt/app/redis6/data"

策略配置:

#在seconds秒内有changes次数据修改就触发RDB持久化
save <seconds> <changes>

使用

执行save/bgsave前后 rdb文件被更新: 

将rdb文件备份后重启服务,数据没了,关闭服务将备份文件改回来,数据又回来了: 

AOF

介绍

AOF(Append-Only File)记录Redis中每次的写命令,类似mysql中的binlog,服务重启时会重新执行AOF中的命令将数据恢复到内存中,RDB(按策略持久化)持久化方式记录的粒度不如AOF(记录每条写命令),因此很多生产环境都是开启AOF持久化。

AOF中记录了操作和数据,在日志文件中追加完成后才会将内存中的数据进行变更。

AOF持久化流程

  1. 客户端的请求写命令会被append追加到AOF缓冲区内;
  2. AOF缓冲区根据AOF持久化策略[always,everysec,no]将操作sync同步到磁盘的AOF文件中;
  3. AOF文件大小超过重写策略或手动重写时,会对AOF文件rewrite重写,压缩AOF文件容量;
  4. Redis服务重启时,会重新load加载AOF文件中的写操作达到数据恢复的目的;

配置

开启了AOF之后,RDB就默认不使用了。使用下面的配置开启AOF以及策略。(如果使用AOF,推荐选择always方式持久化,否则在高并发场景下,每秒钟会有几万甚至百万条请求,如果使用everysec的方式的话,万一服务器挂了那几万条数据就丢失了):

vim $REDIS_HOME/bin/redis.conf

#开启AOF持久化
appendonly yes

#AOF文件名
appendfilename "appendonly.aof"

#AOF文件存储路径 与RDB是同一个参数
dir "/opt/app/redis6/data"

#AOF策略,一般都是选择第一种[always:每个命令都记录],[everysec:每秒记录一次],[no:看机器的心情高兴了就记录]
appendfsync always
#appendfsync everysec
# appendfsync no


#aof文件大小比起上次重写时的大小,增长100%(配置可以大于100%)时,触发重写。[假如上次重写后大小为10MB,当AOF文件达到20MB时也会再次触发重写,以此类推]
auto-aof-rewrite-percentage 100 

#aof文件大小超过64MB时,触发重写
auto-aof-rewrite-min-size 64mb 

重写

AOF持久化机制记录每个写命令,当服务重启的时候会复现AOF文件中的所有命令,会消耗太多的资源且重启很慢。因此为了避免AOF文件中的写命令太多文件太大,Redis引入了AOF的重写机制来压缩AOF文件体积。AOF文件重写是把Redis进程内的数据转化为写命令同步到新AOF文件的过程。

重写会根据重写策略或手动触发AOF重写。

重写流程

  1. bgrewriteaof触发重写,判断是否当前有bgsave或bgrewriteaof在运行,如果有,则等待该命令结束后再继续执行。
  2. 主进程fork出子进程执行重写操作,保证主进程不会阻塞。
  3. 子进程遍历redis内存中数据到临时文件,客户端的写请求同时写入aof_buf缓冲区和aof_rewrite_buf重写缓冲区 保证原AOF文件完整以及新AOF文件生成期间的新的数据修改动作不会丢失。
  4. 1).子进程写完新的AOF文件后,向主进程发信号,父进程更新统计信息。2).主进程把aof_rewrite_buf中的数据写入到新的AOF文件。
  5. 使用新的AOF文件覆盖旧的AOF文件,完成AOF重写。

使用

修改redis.conf文件开启AOF之后,AOF文件为空,此时如果重启Redis服务会从AOF中复现数据,因此之前使用RDB持久化的数据都看不到了。因此我们可以使用另一种方式开启AOF持久化,也可以将当前RDB中的数据缓存到aof文件中。

AOF文件为文本格式存储,可以使用cat命令查看。

在redis.conf中开启AOF,RDB中的数据丢失了:

在命令行中热修改配置开启AOF,可以将RDB中的数据持久化到AOF文件中:

重写:

如果AOF文件遇到格式或编码错误可使用 redis-check-aof 命令修复AOF文件:

#修复
$REDIS_HOME/bin/redis-check-aof --fix $REDIS_HOME/data/appendonly.aof 

 

使用下面的命令查看aof持久化情况:

info persistence

 

AOF和RDB的区别

RDB优缺点

优点

  1. 压缩后的二进制文件,适用于备份、全量复制及灾难恢复
  2. RDB恢复数据性能优于AOF方式

缺点

  1. 无法做到实时持久化,每次都要创建子进程,频繁操作成本过高
  2. 保存后的二进制文件,不同版本直接存在兼容性问题

AOF优缺点

优点

  1. 以文本形式保存,易读
  2. 记录写操作保证数据不丢失

缺点

  1. 存储所有写操作命令,且文件为文本格式保存,未经压缩,文件体积高
  2. 恢复数据时重放AOF中所有代码,恢复性能弱于RDB方式

AOF和RDB的恢复顺序

当Redis服务重启时数据恢复的顺序如下:

  1. 判断是否开启AOF持久化,若开启了AOF,则使用AOF持久化文件恢复数据,否则使用RDB持久化文件恢复数据;
  2. 若AOF文件不存在则从RDB文件恢复其实并没有】;若AOF文件存在则使用AOF文件恢复;
  3. 若AOF文件和RDB文件都不存在则直接启动Redis;
  4. 若AOF或RDB文件出现错误,则启动失败返回错误信息;

AOF+RDB混合[推荐]

介绍

看了上面的RDB和AOF的介绍后,我们可以发现,使用RDB持久化会有数据丢失的风险,但是恢复速度快,而使用AOF持久化可以保证数据完整性,但恢复数据的时候会很慢。于是从Redis4之后新增了混合AOF和RDB的模式,先使用RDB进行快照存储,然后使用AOF持久化记录所有的写操作,当重写策略满足或手动触发重写的时候,将最新的数据存储为新的RDB记录。这样的话,重启服务的时候会从RDB何AOF两部分恢复数据,即保证了数据完整性,又提高了恢复的性能。

开启混合模式后,每当bgrewriteaof命令之后会在AOF文件中以RDB格式写入当前最新的数据,之后的新的写操作继续以AOF的追加形式追加写命令。当redis重启的时候,加载 aof 文件进行恢复数据:先加载 rdb 的部分再加载剩余的 aof部分。

配置

修改下面的参数即可开启AOF,RDB混合持久化:

vim $REDIS_HOME/bin/redis.conf 

aof-use-rdb-preamble yes

使用

开启混合持久化模式后,重写之后的aof文件里和rdb一样存储二进制的 快照数据,继续往redis中进行写操作,后续操作在aof中仍然是以命令的方式追加。因此重写后aof文件由两部分组成,一部分是类似rdb的二进制快照,另一部分是追加的命令文本:

 

希望本文对你有帮助,请点个赞鼓励一下作者吧~ 谢谢!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章