Redis持久化方式

RDB

        rdb使用生成快照的方式进行持久化:生成一个快照文件保存当前时刻redis的数据。具体有俩种触发方式:手动触发 和 自动触发.

手动触发:

        手动触发有俩种方式:save和bgsave。

        save:阻塞当前线程向快照文件中写入数据(默认叫做dump.rdb,路径在配置文件中设置)。

        bgsave:使用写时复制(copy on write)执行folk操作(Linux提供的一个创建子进程的api)创建出一个子线程,子进程相当于父进程的一个副本,  子线程会生成一个新的快照文件,完成后替换原本的快照文件并通知父进程。在这期间,如果主线程收到bgsave的命令就直接返回。

自动触发:

        自动触发的持久化逻辑与bgsave相同。

        条件:在一定时间内执行指定次数的操作  (在配置文件中进行设置)。   

 

        

一些需要注意的点:

1:快照文件(dump.rdb)使用压缩二进制的方式保存redis数据,恢复数据时速度非常快。

2:rdb是一个重量级的操作,频繁执行开销过大,所以达不到实时持久化的效果,需要一定触发条件。

3:快照文件不能随意改动,redis提供了对rdb文件进行检查的工具

4:在正常退出redis时redis也会进行一次rdb操作(kill进程的方式不会触发)

5:rdb文件的生成和读取会存在版本差异,老版本的rdb文件在新版本读取时可能存在问题。

folk创建子线程的操作会造成大的时间和空间开销吗?

答案是否定的。folk操作确实会在子进程中对父进程的PCB,文件描述符表,内存变量等进行拷贝,但并不是直接拷贝一份,而是使用“写时拷贝”的策略,先和父进程共用同一份资源,等到某一方要对资源进行修改时才真正进行拷贝。

AOF

       原理: AOF生成一个文本文件用来记录用户对redis的每次操作。

        AOF默认是关闭的,需要在配置文件中手动开启。开启AOF之后,rdb就失效了。

AOF对用户的每个指令进行持久化,现在要存储一个数据既要在内存中存储,又要去硬盘保存指令,会影响redis的速度吗?

        答案是不会。

        1.redis维护了一个缓冲区,指令先存储在缓冲区中,积攒一定的量后再去写入到文件中。

 *指令在缓冲区还没有写入文件时如果进程被kill或者主机掉电之类的数据会丢失

        缓冲区数据写入硬盘的规则(sync):

  always:每条指令立刻去写入硬盘。频率最高,数据可靠性最高,性能最差。

  everyscond:每秒去进行一次将缓冲区数据写入到硬盘的操作。频率低一点,数据可靠性差一点,性能高一点。(reids默认策略,适用于大部分场景)

  no:由系统去执行将缓冲区数据写入到硬盘的操作:缓冲区满了。redis重启或者正常退出之类的情况时。      频率最低,数据可靠性最差,性能最高。

选择什么样的策略实际上就是基于一个数据可靠性和性能的综合考量。

        2.AOF对aof文件进行读写的方式是顺序的,速度会比随机读写快很多。

AOF对冗余数据的处理:

        AOF进行持久化的原理是将指令写入到aof文件中去,那么这个文件一定是用来越大并且有很多冗余数据的:

比如以下操作:set key q;set key a; set key v;

实际上我们只需要在aof文件中保存最终状态的指令set key v即可,不用去关注中间过程。

        reids对aof文件设置了一个重写机制(rewrite),能够对aof文件进行整理,去除其中的冗余操作,达到一个瘦身的效果。

重写流程:

        与RDB生成快照的方式类似,也是folk出一个子进程用来进行重写。子进程会继承父进程当前的内存状态,根据当前内存中的数据生成一个新的aof文件(此时就相当于去除冗余数据了)。  在这期间,父进程正常工作,还是会将指令写入缓冲区和旧的AOF文件。但是,由于子线程只能继承folk时父进程的内存状态,所以对于folk之后的指令子进程感知不到,所以父进程还会开辟出一个新的缓冲区aof_rewrite_buf用来保存folk之后的指令,当子线程重新完成后,把这些缓冲区中的folk之后的指令也写入新的aof文件。之后将新的aof文件替换旧的aof文件,完成重写。

为什么重写的时候父进程还要继续往旧的aof文件写数据?

        考虑到极端情况,如果重写过程中发送主机掉电之类的情况,新的aof文件还不完整,这时候redis还可以通过旧的aof文件恢复数据,数据也不会出现丢失的情况。

触发rewrite机制:

        1:自动触发:设置参数:1.最小文件大小       2.当前aof文件大小相较于上次重写时增加的比例

        2:手动触发:调用bgrewriteaof指令

AOF和RDB比较

        主要存在俩方面的差异:

1:AOF支持实时持久化,RDB主要用来定期持久化,数据可靠性AOF会比RDB高,性能相对较低。

2:AOF以追加的形式将指令以文本的形式写入一个文本文件,RDB则是将当前内存数据以压缩二进制的形式进行持久化。AOF的文件大小相比rdb会大一些,但是可读性更高一点。在进行数据恢复时,由于没有冗余数据,并且由于是二进制,rdb的读取速度会比aof高。

当AOF和RDB都开启后,redis以AOF的数据为准,因为AOF的数据更全面准确。

混合持久化

配置:

        

 Redis针对上述第二点提出了混合持久化的方式(基于aof),即:AOF在进行重写时子线程会按照RDB的方式将当前内存中的数据以压缩二进制的形式存储在AOF文件中,之后不触发重写时则会将指令以文本的形式追加在后面。对于aof_rewrite_buf中的数据同样采用aof文本追加的方式。

混合持久化完善了aof读取数据时速度慢的缺点,还能增加重写的速度

  • 23
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值