Redis持久化机制RDB和AOF

前言:Redis读写速度快、性能优越是因为它将所有数据存在了内存中,然而,当Redis进程退出或重启后,所有数据就会丢失。所以我们希望Redis能保存数据到硬盘中,在Redis服务重启之后,原来的数据能够恢复,这个过程就叫持久化。

一、RDB持久化

RDB(Redis DataBase)持久化是指在指定的时间间隔内将内存中的数据集快照写入磁盘,实际操作过程是fork一个子进程,先将数据集写入临时文件,写入成功后,再替换之前的文件,用二进制压缩存储。

RDB持久化方式是通过快照(snapshotting)完成的,当符合一定条件时,redis会自动将内存中所有数据以二进制方式生成一份副本并存储在硬盘上。RDB生成快照可通过配置自动触发,也可以使用命令手动触发,以下是redis触发执行快照条件:

  • 客户端执行命令save和bgsave会生成快照;

  • 根据配置文件save m n规则进行自动快照;

1.1、save和bgsave命令手动触发

RDB有两种方式,save和bgsave:

  • save,会阻塞服务器的其他操作,直到save执行完成,所以,这个期间的所有命令请求都会被拒绝。对客户端影响较大。

  • BGSave,手动启动后台持久化操作,但不是立即执行。由子进程进行数据保存,期间redis仍然可以继续处理客户端请求。为了防止竞争和冲突,bgsave被设计成和save/bgrewriteaof操作互斥。

Redis服务器默认每100毫秒执行一次,如果数据库修改次数(dirty计数器)大于设置的阈值,并且距离上次执行保存的时间(lastsave属性)大于设置的阈值,则执行保存操作。

因为是统一批量的保存操作,rdb文件有二进制存储、结构紧凑、空间消耗少、恢复速度快等特点,在持久化方案上不可或缺。

1.2、配置save m n规则自动触发

Redis会将数据集的快照dump到dump.rdb文件中。此外,我们也可以通过配置文件来修改Redis服务器dump快照的频率,在打开redis.conf 文件之后,我们搜索save,可以看到下面的配置信息:

save 900 1              #在900秒(15分钟)之后,如果至少有1个key发生变化,则dump内存快照。

save 300 10            #在300秒(5分钟)之后,如果至少有10个key发生变化,则dump内存快照。

save 60 10000        #在60秒(1分钟)之后,如果至少有10000个key发生变化,则dump内存快照。


二、AOF持久化

Append Only File,AOF会保存服务器执行的所有写操作到日志文件中,在服务重启以后,会执行这些命令来恢复数据。实时性更好,丢失的数据更少。默认情况下,aof没有被开启。需要在redis.conf开启

然而,因为bgsave的周期间隔和保存触发条件等原因,在服务器宕机时,不可避免的会丢失一部分最新的数据。这就需要一些辅助手段来做持久化补充。

2.1、为什么AOF保存的是命令,而不是键值对呢?

RDB保存的是键值对,而AOF则用来保存写命令。

一是因为aof刷盘,是在文件事件处理过程当中的,具体位置是在结束一个事件循环之前,调用追加函数进行,所以,使用请求命令来存储更方便;二是如果遇到追加过程中命令被破坏,也可以通过redis-check-aof来恢复(命令恢复起来比较方便)。

AOF刷盘策略,由于aof追加动作是和客户端请求处理串行执行的,所以每次都刷盘对性能影响较大,因此都是先追加到aof_buf缓存区里,而是否同步到AOF文件中则依赖always、everysec(默认)、no的刷盘配置。想比everysec ,always对性能影响较大,而no则容易丢失数据。

AOF文件重写压缩,AOF因为保存了请求命令,自然要比RDB更大,并且随着程序的运行,会越来越大,然而,文件中有很多冗余的命令数据是可以压缩的,因为对于某个键值对,某一时刻只会有一个状态。

2.2、AOF持久化配置

在Redis的配置文件中存在三种同步方式,它们分别是:

appendfsync always     #每次有数据修改发生时都会写入AOF文件。

appendfsync everysec  #每秒钟同步一次,该策略为AOF的缺省策略。

