Redis 持久化

发布时间:2024年01月05日

1、Redis持久化有哪几种方式

持久化

将数据写入磁盘,避免因进程退出而造成的数据丢失,下次重启时通过持久化文件恢复数据。

1.1 RDB(Redis DataBase)

通过快照(内存中数据在某一时刻的状态记录)的方式实现持久化,根据快照的触发条件,将内存的数据快照写入磁盘,以二进制的压缩文件进行存储。

优点

  • 大规模的数据恢复,并且对数据恢复的完整性要求不高,使用RDB比AOF更高效
  • 以二进制压缩文件的形式存储,占用内存更小
  • redis使用bgsave命令进行持久化,基本不会影响主进程,保证了redis的高性能

缺点

  • Fork的时候,内存中的数据会被克隆一份,大致2倍的膨胀,需要考虑
  • 虽然Redis在fork的时候使用了写时拷贝技术,但是如果数据庞大时还是比较消耗性能
  • 在备份周期在一定间隔时间做一次备份,所以如果Redis意外down的话,就会丢失最后一次快照后所有修改

1.2 AOF(Append Of File)

以独立日志的方式记录每次写的命令,重启时重新执行AOF文件中的命令恢复数据

AOF重写机制:AOF文件的大小达到某个阈值时,会将其中指令进行压缩。(如果有对于某个key多次的变更指令,则仅保留最新的数据指令)。

重写流程

  • 手动执行 bgrewriteaof命令触发重写,判断是否当前有bgfsave或bgrewriteaof在运行,如果有,则等待该命令结束后再继续执行
  • 主进程fork出子进程执行重写操作,保证主进程不会阻塞
  • 子进程遍历redis内存中的数据到临时文件,客户端的写请求同时写入aof_buf缓冲区和aof_rewrite_buf重写缓冲区保证原AOF文件完整性以及新AOF文件生成期间的新的数据修改动作不会丢失
  • 子进程写完新的AOF文件后,向主进程发送信号,父进程更新统计信息
  • 主进程把aof_rewrite_buf中的数据写入到新的AOF文件
  • 使用新的AOF文件覆盖旧的AOF文件,完成AOF重写

在这里插入图片描述

优化

  • 因为AOF重写过程中需要读取当前内存中所有键值数据,性能较低,redis将其放在一个后台子线程中完成。
  • 为了避免重写过程中出现数据变动,主进程的数据变更需要追加到AOF重写缓冲区中,等到AOF重写完成后,再把AOF重写换乘区里面的内容追加到新的AOF文件中。

优点

  • 备份机制更稳健,丢失数据概率更低
  • 可读的日志文本,通过操作AOF文件,可以处理误操作

缺点

  • 比RDB占用更多的磁盘空间
  • 恢复备份速度要慢
  • 每次读写都同步的话,有一定的性能压力
  • 存在个别bug,造成不能恢复

1.3 混合持久化

生产环境中一般采用两种持久化机制混合使用。

将内存中数据快照存储在AOF文件中(模拟RDB),后续再以AOF追加方式。

如果仅作为缓存使用,可以承受几分钟数据丢失,可以使用RDB,对主程序性能影响最小。

混合持久化优点

  • 结合了 RDB 和 AOF 的优点,可以更快的启动,同时也降低了数据丢失的风险

混合持久化缺点

  • AOF 文件中添加了 RDB 格式的内容,可读性降低
  • 如果开启混合持久化,那么支持次混合持久化 AOF 文件,不能用在redis 4.0 之前的版本

img

2、持久化配置

2.1 RDB:redis备份默认方式

配置主要是在redis安装目录下的redis.conf文件中进行

2.2.1 指定备份文件的名称

在redis.conf中,可以修改rdb备份文件的名称,默认为dump.rdb

在这里插入图片描述

2.2.2 指定备份文件存放的目录

在redis.conf中,rdb文件的保存的目录是可以修改的,默认为Redis启动命令所在的目录

在这里插入图片描述

在这里插入图片描述

2.2.3 触发RDB备份
2.2.3.1 自动备份:

可在redis.conf中配置自动备份的规则

在这里插入图片描述

save用来配置备份的规则

save的格式: save 秒钟 写操作次数

默认是1分钟内修改了1万次,或5分钟内需修改了10次,或30分钟内修改了1次。

示例:设置2分钟(120秒)内有最少有3次key发生变化,则进行备份

save 120 3
2.2.3.2 手动执行命令备份(save | bgsave)

有2个命令可以触发备份。

  • save:save时只管保存,其他不管,全部阻塞,手动保存,不建议使用。
  • bgsave:redis会在后台异步进行快照操作,快照同时还可以响应客户端情况。

save命令: 在客户端中执行 save 命令,就会触发 Redis 的持久化 ,但是会阻塞主线程命令的执行

bgsave命令:bgsave会 fork() 一个子进程来执行持久化,整个过程只有 fork() 子进程的时候有短暂的阻塞,子进程创建之后,redis的主进程就可以响应客户端的请求了

fork() 作用:复制一个与当前进程一样的进程,新进程所有的数据数值与原进程一致,但是是一个全新的进程,并作为原进程的子进程

一般情况父进程和子进程会共用同一段物理内存,只有进程空间的各段的内容要发生变化时,才会将父进程的内容复制一份给子进程。

2.2.3.3 redis.conf 其他一些配置
  • stop-writes-on-bgsave-error:当磁盘满时,是否关闭redis的写操作

  • rdbcompression:rdb备份是否开启压缩

  • rdbchecksum:是否检查rdb备份文件的完整性

2.2.4 不同版本Redis关闭RDB的坑

我们仔细阅读save之上的注释,可以发现两个版本关闭RDB的方式完全不同

Redis 3.2.100

