Redis学习专栏(Redis持久化)

 一. 什么是持久化

持久化,即将数据持久存储,而不因断电或其它各种复杂外部环境影响数据的完整性。由于Redis将数据存储在内存而不是磁盘中,所以内存一旦断电,Redis中存储的数据也随即消失,这往往是用户不期望的,所以Redis用 持久化机制 来保证数据的安全性。

二.持久化机制

Redis的持久化的机制分为两种,分别是 RDB(Redis DataBase)AOF(Append Only File)

1.RDB持久化

RDB是通过保存某个时间点的全量数据快照实现数据的持久化,当恢复数据时,直接通过rdb文件中的快照,将数据恢复。那么就应该有一种触发机制去生成快照,对于RDB来说,提供了三种机制:savebgsave 和 自动化

save机制

阻塞Redis的服务器进程,直到RDB文件被创建完毕。SAVE命令很少被使用,因为其会阻塞主线程来保证快照的写入,而Redis是使用一个主线程来接收所有客户端请求,这样会阻塞所有客户端请求,如下图所示:

bgsave机制

该指令会fork出一个子进程来创建rdb文件,不阻塞服务器进程,子进程接收请求并创建快照,父进程继续接收客户端的请求,如下图所示:

子进程完成文件的创建后会向父进程发送信号,父进程在接收客户端请求的同时,在一定时间间隔内,通过轮询来接收子进程的信号。

我们可以通过使用 lastsave 指令来查看bgsave是否执行成功,lastsave会返回最后一次执行成功bgsave的时间。

基本上 Redis 内部所有的RDB操作都是采用 bgsave 命令来完成,以上两种机制的对比如下:

自动化触发RDB持久化机制

自动触发是由配置文件来完成的,在 redis.conf 配置文件中进行设置:

save:用来配置触发 Redis的 RDB 持久化条件,也就是什么时候将内存中的数据保存到硬盘。比如 save m n 。表示m秒内数据修改n次时,自动触发bgsave机制。

默认如下配置:

#表示900秒内如果至少有1个key的值变化
save 900 1

#表示300秒内如果至少有10个key的值变化
save 300 10

#表示60秒内如果至少有10000个key的值变化
save 60 10000

不需要持久化时,可以注释掉所有的 save 行来停用保存功能。每次执行命令都会将所有redis内存快照保存到一个rdb文件里,并覆盖原有的rdb快照文件。

stop-writes-on-bgsave-error : 当启用了RDB且最后一次后台保存数据失败,Redis是否停止接收数据,默认为yes。这会让用户意识到数据没有正确持久化到磁盘上,Redis重启后,可以重新开始接收数据。

rdbcompression :设置存储到磁盘中的快照是否进行压缩存储,默认为yes。

rdbchecksum:在存储快照后,可以让redis使用CRC64算法来进行数据校验,但是这样做会增加大约10%的性能消耗,如果希望获取到最大的性能提升,可以关闭此功能。

dbfilename:设置快照的文件名,默认是dump.rdb;

dir:设置快照文件的存放路径,该配置项必须是目录,不能是文件名。

RDB方式优点

1、完全备份,不同时间的数据集备份可以做到多版本恢复。

2、对性能影响最小,如上文所述,Redis在保存RDB快照时会fork()出子进程来进行,几乎不影响Redis处理客户端请求的效率。

3、RDB文件为二进制文件,方便网络传输,适合灾难恢复。

4、恢复大数据集速度较AOF快。

RDB方式缺点

1、可能会丢失最近写入,修改而未能持久化的数据。

2、如果数据集较大且CPU不够强,在fork()子进程时会非常耗时,可能会出现毫秒级不能响应客户端请求的情况。

2.AOF持久化

AOF持久化是通过保存Redis的写状态来记录数据库的。

相对RDB来说,RDB持久化是通过备份数据库的状态来记录数据,而AOF持久化是备份数据库接收到的指令,如下图所示:

采用AOF持久方式时,Redis会把所有写操作记录在一个AOF日志文件里。在Redis重启时,会把AOF文件中记录的所有写操作顺序执行一遍,确保数据恢复到最新。

AOF默认是关闭的,若要开启,把配置文件中的 appendonly 修改为yes即可。

AOF机制下将数据写入磁盘有三种写入策略,分别为 always、everysec、no

appendfsync always:服务器每写入一个命令,就调用一次 fdatasync,将数据写入硬盘。在这种模式下,服务器出现故障,也不会丢失任何已经成功执行的数据命令。但是,因为每一个操作就要同步一次,所以速度最慢。

appendfsync everysec(默认):服务器每秒调用一次fdatasync,将数据写入硬盘。这种模式下,服务器出现故障,最多丢失一秒内所执行的命令数据。速度较快。

appendfsync no:服务器不主动调用fdatasync,由操作系统决定何时将数据写入硬盘,速度较快。这种情况下,如果服务器意外停机,丢失命令的数量是不确定的。

随着AOF不断的记录写操作日志,因为AOF所有的操作都会被记录,所以一定会有些无用的日志。比如对一个key修改后又把这个key删了,那么对key修改的这个操作就是无用的日志操作。大量无用的日志会让AOF文件过大,也会让数据恢复的时间过长。

AOF提供了rewrite重写功能,可以重写AOF日志,只保留能把数据恢复到最新状态的最小写操作集。

AOF的优点

1、安全:若开启always,不会丢失任何数据;若开启everysec,最多也就丢失一秒的数据;

2、提供重写机制:优化AOF文件;

3、可恢复性:如果出现误操作(比如flushall等),只要AOF未被重写,停止服务移除AOF文件中的该语句即可。

4、AOF文件在发生断电等问题时也不会损坏,即使出现某条日志只写了一半的情况,也可以使用redis-check-aof工具进行修复。

AOF的缺点

1、相同的数据集,AOF文件体积较RDB文件大了许多。

2、恢复数据库速度比RDB慢。

3、性能消耗比RDB高。

3.RDB-AOF混合持久化方式

redis4.0之后推出了此种持久化方式,使用RDB作为全量备份,AOF作为增量备份,并且将此种方式作为默认方式使用。

在上述两种方式中,RDB方式是将全量数据写入RDB文件,这样写入的特点是文件小,恢复快,但无法保存最近一次快照之后的数据,AOF则将redis指令存入文件中,这样又会造成文件体积大,恢复时间长等弱点。

RDB-AOF方式下,持久化策略首先将缓存中的数据以RDB方式全量写入文件,再将写入后新增的数据以AOF的方式追加在RDB数据的后面,在下一次做RDB持久化的时候将AOF的数据重新以RDB的形式写入文件。

这种方式既可以提高读写和恢复效率,也可以减少文件大小,同时可以保证数据的完整性。在此种策略的持久化过程中,子进程会通过管道从父进程读取增量数据;在以RDB格式保存全量数据时,也会通过管道读取数据,不会造成管道的阻塞。采用此种方式下生成的持久化文件,前半段是RDB格式的全量数据,后半段是AOF格式的增量数据。

RDB-AOF混合持久化方式是目前较为推荐的一种持久化方式。

猜你喜欢

转载自blog.csdn.net/j1231230/article/details/106329071
今日推荐