appendfsync no          #从不同步。高效但是数据不会被持久化。


三、RDB和AOF对比

3.1、RDB的优点:

  • 体积更小:相同的数据量rdb数据比aof的小,因为rdb是紧凑型文件

  • 恢复更快:因为rdb是数据的快照,基本上就是数据的复制,不用重新读取再写入内存

  • 性能更高:父进程在保存rdb时候只需要fork一个子进程,无需父进程的进行其他io操作,也保证了服务器的性能。

3.2、RDB缺点:

  • 故障丢失:因为rdb是全量的,我们一般是使用shell脚本实现30分钟或者1小时或者每天对redis进行rdb备份,(注,也可以是用自带的策略),但是最少也要5分钟进行一次的备份,所以当服务死掉后,最少也要丢失5分钟的数据。

  • 耐久性差:相对aof的异步策略来说,因为rdb的复制是全量的,即使是fork的子进程来进行备份,当数据量很大的时候对磁盘的消耗也是不可忽视的,尤其在访问量很高的时候,fork的时间也会延长,导致cpu吃紧,耐久性相对较差。

3.3、AOF的优点

  • 数据保证:我们可以设置fsync策略,一般默认是everysec,也可以设置每次写入追加,所以即使服务死掉了,咱们也最多丢失一秒数据

  • 自动缩小:当aof文件大小到达一定程度的时候,后台会自动的去执行aof重写,此过程不会影响主进程,重写完成后,新的写入将会写到新的aof中,旧的就会被删除掉。但是此条如果拿出来对比rdb的话还是没有必要算成优点,只是官网显示成优点而已。

3.4、AOF缺点:

  • 性能相对较差:它的操作模式决定了它会对redis的性能有所损耗

  • 体积相对更大:尽管是将aof文件重写了,但是毕竟是操作过程和操作结果仍然有很大的差别,体积也毋庸置疑的更大。

  • 恢复速度更慢

二者选择的标准,就是看系统是愿意牺牲一些性能,换取更高的缓存一致性(aof),还是愿意写操作频繁的时候,不启用备份来换取更高的性能,待手动运行save的时候,再做备份(rdb)。rdb这个就更有些 eventually consistent的意思了。不过生产环境其实更多都是二者结合使用的。


四、Redis 4.0 后的混合持久化

由于单纯 RDB 的话,可能存在数据的丢失,而频繁的 AOF 又会影响性能,在 Redis 4.0 之后,支持了 rdb 和 aof 的混合持久化,也就是同时结合RDB持久化以及AOF持久化混合写入AOF文件。这样做的好处是可以结合 rdb 和 aof 的优点, 快速加载同时避免丢失过多的数据,缺点是 aof 里面的 rdb 部分就是压缩格式不再是 aof 格式,可读性差。

4.1、开启混合持久化

Redis4.0版本的混合持久化默认关闭的,通过aof-use-rdb-preamble配置参数控制,yes则表示开启,no表示禁用,默认是禁用的,可通过config set修改。

4.2、混合持久化过程

混合持久化同样也是通过bgrewriteaof完成的,不同的是当开启混合持久化时,fork出的子进程先将共享的内存副本全量的以RDB方式写入aof文件,然后在将重写缓冲区的增量命令以AOF方式写入到文件,写入完成后通知主进程更新统计信息,并将新的含有RDB格式和AOF格式的AOF文件替换旧的的AOF文件。

简单来说,新的AOF文件前半段是RDB格式的全量数据,后半段是AOF格式的增量数据,aof 文件内容会变成如下:

这样做的好处是可以结合 rdb 和 aof 的优点, 快速加载同时避免丢失过多的数据。Redis每次启动时候通过 RDB+增量的 AOF 文件来进行恢复,由于增量的 AOF 仅记录了开始持久化到持久化结束期间发生的增量,这样日志不会太大,性能相对较高。


参考链接:

RDB和AOF的区别

Redis(持久化) - 简书

redis系列--redis4.0深入持久化

Redis-4.0以后的混合持久化

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Java架构何哥

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

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

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

打赏作者

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

抵扣说明:

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

余额充值