通过注释所有save 命令就可以关闭新数据进行RDB备份了。

在这里插入图片描述

Redis 7.2.3

通过 写入一个sava ”“ 来指定save的规则为空,才能关闭新数据进行RDB备份。

如果只是注释所有save命令,redis则会采用默认的save规则继续执行RDB持久化。

在这里插入图片描述

2.2 AOF

AOF 日志存储的是 Redis 服务器的顺序指令序列,AOF 日志只记录对内存进行修改的指令记录。

在这里插入图片描述

2.2.1 写入机制

Redis 在收到客户端修改命令后,先进行相应的校验,如果没问题,就立即将该命令存追加到 .aof 文件中,也就是先存到磁盘中,然后服务器再执行命令。这样就算遇到了突发的宕机情况情况,也只需将存储到 .aof 文件中的命令,进行一次“命令重演”就可以恢复到宕机前的状态。

2.2.2 写入缓存

在上述执行过程中,有一个很重要的环节就是命令的写入,这是一个 IO 操作。Redis 为了提升写入效率,它不会将内容直接写入到磁盘中,而是将其放到一个内存缓存区(buffer)中,等到缓存区被填满时采用异步真正将缓存区中的内容写入到磁盘里。

在这里插入图片描述

  • Always:服务器每写入一个命令,就调用一次 fsync函数,将缓冲区里面的命令写入到硬盘。这种模式下,服务器出现故障,也不会丢失任何已经成功执行的命令数据,但是其执行速度较慢;
  • Everysec(默认):服务器每一秒调用一次 fsync 函数,将缓冲区里面的命令写入到硬盘。这种模式下,服务器出现故障,最多只丢失一秒钟内的执行的命令数据,通常都使用它作为 AOF 配置策略;
  • No:服务器不主动调用 fsync 函数,由操作系统决定何时将缓冲区里面的命令写入到硬盘。这种模式下,服务器遭遇意外停机时,丢失命令的数量是不确定的,所以这种策略,不确定性较大,不安全。

注意:Linux 系统的 fsync() 函数可以将指定文件的内容从内核缓存刷到硬盘中。

由于是 fsync 是磁盘 IO 操作,所以它很慢!如果 Redis 执行一条指令就要 fsync 一次(Always),那么 Redis 高性能将严重受到影响。

在生产环境的服务器中,Redis 通常是每隔 1s 左右执行一次 fsync 操作( Everysec),这样既保持了高性能,也让数据尽可能的少丢失。最后一种策略(No),让操作系统来决定何时将数据同步到磁盘,这种策略存在许多不确定性,所以不建议使用。

2.2.3 自动触发AOF重写

Redis 为自动触发 AOF 重写功能,提供了相应的配置策略。如下所示:修改 Redis 配置文件,让服务器自动执行 BGREWRITEAOF 命令。

在这里插入图片描述

2.2.4 运行流程
  • 客户端的请求写命令会被append追加到AOF缓冲区内
  • AOF缓冲区会根据AOF持久化策略[always,everysec,no]将操作sync同步到磁盘的AOF文件中
  • AOF文件大小超过重写策略或手动重写时,会对AOF文件进行重写(rewrite),压缩AOF文件容量
  • redis服务器重启时,会重新load加载AOF文件中的写操作达到数据恢复的目的
2.2.5 AOF配置
appendonly no # 是否开启AOF,yes:开启,no:不开启,默认为no
appendfilename "appendonly.aof" # aof文件名称,默认为appendonly.aof
dir ./ # aof文件所在目录,默认./,表示执行启动命令时所在的目录
2.2.6 AOF的备份恢复

AOF的备份机制和性能虽然和RDB不同,但是备份和恢复的操作同RDB一样,都是拷贝备份文件,需要恢复时再拷贝到Redis工作目录下,启动系统即加载。

2.2.6.1 正常恢复

修改默认的appendonly no,改为yes

将有数据的aof文件复制一份保存到对应的目录(查看目录:config get dir)

恢复:重启redis然后重新加载

2.2.6.2 异常恢复

修改默认的appendonly no,改为yes

如遇到aof文件损坏,通过 redis-check-aof --fix appendonly.aof 进行恢复,

appendonly.aof是文件名

在这里插入图片描述

2.3 Redis 4.0 混合持久化

重启 Redis 时,我们很少使用 rdb 来恢复内存状态,因为会丢失大量数据。我们通常使用 AOF 日志重放,但是重放 AOF 日志性能相对 rdb 来说要慢很多,这样在 Redis 实例很大的情况下,启动需要花费很长的时间。

Redis 4.0 为了解决这个问题,带来了一个新的持久化选项——混合持久化。将 rdb 文件的内容和增量的 AOF 日志文件存在一起。这里的 AOF 日志不再是全量的日志,而是自持久化开始到持久化结束的这段时间发生的增量 AOF 日志,通常这部分 AOF 日志很小。

2.3.1 混合持久化配置

在redis的配置文件当中有一个aof-use-rdb-preamble参数来开启 混合持久化,默认是yes开启的。混合持久化结合了 RDB 和 AOF 的优点,Redis 5.0 默认是开启的。

新的持久化选项——混合持久化。将 rdb 文件的内容和增量的 AOF 日志文件存在一起。这里的 AOF 日志不再是全量的日志,而是自持久化开始到持久化结束的这段时间发生的增量 AOF 日志,通常这部分 AOF 日志很小。

2.3.1 混合持久化配置

在redis的配置文件当中有一个aof-use-rdb-preamble参数来开启 混合持久化,默认是yes开启的。混合持久化结合了 RDB 和 AOF 的优点,Redis 5.0 默认是开启的。

在这里插入图片描述

文章来源:https://blog.csdn.net/Zyw907155124/article/details/135404474
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。