暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Redis学习笔记——持久化

07BLOG 2020-03-23
388

Redis学习笔记——持久化

Redis持久化的必要性

要了解Redis持久化的原理,不如先来聊聊,Redis持久化的必要性。Redis作为一个NoSQL类型的内存数据库,核心特点就是:所有数据都存放在内存中。所以,假设没有持久化机制的话,当Redis服务出现宕机的时候,内存中的数据必然会丢失。而我们知道,Redis通常会被我们当作缓存来使用。如果某个阶段Redis宕机导致了数据丢失,这时候,即使重启,缓存数据也无法很快恢复过来。那么,就必然会有大量的请求找到DB上。如果DB抗不住,网站就会出事了……称之为缓存雪崩。
那么,如何解决这种问题呢?很自然,我们就想到了持久化。如果在宕机前,
数据持久化到磁盘上,当重启后,再从磁盘上把数据恢复过来,这样,是不是就解决了缓存雪崩的问题?
我们有以下几条关于该问题的分析:

  1. 假如Redis宕机了,那么,最大可能是,在它重启之前,缓存雪崩已经造成了。(难道可以打电话让雪崩先等一等吗?)

  2. Redis甚至提供一种配置,可能把每次的修改都持久化到磁盘后,才算修改完成。但是,如果这样,那使用Redis这种内存数据库的意义岂不是要丢掉一半吗?

综上,如果Redis服务对你的整体服务是至关重要的,那么,通过集群来提高可用性,是一个必须的选择。持久化,只能是在某些非关键场景下的权衡成本后的选择,或者是作为集群的补充(帮助宕机的节点快速恢复)。
当然了,有同学可能会说,假设有天我的Redis集群整体宕机了,那持久化是不是可以给我提供一个恢复数据的数据源?答:

  1. 还是如前面所说,Redis服务的整体宕机可能会使整个系统服务出现问题,应尽量避免这种问题的发生。

  2. 如果不考虑系统整体可用性,那么,持久化也不是恢复数据的一个唯一选择。因为Redis中,存储的都是缓存类型数据,所以,我们完全可以基于其它数据源来重建缓存。

基于以上,我们得到结论,Redis持久化不是一种必要的选择,但是我们还是有必要来探究一下它的原理,比使用更重要的是,学习它其中的设计思想。(谁让面试官爱考呢?)

快照的两种方式:ROW和COW

Redis的持久化是基于快照技术实现的,所以,我们有必要简单学习一些快照的两种基本方式,ROW和COW。即使这不是我们本篇内容的重点。
快照分为两种,全量快照和增量快照。
全量快照相当于一次整体的数据备份。
增量快照,可以理解为是保存了被修改数据在某个时间点上的状态。它有以下优势:

  1. 速度快,对主体性能影响小。

  2. 可在多个时间节点建立多个备份,必要时,可以选择恢复到任意一个备份。

增量快照有两种实现方式,分别是ROW和COW,即写时重定向和写时复制。
COW原理如下:
当创建了快照后,要修改源卷上的数据时,就会把原来的数据从源卷复制到快照卷,然后再对源卷上的数据进行修改。这样,当需要恢复时,直接把快照卷的数据覆盖回源卷即可。如果快照不需要时,直接将快照卷删除。
**ROW原理如下:
当创建了快照后,要修改源卷上的数据时,会把新的数据写到快照卷上,在读取时,也需要根据是否有修改,将读重定向到快照卷上。这样,当需要恢复时,直接把快照卷中的数据删除即可。如果快照不需要时,则需要把快照卷中的数据覆盖到源卷。
对比两种快照方式,可以发现,相较而言,COW会更影响到写时的效率,而ROW则对读影响较大。所以,具体选择哪种,还需要根据业务的特点来做选择。

Redis持久化之RDB

Redis持久化有两种方式,一种是RDB,另一种是AOF。RDB的技术原理就是快照的COW,而AOF,有点类型于数据库日志。
我们先来看RDB。
启动RDB有两种方式,一种是手动,另一种是自动。手动即手动执行SAVE或BSAVE命令,自动则由配置文件中的save配置触发。由SAVE命令触发的RDB会占用当前进程,阻塞业务,而通过BSAVE命令或自动则不会占用当前进程,而是会fork一个子进程来专门负责持久化。所以,一般我们不会使用SAVE命令去手动触发持久化。
那么,fork出的子进程和主进程之间是如何进行持久化的呢?很简单,基于COW。子进程刚建立时,就建立了一个快照。这时候,它就开始将内存中的数据向磁盘保存。而当这个过程开始后,如果主进程又有新的数据修改,这时候,主进程就会将原数据复制一份再进行修改。此时,正在进行持久化作业的子进程是看不到数据变化的。

Redis持久化之AOF

Redis的另一种持久化方式,AOF,则更像是一个数据库日志。RDB是在磁盘中保存了一份的持久化开始时内存中一致的数据备份,而AOF,则是在磁盘中保存了一份详细的针对数据进行的操作的日志记录。所以,对于AOF来说,它的恢复方式是将日志文件中的操作再次执行,也就是重放。
我们可以通过配置,让Redis间隔固定时间去做AOF,如1s,也可以配置使得每次修改都进行AOF。

RDB与AOF进行对比

接下来,我们对RDB和AOF进行一个对比。

  1. 文件大小:RDB持久化的是某个节点Redis内存中的数据,AOF持久化的是每一个操作。使得AOF产生的文件要比RDB大很多。事实上,经过不断的操作,AOF文件会变得越来越大,所以,Redis有一种机制,可以对已有的AOF文件进行自动的缩小(事实上是遍历当前内存中的数据,将它们转换成指令记录到日志中)。

  2. 资源占用:RDB方式下,会fork一个新的进程来基于快照进行持久化,这种方式,对主进程的服务的影响是比较小的。而AOF则是在主进程中增加保留日志的操作。这种保留日志,是针对磁盘的IO,它和操作内存比起来,效率就要低很多。也就是说AOF的对资源的占用是大于RDB的,尤其是AOF的间隔时间较短,甚至是每执行一条指令都要持久化的情况下,这会让Redis失去它本身的优势。

  3. 备份效果:对于RDB和AOF来说,备份效果和备份间隔有关。AOF最大可做到每执行一条指令都进行持久化,这样,就不会丢失数据。而对于RDB来说,也可以把时间设置的尽量短,比如说5分钟,那么,最多就可能会丢失5分钟的数据。需要注意的是,RDB即使是fork一个子进程来进行持久化。但是,由于每次都要把内存的数据全部持久化到硬盘,所以,间隔太短依然会占用较多的CPU,对主线程产生影响,甚至卡死。

  4. 恢复速度:由于RDB备份的是数据,恢复时,只需要将所有数据都读取到内存即可。而AOF备份的是操作日志,恢复时,需要读取到日志,再去依次执行。所以,AOF的恢复速度是低于RDB的。

选择RDB还是AOF?

前面聊了那么多,最终都是为了解答这个问题:选择RDB还是AOF?
我们说,如何选择,主要看数据在重要程序。如果数据不重要,可从其它数据源恢复,Redis持久化仅仅是为了补充,那就选择RDB,如果数据重要,那就选择AOF。


文章转载自07BLOG,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论