Redis持久化之RDB内存快照

Redis中持久化方法:内存快照,所谓内存快照是指,内存中的数据,在某一时刻被系统做个记录,类似于拍照。
Redis就是把某一时刻的状态以文件的形式记录到磁盘,也就是快照,这样一来就可以不丢失数据,也就是RDB(Redis Data Base)的缩写。

Redis中的RBD内存快照

      • RDB和AOF的记录区别
      • RBD给哪些数据做快照呢?
      • 做快照时是否阻塞?
      • 在做快照是能否修改数据?
      • 多久做一次快照?
      • 增量快照
      • AOF与RDB的混合模式
      • 如何选择AOF和RDB

RDB和AOF的记录区别

AOF是记录的每一次操作的命令,而RDB则是记录某一时刻的数据,并且以二进制压缩文件进行存储,所以再做数据恢复时,把文件读入内存,很快就会完成恢复。

RBD给哪些数据做快照呢?

Redis的数据都是再内存中的,为了提供数据的可靠性,RDB执行的是全量快照,也就是把内存中的所有数据都记录到磁盘中。给内存做全量快照时,RDB文件越大,往磁盘写数据的时间开销也就会越大。

做快照时是否阻塞?

Redis毕竟是单线程,我们应该避免一切可能会发生的阻塞点,但是Redis做全量快照时,它会阻塞主线程吗?
Redis提供了两个命令来生成RDB文件:

  • save:在主线程中执行,必定会阻塞;
  • bgsave:创建子进程,用于写入RDB文件,避免了主线程的阻塞,这也是默认配置。

在AOF中我说明了创建子进程的过程。

在做快照是能否修改数据?

拍照的比喻在合适不过了,做快照就相当于拍照,我们希望在给朋友拍照时希望朋友不要随意乱动,于Redis相同,希望在做快照时,数据不要被修改,但是可想而知,如果数据量有几个G甚至几十个G的时候,做快照磁盘落地而不对外提供修改操作的话,客户端只有被阻塞,Redis当然不会允许这种情况出现的。

此时Redis也是使用了操作系统提供的写时复制机制。和AOF重写一样。bgsave时父进程fork出子进程,子进程可以共享父进程的内存页,开始读取内存页,再把它写入到RDB文件。
此时需要注意的时,在RDB的过程中,读操作父进程和子进程互不影响,比如说下图中父进程与子进程共同读取数据块A。但是如果父进程需要修改某一块的数据时就会触发COW,比如说下图中的客户端如果发送了一条写操作的命令(set c)给Redis父进程,C就会被复制一份共子进程使用。
Redis持久化之RDB内存快照_第1张图片

这样就保证了Redis在做快照是可以进行写操作,也避免了对业务的影响。

多久做一次快照?

先来了解下RDB做快照时,应该多久做一次,拍照都有连拍,Redis可以嘛?如果Redis也有向连拍一样的机制,那RDB的间隙不就是很短了(间隙是指上一次RDB和下一次RDB文件之间的时刻)。

如下图所示的那样,在时刻1做了一次快照,然后时刻1+N又做了一次快照,中间修改了A、B。如果在此之间也就是时刻1后,Redis宕机了,那么重启服务只能以时刻1来恢复数据了,A、B就丢失了。
Redis持久化之RDB内存快照_第2张图片
想要数据丢失的少,就要向相机连拍一样,让RDB每秒执行一次,那么RDB可以每秒执行一次持久化嘛?
答案是否定的,因为这是存在一定风险的,就算执行bgsave让子线程去执行也是不行的,如果频繁的执行全量快照会有一定的开销。

  1. 频繁快照会给磁盘带来很大的压力,而且每秒一次,前一个没做完后一个就开始了。
  2. 频繁的bgsave创建子进程来处理的话,fork系统调用也是会存在阻塞点,而且主进程内存越大阻塞时间越长,毕竟子进程会复制父进程页表。

增量快照

为了解决以上的问题可以使用增量快照来解决,就是做了一次全量快照以后,后面的记录只对修改的数据进行快照,大大的减少了开销。

在第一次进行了全量快照后,再有修改的操作,Redis必须把它记下来,以便进行增量快照。但是这个记住功能需要额外的元数据空间来进行存储,会带来额外的开销。比如我们修改了一千万的键值对,我们就要记录这一千万的键值对数据到元数据,每个键值对的大小不依,所以为了记住修改的数据,而引入的额外空间开销,对Redis来说这些空间是宝贵的。

AOF与RDB的混合模式

Redis在4.0的时候提出混合使用AOF日志和内存快照,内存快照之间的间隙只用AOF日志文件记录操作命令。

这样快照不用很频繁执行,避免了频繁fork和磁盘开销。而且AOF日志文件也只需要记录两次快照之间的操作,也就不需要每一次命令都要记录了,也就是避免了重写操作。结合后AOF的数据回复慢也被解决,RDB快照丢失数据问题也被解决,混合体,利用了RDB的快,跟AOF的追加和全量,将老的数据RDB到老的AOF文件中,再有新的操作的时候增量指令的方式Append到AOF
这样两种持久化模式结合,从两个模式中取长补短,来弥补各方的缺点,简直不要太舒服。

在Redis.conf配置文件中修改此参数aof-use-rdb-preamble yes即可打开混和模式,默认开启。

如何选择AOF和RDB

  • 数据不能丢失时,RDB和AOF混合模式是个选择;
  • 如果允许少量的丢失可以使用RDB;

本章参考蒋德均老师的Redis核心技术与实战。

你可能感兴趣的:(Redis,redis,数据库,linux)