redis作为单线程的内存数据库在满足性能的同时,也需要持久化机制防止数据的丢失,特别对数据的安全性要求比较高的业务而言,持久化机制是必不可少的,所以redis提供了RDB(Redis Data Base)和AOF(Append-only file)两种持久化机制。

1、RDB

    RDB就是在redis运行时,在特点的时间间隔内生成数据集的时间点快照。那么什么情况下回触发快照机制呢?

    1、可以在redis.conf配置文件中配置 save <seconds> <changes> ,即在多少秒时间内更改的数据量大于changes的时间执行快照机制。

    2、在执行redis的server命令 save和bgsave的时候。前者执行同步数据到磁盘的时候会阻塞用户端的情况,而后者不会。

    3、执行flushall的时候,清除内存中所有的数据,并且若redis.cof中配置了save 参数则就会执行快照机制。

    RDB是一个非常紧凑的快照文件,非常适合用于备份和数据的容灾(可以定时对数据进行快照备份),默认情况下该文件为bin目录下的dump.rdb。而执行机制是redis会fork出一个子进程,子进程会完成RDB文件的保存。父进程不会有任何的磁盘IO操作。但是若数据量比较大时可能会造成多少毫秒(大的时候会到一秒钟)内不能处理客户端请求。并且若服务故障则在执行fork期间(可能会几分钟)的数据则会发生丢失,所以这完全取决于服务本身的数据重要性。

    所以RDB的优点就是方便定时备份数据,缺点就是可能发生数据的丢失。

2、AOF

    AOF机制则会记录下redis在某一时间段内执行过的所有命令,并且以append的形式加入到指定的aof文件当中。需要在配置文件redis.conf进行配置

    1、开启AOF机制:appendonly yes

    2、aof文件地址:默认会在bin目录下生成appendonly.aof文件,可以使用appendfilename进行配置

    3、auto-aof-rewrite-percentage 100 表示aof文件大小超过上一次执行aof文件的百分之多少的时候触发,默认100表示为上一次的两倍

    4、auto-aod-rewrite-min-size 64m 表示运行重写最小aof文件的大小,即触发aof后发现文件大小小于该数后将不需要执行

    AOF机制解决了RDB缓存机制可能会丢失数分钟的数据的问题,会将所有的执行过的命令都记录到一个append的文化当中,那么对于redis的性能方面多少是有影响的(可以使用ssd降低这种影响)。但是将内存中的所有命令都同步到文件中,其中间有几个环节需要注意:

    1、首先肯定是redis记录了所有的命令,而其实我们在某一时间节点下只需要关注该节点的数据情况,并不需要关心执行的过程,如:对一个key进行了100次修改就会有100条记录,那么我们只会关心其最后的值即可(即有99条记录完全可以删除,数据恢复时直接赋值最后的状态)。则需要触发rewrite机制执行该操作,重写后的aof文件将是恢复前所有数据的最小命令集合。并整改过程是觉得安全的,因为在创建新的aof文件的过程中会继续将执行的命令追加到aof文件当中,即使在发生重写的过程当中发生服务器停机现有的aof文件也不会丢失。而一旦新的aof文件创建完成,redis就会从旧的aof文件切换到新的aof文件,并继续接受新的命令。

    2、在持久化的过程当中,首先会将数据持久化到磁盘缓冲区中并定时将缓冲区的数据刷新到磁盘中,才会完成整个过程。那么多久刷新一次缓冲器则需要在redis.conf中进行配置:

        1)、appendfsync always 每次执行写入操作都会执行rewrite操作,保证数据的绝对安全但是对性能的影响比较大

        2)、appendfsync everysec 每秒中同步一次,就即使服务不可用也就是丢失一秒钟的数据

        3)、appendfsync no 不主动进行同步,完全由操作系统决定。

    3、aof文件在将命令append到文件中时不会对命令本身进行检查,那么若磁盘写满、写入中途停机等都可能会造成写入的命令不完整,那么在重启服务的时候会拒绝载入aof文件,则需要将对文件进行修复。修复之前一般会对其进行备份,然后执行bin目录下的 redis-check-aof --fix 进行修复,再启动redis服务。

    4、aof只会文件保存写入的操作命令是redis协议的格式,其特点是易读,方便进行分析。若不小心执行了flushall命令,并且未做其他操作的情况下,则可以打开aof文件本身,删除flushall的命令(如还有其他操作,则该命令不会在最后,找到并删除它也可以),并重启服务即可。

    5、aof文件本身一般都会比rdb文件大,并且恢复数据的速度也会比rdb慢,只有在关闭rewrite功能的情况下aof的速度才会赶上rdb机制,至于慢多少完全取决于刷新的机制的执行间隔。并且之前发生过由于阻塞命令brpoplpush命令导致aof文件载入是无法恢复成保存时候的样子的情况(算是bug)。

    所以AOF的优点就是能完全保证数据的不丢失,缺点就是性能会差一点(但是是值得的),还要存在一些bug隐患。

3、应该如何选择

    那么基于以上对于两张持久化机制的特性和优缺点分析,该怎么样选择持久化策略完全取决于应用业务本身的数据的重要性。若要求特别高的情况下同时启用两种机制也是完全可以的(若两种机制都启用,redis服务重启时默认会加载aof文件数据到redis内存中)。若只开启aof以保证数据不会数分钟的丢失,那么可能发生之前说的概率较小的aof bug 的隐患,并且定时对数据进行容灾备份也是比较不错的选择。