当前位置 博文首页 > 盛夏温暖流年:Redis学习专栏(Redis持久化)

    盛夏温暖流年:Redis学习专栏(Redis持久化)

    作者:[db:作者] 时间:2021-07-13 19:03

    ?一. 什么是持久化

    持久化,即将数据持久存储,而不因断电或其它各种复杂外部环境影响数据的完整性。由于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混合持久化方式是目前较为推荐的一种持久化方式。

    cs