Redis提供了两种持久化机制,分别是RDB和AOF。

1、RDB(snapshoting,快照)

1.1 RBD是什么及作用:

RBD是什么:
RDB是指在指定的时间间隔中,将内存中的数据集快照写入磁盘,在恢复的时候将快照文件直接读到内存中。是Redis的默认持久化方式。
RDB的作用:
Redis可以通过创建快照来获取存储在内存里的数据在某个时间点上的副本。Redis创建快照后,可以对快照进行备份,也可以将快照复制到其他服务器上来创建具有相同数据的服务器副本(比如Redis主从结构,主要用来提高Redis性能)买还可以将快照留在原地以便重启服务器的时候恢复数据。

1.2 RDB的快照:

RBD的快照是记录某一瞬间的内存数据,记录的是实际数据。Redis的快照是全量快照,每次执行快照,都是把内存中的Redis的所有数据记录到磁盘中。
因此,可以认为,执行RDB快照是一个很重量级的操作,如果频率太过频繁,可能会对Redis性能产生影响;而如果频率太低,服务器发生故障时,丢失的数据会更多。

1.3 RDB是如何进行的:

Redis会单独创建(fork)一个子进程来进行持久化。会先将数据写入到一个临时文件中,等持久化的过程结束了,用这个临时文件,替换上次持久化好的文件。在整个过程中,主进程是不进行任何IO操作的,这就确保了极高的性能。如果需要进行大规模的数据恢复,且对数据恢复的完整性不是非常敏感,那么RDB的方式比AOF方式更高效。
RDB方式最后一次持久化的数据可能丢失。
可以通过lastsave命令获取最后一次成功执行快照的时间。

1.4 RDB文件:

RDB文件的默认文件名为dump.rdb。
在配置文件redis.conf中配置为:
adfilename dump.db
如果我们想修改名字,可以把配置文件redis.conf中这个位置的名字改掉。
rdb文件的保存路径,默认为Redis启动时命令行所在的目录下。

1.5 如何触发生成RBD快照文件:

1、配置文件自动触发:
redis默认的配置文件redis.conf中,有一个自动触发RBD持久化的配置:
save 3600 1 (3600秒内有1个key被修改,触发RBD)
save 360 100 (360秒内有100个key被修改,则触发RDB)
save 60 10000 (60秒内有10000个key被修改,则触发RDB)
使用时可以根据自己的需求按规则配置。同时,当满足任意一个save条件时,都会触发一次bgsave命令进行异步持久化。
如果,把原来的持久化规则注释掉, 配置为空,即save “”,然后把原有的持久化的本地文件删掉,那么就相当于关闭RDB持久化。
2、通过save命令:
save命令是一个同步操作,执行该命令后,RDB持久化是在主进程中进行的,这样会阻塞当前redis服务,直到RDB持久化完成后,客户端才能正常连接redis服务。不建议使用。
3、通过bgsave命令:
bgsave命令是对save命令的一个优化,是一个异步操作。使用这个命令,redis会在后台异步进行快照操作,执行快照的同时还可以相应客户端请求。
执行bgsave命令后,redis主进程会通过fork操作创建一个子进程,RDB持久化由子进程操作,完成后自动结束。这个过程中,主进程不阻塞,可以继续接受客户端的访问。因此,redis内部所有涉及RDB持久化的操作都是采用bgsave方式,save命令基本已经废弃。
image.png
4、执行shutdown命令:
shutdown命令会关闭redis服务器。在关闭之前,首先会停止所有客户端,然后如果配置了save策略(RDB),则会执行一个阻塞的save命令,然后如果配置了AOF,会刷新AOF文件,最后退出当前服务。
5、执行flushall命令:
flushall命令是清空redis内存中的数据,并且同时情况dump.rdb文件。所以这个命令相当于删库跑路。如果之前没有dump文件,那么执行flushall命令后,会生成一个rdb文件,不过这个dump.rdb文件里面是空的,没有意义,就算原本有dump.rdb文件,执行flushall之后也会清空。

2、AOF方式持久化

2.1 AOF是什么及作用、如何开启

AOF(append only file,只追加文件)是redis提供的另一种持久化方式。AOF以日志的形式来记录客户端对redis服务端的每一个写操作(增量保存),并把这些写操作以redis协议追加保存到后缀为aof的文件的末尾。在redis服务器重启时,会读取并加载aof文件,达到恢复数据的目的。
AOF持久化方式redis默认不开启,可以通过修改配置文件来开启AOF:
配置文件redis.conf中
appendonly no
no是默认值,改为yes即可开启持久化方式。AOF默认的文件名为appendonly.aof,也可以通过appendfilename配置修改。
appendonly.aof文件网上说在根目录,可以通过修改redis.conf,指定文件目录和文件名,重启后文件出现:

  1. # 指定文件夹路径
  2. dir "/usr/local/redis/bin"
  3. # 指定文件名
  4. appendonly.aof "appendonly.aof"

