小言_互联网的博客

Redis入门学习笔记(六)redis持久化原理

302人阅读  评论(0)

一.前言

Redis的所有数据都是保存在内存中,然后不定期的通过异步方式保存到磁盘上(这称为“半持久化模式”);也可以把每一次数据变化都写入到一个append only file(aof)里面(这称为“全持久化模式”)。

由于Redis的数据都存放在内存中,如果没有配置持久化,redis重启后数据就全丢失了,于是需要开启redis的持久化功能,将数据保存到磁 盘上,当redis重启后,可以从磁盘中恢复数据。redis提供两种方式进行持久化,分别是RDB(Redis默认方式)和AOF。

二.RDB持久化原理

RDB持久化是把当前进程数据生成快照保存到硬盘的过程,触发RDB持久化过程分为手动触发和自动触发。

手动触发又可以分为 save命令触发和bgsave命令触发。

  • save命令:阻塞当前Redis服务器,直到RDB过程完成为止,对于内存比较大的实例会造成长时间阻塞,先上环境不建议使用。运行save命令对应Redis日志如下:
DB saved on disk
  • bgsave命令:通过执行fork操作创建子进程,子进程创建RDB文件,根据父进程内存生成临时快照文件,完成后对原有文件进行原子替换覆盖(定时一次性将所有数据进行快照生成一份副本存储在硬盘中),Redis 将内存数据库快照保存在名字为dump.rdb的二进制文件中。


运行bgsave名字对应的Redis日志如下:

Background saving started by pid 3152
DB saved on disk
RDB: 0MB of memory userd by copy-on-write
Background saving terminated with success

RDB文件是一个紧凑压缩的二进制文件,文件体积小,Redis加载RDB恢复数据远远快于AOF的方式。

由于每次生成RDB开销较大,非实时持久化,无法保存最近一次快照之后的数据,数据量大会由于I/O严重影响性能。

bgsave命令是针对save阻塞问题做的优化。因此Redis内部所有涉及到RDB操作都采用bgsave的方式,而save命令可以废弃。

Redis内部还存在自动触发RDB的持久化机制,例如一下场景:

  • 使用save相关配置,如‘save m n’表示m秒之内数据集存在n次修改时,自动触发bgsave。

  • 如果从节点执行全量复制操作,主节点自动执行bgsave生成RDB文件并发送给从节点。

  • 执行debug reload命令重新加载Redis时,也会自动触发save操作。

  • 默认情况下执行shutdown命令时,如果没有开启AOF持久化功能则自动执行bgsave。

三.AOF(append only file)持久化原理

开启后,Redis每执行一个修改数据的命令,以append的方式添加到AOF文件中。实时持久化,每一次操作都会记录下来,数据不会丢失。不过这样肯定会造成AOF文件体积逐渐变大,需要定期执行重写操作来降低文件体积,恢复起来速度慢。

AOF的工作流程操作:客户端命令写入(append)、文件同步(sync)、文件重写(rewrite)、重启加载(load),工作流程如下:

  • 所有的写入命令会追加到aof_buf(缓冲区)中。

  • AOF缓冲区根据对应的策略向硬盘做同步操作。

  • 随着AOF文件越来越大,需要定期对AOF文件进行重写,达到压缩的目的。

  • 当Redis服务重启时,可以加载AOF文件进行数据恢复。了解AOF工作流程之后,下面针对每个步骤做详细介绍。

四.优点和缺点

RDB优点

  • 一旦采用该方式,那么你的整个Redis数据库将只包含一个文件,这对于文件备份而言是非常完美的。比如,你可能打算每个小时归档一次最近24小时的数 据,同时还要每天归档一次最近30天的数据。通过这样的备份策略,一旦系统出现灾难性故障,我们可以非常容易的进行恢复。

  • 对于灾难恢复而言,RDB是非常不错的选择。因为我们可以非常轻松的将一个单独的文件压缩后再转移到其它存储介质上。

  • 性能最大化。对于Redis的服务进程而言,在开始持久化时,它唯一需要做的只是fork出子进程,之后再由子进程完成这些持久化的工作,这样就可以极大的避免服务进程执行IO操作了。

  • 相比于AOF机制,如果数据集很大,RDB的启动效率会更高。

