深入理解Redis--RDB和AOF

        Redis是一个No-SQ缓存数据库,数据保存在内存中,由于读写频繁,或在出现宕机等等异常情况,数据往往会丢失。不用担心,Redis给我们提供了持久化的机制,分别是RDB(Redis DataBase)和AOF(Append Only File)。

一、持久化流程

(1)客户端向服务端发送写操作(数据在客户端的内存中)。

(2)数据库服务端接收到写请求的数据(数据在服务端的内存中)。

(3)服务端调用write这个系统调用,将数据往磁盘上写(数据在系统内存的缓冲区中)。

(4)操作系统将缓冲区中的数据转移到磁盘控制器上(数据在磁盘缓存中)。

(5)磁盘控制器将数据写到磁盘的物理介质中(数据真正落到磁盘上)。

 以上是正常的保存流程,但是在大多数情况下,我们的机器会出现不同的故障,这里划分了两种情况:

(1)Redis数据库发生故障,只要在上面的第三步执行完毕,那么就可以持久化保存,剩下的两步由操作系统替我们完成。

(2)操作系统发生故障,必须上面5步都完成才可以。

二、RDB机制

     RDB其实就是把数据以快照的形式保存在磁盘上。什么是快照呢,你可以理解成把当前时刻的数据拍成一张照片保存下来。

     RDB持久化是指在指定的时间间隔内,将内存中的数据集以快照的形式,写入磁盘。也是默认的持久化方式,这种方式是就是将内存中数据以快照的方式写入到二进制文件中,默认的文件名为dump.rdb。在redis.conf文件中,有RDB和AOF两种持久化机制的各种配置。

      既然RDB机制是通过把某个时刻的所有数据生成一个快照来保存,那么就应该有一种触发机制,是实现这个过程。对于RDB来说,提供了三种机制:save、bgsave、自动触发。

1、Save触发方式

    该命令会阻塞当前Redis,然后执行Save命令,期间无法使用Redis其他命令,RDB过程完成之后自动释放,这种方式局限性比较大,基本不会使用到,他会严重影响其他客户端使用。如下图:

2、Bgsave触发方式

     执行该命令时,Redis会异步执行快照操作,同时也能处理客户端发送过来的请求。如下图:

     具体流程:Redis进程执行fork操作,创建子进程,RDB持久化(快照)操作交由子进程负责,完成后自动结束。在fork阶段,Redis会发生阻塞,一般时间很短,(下篇文章会讲到Redis fork优化),正常都采取这种方式进行RDB持久化。

Save和Bgsave对比:

3、自动触发

     通过配置redis.conf文件,进行触发设置,以下主要配置.

(1)save:配置触发 Redis的 RDB 持久化条件,主要是多少时间段内,KEY的变化,然后触发保存操作 。“save x y”,x 为时间,y为key值变化次数。以下三Redis默认配置:

save 900 1  、save 300 10、save 60 10000

(2)stop-writes-on-bgsave-error:设置了对Redis服务器和持久性的监视,默认值为yes。将即使磁盘或在权限出现故障,也Redis也照常工作。

(3)rdbcompression:对于存储到磁盘中的快照,可以设置是否进行压缩存储。默认值是yes,

(4)rdbchecksum:默认值是yes。在存储快照后,我们还可以让redis使用CRC64算法来进行数据校验,但是这样做会增加大约10%的性能消耗。

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

(6)dir:设置快照文件的存放路径。

4、RDB 的优势和劣势

①、优势

(1)RDB文件紧凑,全量备份,非常适合用于进行备份和灾难恢复。

(2)生成RDB文件的时候,redis主进程会fork()一个子进程来处理所有保存工作,主进程不需要进行任何磁盘IO操作。

(3)RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快。

②、劣势

       RDB快照是一次全量备份,存储的是内存数据的二进制序列化形式,存储上非常紧凑。当进行快照持久化时,会开启一个子进程专门负责快照持久化,子进程会拥有父进程的内存数据,父进程修改内存子进程不会反应出来,所以在快照持久化期间修改的数据不会被保存,可能丢失数据。

三、AOF机制

      全量备份总是耗时的,Redis提供一种更加高效的方式AOF,工作机制很简单,redis会将每一个收到的写命令都通过write函数追加到AOF文件中,通常在redis-server同级目录下。

1、持久化原理

       每当有一个写命令过来时,就直接保存在我们的AOF文件中,如下图:

2、文件重写原理

       AOF明显的会带来一个问题:持久化文件会越来越大,该怎么办呢?Redis提供一个 bgrewriteaof 命令,将内存中的数据保存到临时文件中,同时fork会创建一个新线程进行文件重写。注意:重写时,并不会读取旧的AOF文件,而是将整个内存中数据重写到新的一个AOF文件中,类似于RDB快照。

3、AOF三种触发机制

(1)每次修改同步always:同步持久化 每次发生数据变更会被立即记录到磁盘 性能较差但数据完整性比较好

(2)每秒同步everysec:异步操作,每秒记录 如果一秒内宕机,有数据丢失

(3)不同no:从不同步

4、优点

(1)AOF可以更好的保护数据不丢失,一般AOF会每隔1秒,通过一个后台线程执行一次fsync操作,最多丢失1秒钟的数据。

(2)AOF日志文件没有任何磁盘寻址的开销,写入性能非常高,文件不容易破损。

(3)AOF日志文件即使过大的时候,出现后台重写操作,也不会影响客户端的读写。

(4)AOF日志文件的命令通过可读的方式进行记录,这个特性适合做灾难性的误删除的紧急恢复。比如误操作用flushall命令清空了所有数据,只要这个时候后台rewrite还没有发生,那么就可以立即拷贝AOF文件,将最后一条flushall命令给删了,然后再将该AOF文件放回去,就可以通过恢复机制,自动恢复所有数据。

5、缺点

(1)对于同一份数据来说,AOF日志文件通常比RDB数据快照文件更大。

四、RDB和AOF对比

通过以上介绍,相信都有一定的了解,根据实际需求进行选择,如下图:

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