这里dir默认配置为 dir ./

2.2 AOF的三种持久化策略

  • appendfsync always:每次有修改发生时,都会写入AOF文件,这样会严重降低Redis的速度;
  • appendfsync ererysec:每秒钟同步一次,显示地将多个命令同步到硬盘;理论上,这种方式最多只丢失一秒钟内的数据。
  • appendfsync no:让操作系统决定何时进行同步。这种方式是最快的一种策略,但是丢失数据的可能性非常大,不推荐使用。

—>为了兼顾数据和写入性能,推荐使用appendfsync everysec策略,让redis每秒同步一次aof文件,这样对redis性能影响很小,而且这样即使系统出现崩溃,也最多丢失一秒内产生的数据。

2.3 AOF持久化流程

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

2.4 AOF文件重写(文件压缩)

AOF采用文件追加方式,文件会越来越大。尤其是我们对同一个key做多次写操作时,就会擦火山泥哼大量针对同一个key操作的日志指令。这样恢复数据就会变得非常慢。
因此,Redis提供了重写机制来解决这个问题。Redis通过重写AOF文件,保存的只是恢复数据的最小指令级。
Redis会记录上次重写时AOF文件的大小,默认配置是当AOF文件是上rewrite后大小的一倍,且文件大于64mb时触发。
如何触发重写:

  • 手动执行bgrewriteaof命令,以此手动触发重写。
  • 修改配置文件触发重写:

配置文件中,有下面部分:

  1. auto-aof-rewrite-percentage 100
  2. auto-aof-rewrite-min-size 64mb
  1. auto-aof-rewirte-percentage 100; 文件达到100%时重写。即:当文件大小达到原先文件大小的两倍。原先文件是指上次重写后的文件大小,如果没有重写过,那就是redis服务启动时的文件大小。<br />auto-aof-rewrite-min-size: 64mb; 这时文件重写的最小文件大小,即当AOF文件小于64mb时,不会触发重写。<br />只有这两个指标同时满足的时候才会重写。<br />**重写的流程:**
  1. bgrewriteaof命令触发重写,判断是否存在bgsave或者bgrewriteaof正在执行,如果存在就等待其执行结束后在执行;
  2. 主进程fork子进程,防止主进程阻塞无法提供服务;
  3. 子进程遍历redis内存中的数据写入临时AOF文件,客户端的写操作同时写入aof_buf和aof_rewrte_buf两个重写缓冲区。aof_buf缓冲区是为了写回旧的AOF文件,aof_rewrite_buf是为了后续刷新到临时AOF文件中吗,防止内存遍历时新的写入操作丢失。这两个缓冲区就是为了保证原本的AOF文件的完整,以及新的AOF文件生成期间的新的数据修改动作不会丢失。
  4. 子进程写完临时AOF文件后,通知主进程;
  5. 主进程会将aof_write_buf缓冲区中的数据写入到子进程生成的临时AOF文件中;
  6. 主进程使用临时AOF文件替换旧的AOF文件,完成整个重写过程。

重写要注意的问题:
某些场景下,AOF文件格式可能会发生错误,导致 redis不能识别里面的数据,例如文件写到一半宕机了,或者人为不小心标记了aof文件内从等。针对这种情况,redis提供了一个命令来解决这种异常:
redis-check-aof —fix appendonly.aof
在执行这个命令前,最好先备份一下aof文件,以防万一。

3 RDB和AOF的优劣对比及去和选择

首先,官方推荐两个都启用。(两个都启用时,redis会默认读取AOF的数据)。
如果对数据不敏感,可以单独选用RDB;
官方说不要只使用AOF,可能有潜在的BUG;
如果只做纯内存缓存,可以都不用;

RDB的优缺点:
优点:

  1. RDB文件非常紧凑,节省内存空间;
  2. RDB在恢复大数据集时速度比AOF要快;
  3. 适合全量备份,全量复制的场景,经常用于灾难恢复(在对数据的完整性和一致性要求相对较低的场合)

缺点:

  1. 服务器宕机时,可能会丢失部分数据;
  2. 每次保存RDB快照时,redis都要创建出一个紫禁城,这个过程是阻塞的,如果数据集巨大,那么阻塞的时间就会很长。

AOF的优缺点:
优点:

  1. 数据更加完整,丢失数据的可能性较低;
  2. AOF日志文件刻度,并且可以对AOF文件修复(可以处理误操作);

缺点:

  1. AOF日志在长期运行中主逐渐庞大,恢复起来非常耗时,需要定期对AOF文件进行压缩处理;(相比RDB占用更多磁盘空间)
  2. 恢复备份速度比较慢。