RDB缺点

  • 如果你想保证数据的高可用性,即最大限度的避免数据丢失,那么RDB将不是一个很好的选择。因为系统一旦在定时持久化之前出现宕机现象,此前没有来得及写入磁盘的数据都将丢失。

  • 由于RDB是通过fork子进程来协助完成数据持久化工作的,因此,如果当数据集较大时,可能会导致整个服务器停止服务几百毫秒,甚至是1秒钟。

AOF优点

  • 该机制可以带来更高的数据安全性,即数据持久性。Redis中提供了3中同步策略,即每秒同步、每修改同步和不同步。事实上,每秒同步也是异步完成的,其 效率也是非常高的,所差的是一旦系统出现宕机现象,那么这一秒钟之内修改的数据将会丢失。而每修改同步,我们可以将其视为同步持久化,即每次发生的数据变 化都会被立即记录到磁盘中。可以预见,这种方式在效率上是最低的。至于无同步,无需多言,我想大家都能正确的理解它。

  • 由于该机制对日志文件的写入操作采用的是append模式,因此在写入过程中即使出现宕机现象,也不会破坏日志文件中已经存在的内容。然而如果我们本次操 作只是写入了一半数据就出现了系统崩溃问题,不用担心,在Redis下一次启动之前,我们可以通过redis-check-aof工具来帮助我们解决数据 一致性的问题。

  • 如果日志过大,Redis可以自动启用rewrite机制。即Redis以append模式不断的将修改数据写入到老的磁盘文件中,同时Redis还会创 建一个新的文件用于记录此期间有哪些修改命令被执行。因此在进行rewrite切换时可以更好的保证数据安全性。

4). AOF包含一个格式清晰、易于理解的日志文件用于记录所有的修改操作。事实上,我们也可以通过该文件完成数据的重建。

AOF缺点

  • 对于相同数量的数据集而言,AOF文件通常要大于RDB文件。RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快。

  • 根据同步策略的不同,AOF在运行效率上往往会慢于RDB。总之,每秒同步策略的效率是比较高的,同步禁用策略的效率和RDB一样高效。

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

五.持久化配置

RDB持久化配置

Redis会将数据集的快照dump到dump.rdb文件中。此外,我们也可以通过配置文件来修改Redis服务器dump快照的频率,在打开6379.conf(windows 对应的文件是redis.windows.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持久化配置

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

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

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

六.混合持久化

重启 Redis 时,我们很少使用 rdb 来恢复内存状态,因为会丢失大量数据。我们通常使用 AOF 日志重放,但是重放 AOF 日志性能相对 rdb 来说要慢很多,这样在 Redis 实例很大的情况下,启动需要花费很长的时间。 Redis 4.0 为了解决这个问题,带来了一个新的持久化选项——混合持久化。

AOF在重写(aof文件里可能有太多没用指令,所以aof会定期根据内存的最新数据生成aof文件)时将重写这一刻之前的内存rdb快照文件的内容和增量的 AOF修改内存数据的命令日志文件存在一起,都写入新的aof文件,新的文件一开始不叫appendonly.aof,等到重写完新的AOF文件才会进行改名,原子的覆盖原有的AOF文件,完成新旧两个AOF文件的替换;

aof 根据配置规则在后台自动重写,也可以人为执行命令bgrewriteaof重写AOF。 于是在 Redis 重启的时候,可以先加载 rdb 的内容,然后再重放增量 AOF 日志就可以完全替代之前的 AOF 全量文件重放,重启效率因此大幅得到提升。

打开配置文件,找到配置,如下(注意必须是Redis 4.0 以上版本

aof-use-rdb-preamble yes


BGSAVE做镜像全量持久化,AOF做增量持久化
混合持久化的缺点是兼容性差,一旦开启了混合持久化,在4.0之前版本都不识别该aof文件,同时由于前部分是RDB格式,阅读性较差。

七.小结

不管是选择RDB还是AOF,都有利也有弊,具体还是要看实际项目情况来决定使用哪种持久化方式,这样才能发挥redis持久化的特点和优势,也在实际项目运用中大大提升缓存的效率和用户体验。

参考资料
https://www.cnblogs.com/AndyAo/p/8135980.html
https://www.jianshu.com/p/9f4a3915df71
https://www.jianshu.com/p/4e6b7809e10a
https://blog.csdn.net/a1007720052/article/details/79126253


转载:https://blog.csdn.net/u013254183/article/details/105380024
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场