redis持久化存储,rdb快照文件,aof文件

redis作为内存数据库,在内存中进行读写操作,将读写操作从毫秒级别降为纳秒级别,得到极大的性能提升,与此同时,作为内存数据库其也有致命缺陷,一旦redis发生意外宕机,那么内存中的数据将全部消失,无法找回,为了防止这种情况,redis提供了两种持久化存储的方式,分别是rdb文件,以及aof文件。

rdb文件

redis可以通过save命令生成一个rdb文件,rdb文件内部保存了当前数据的副本,并且通过算法优化压缩,将文件体积大大减小,但生成rdb文件需要将整个内存中的数据全部进行复制,这无疑是及其耗时的操作,如果周期性执行这种命令,则会造成redis的周期行卡顿,所以redis还有另一种方式,通过bgsave命令进行写时复制,那么什么是写时复制呢?

写时复制是通过操作系统提供的fork系统调用来实现的,fork系统调用会创建出一个子进程,和父进程执行相同的代码(fork调用时刻以下的),并且和父进程共享内存空间,也就是读操作是读相同的内存空间,并且将内存空间变为只读,当父进程想要修改内存页时,会向操作系统抛出异常,操作系统识别到异常后,会复制一份当前操作的内存页(操作系统中无论是内存是页式存储)的副本交给父进程进行修改。

所以redis实现写时复制的流程是,首先调用fork,创建子进程,fork会返回一个id,如果当前时父进程,则返回子进程id,如果是子进程则返回0,通过这个,判断当前执行代码的是哪个进程,如果是父进程,则继续监听读写操作,如果有写操作,操作系统会复制内存页供父进程修改。如果当前是子进程,则进行内存数据的读取,并且生成rdb文件,实现代码大致如下。

pid_t pid = fork();
​
    if (pid < 0) {
        // fork 失败
        perror("fork");
        exit(EXIT_FAILURE);
    } else if (pid == 0) {
        // 子进程
        //执行读取内存数据,生成rdb文件的操作......
    } else {
        //父进程
        //执行监听读写操作,修改数据
    }

大致流程如下图,其中红色箭头为子进程复制rdb文件的流程,蓝色为内存页被复制前,父进程的流程,紫色为内存页被复制后父进程的流程。

在redis的配置文件中,我们可以通过配置如下参数,让redis定期执行写时复制

save 900 1     # 900秒内至少有1次写操作
save 300 10    # 300秒内至少有10次写操作
save 60 10000  # 60秒内至少有10000次写操作

aof文件

rdb文件可以通过周期性生成更新保存绝大多数数据,但在对数据安全性较高的情况下,rdb还是避免不了丢失一部分数据,而aof文件,则是提供了另一种解决方案。

aof文件是通过保存执行写操作的指令,以达到持久化存储的目的,其首先在执行写操作时,redis会将写操作指令读取到aof缓冲区,并且根据不同的频率将缓冲区内容写入aof文件,其有三种频率,通过配置appendfsync来进行调整,分别是no(由操作系统决定,性能最好,但丢失数据最多),everysec(折中方案,每秒读取一次日志文件,丢失一秒的数据),always(不丢失数据,性能最查),在高可用集群环境下,我们通常会采取always进行保存。

虽然aof是保存指令而不是数据,但是aof没有算法对其进行压缩,所以aof文件体积较大,为了优化aof体积,redis采用了一种定期更新aof文件的方式(对一个数据多次修改,其实只有最后一次有用,前面保存的都是多余的指令),可以通过如下配置自定义

auto-aof-rewrite-percentage 100  # 当 AOF 文件大小达到上次重写后的两倍时,触发重写
auto-aof-rewrite-min-size 64mb   # AOF 文件最小达到 64MB 时才会触发重写

其中第一个配置是百分比,也就是增大了百分之百后重写aof,第二个配置是最小大小,也就是说即使你已经增大了既定的百分比,你也要达到64mb才能重写。而重写的过程则是便利内存中全部的数据,并将数据变成对应的执行,比如说string类型变成set指令,hash类型变成hset指令。

aof缓冲区到磁盘的过程是在主线程执行的,其会阻塞redis代码的执行,而aof重写则是写时复制,跟rdb写时复制流程相同,只不过子线程执行的逻辑变成了将内存数据读取成aof文件。

当rdb和aof文件都存在时,redis的数据恢复会优先读取aof文件,如果没有aof文件或者aof文件读取失败,才会读取rdb文件。

rdb和aof结合使用

rdb文件体积小,生成和恢复速度快,但保存文件不完成,而aof则相反,所以可以通过将两者结合,最大化发挥两者的优势,在redis配置文件中可以通过配置aof-use-rdb-preamble为yes开启,在这个模式下,重写aof时会先在aof文件中创建rdb快照,然后在将aof缓冲区的内容追加到rdb快照的后面。

  • 16
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不止会JS

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值