Redis持久化

Redis持久化

持久化就是把内存中的数据写进硬盘里面,获得持久的保存。

为了防止断电,服务器宕机导致内存中的数据丢失

持久化的实现方式:

  • RDB(Redis Database)

  • AOF(Append Only File)

  • RDB+AOF

 

一、RDB

RDB:在指定的时间间隔,执行数据集的时间点快照。类似照片记录效果的方式,把某一时刻的数据和状态以文件的形式写到磁盘上,也就是快照。这样一来即使故障宕机,快照文件也不会丢失,数据的可靠性也就得到了保证。

这个快照文件就成为RDB文件(dump.rdb)恢复时将硬盘快照文件直接读回到内存里。保存备份时是全量快照,把内存中的所有数据都记录到磁盘中。

 

rdb配置修改

在redis的配置文件中指定 时间间隔

redis6之前

image-20240829171152105

在Redis.conf 配置文件中的 SNAPSHOTTING 下配置save参数,来触发Redis的RDB 持久化条件

比如 “save m n ”表示 m 秒内数据存在 n 次修改时,自动触发bgsave

save 900 1:每隔900秒,如果有1个key发生变化,就写一份新的RDB文件

save 300 10:每隔300秒,如果有10个key发生变化,就写一份新的RDB文件

save 60 10000:每隔60秒,如果有10000个key发生变化,就写一份新的RDB文件

 

Redis7的配置文件将配置项修改为:

image-20240829172549064

 

自定义修改:

  • 修改触发频率 通过修改save后的值 save 5 2

    • 也就是5秒之后,并且修改次数达到2次,就会保存到dump

  • 修改dump文件保存路径 ----修改 dir

  • 修改dump文件名 -----修改dbfilename

 

恢复数据

如果想要恢复数据,只需要将备份文件(dump.rdb) 移动到redis的安装目录(如果指定了dump文件的存放路径,那么把dump文件放到该路径即可恢复)并启动服务即可。

如何测试?

先创建三个set集合,保证5秒后修改了2次,会生成一个 dump.rdb,我们把这个dump.rdb改个名字,然后把库清空。(执行flushall或 flushdb 命令也会产生 dump.rdb),把新生成的dump.rdb 删除,重启redis(关闭redis也会生成dump文件),把之前修改的dump改回去,,发现一开始创建的三个set集合又回来了。

 

当产生了有数据的 dump.rdb 一定要进行备份,服务和备份分机隔离,分开存储

防止备份文件中的内容被替换掉。

 

上面是 自动触发,5秒后并且修改次数达到两次,会自动添加到 dump文件

除了这种方式还可以手动触发

涉及到了两个命令 save 和 bgsave

这两个命令的原理是在后台开启了子进程可以去备份文件

 

save和bgsave的区别

  • save 在主程序中会阻塞当前的redis服务器,直到持久化工作完成,在执行save命令期间,redis不能处理其他命令,这样会导致缓存功能的缺失,工作中禁止使用

    image-20240830112328971

     

  • bgsave redis会在后台异步进行快照操作,不阻塞快照同时还可以响应客户端请求,该触发方式会fork() 一个子进程,由子进程复制持久化过程

    image-20240830113602313

 

除了这两个命令,还有一个命令是 lastsave,用来查看最后一次成功执行快照的时间

执行该命令会得到一个时间戳,

将 时间戳转换成时间:date -d @时间戳

 

rdb的优点:

  • 适合大规模的数据恢复

  • 按照业务定时备份

  • 对数据完整性和一致性要求不高

  • RDB文件在内存中的加载速度要比AOF快得多

rdb的缺点:

  • 在一定时间间隔做一次备份,所以如果redis意外宕机,就会丢失从当前到最近一次快照之间的数据。

  • 内存数据的全量同步,如果数据量太大会导致I/O严重影响服务器性能

  • RDB依赖于主进程的fork,在更大的数据集中,这可能会导致服务请求的瞬间延迟,fork的时候内存中的数据被克隆了一份,导致2倍的膨胀性

 

如果dump.rdb 文件在写入的时候毁坏了,比如宕机时正在写入,导致有一部分数据没有写进去

可以使用 redis-check-rdb 命令修复 dump文件

 

触发rdb的情景:

  • 默认配置文件中的自动触发

  • 手动save/bgsave 触发

  • 执行 flushdb/flushall 也会产生dump文件,但里面是空的

  • 执行shutdown且没有开启AOF持久化

  • 主从复制时,主节点自动触发

如果想要禁用rdb,可以在配置文件中将save 注释掉

 

配置文件中 snapshot 的其他配置

  • stop-writes-on-bgsave-error yes 默认是yes,表示当bgsave出现错误时,停止写入,为了保证数据的一致性,如果为no,那么bgsave写入失败,也能继续接收新的写请求

  • rdbcompression yes 默认是yes,表示对dump进行压缩

  • rdbchecksum yes 默认是yes,在存储快照后,让redis使用CRC64算法进行数据校验。但会增加性能消耗

    • rdb-del-sync-files no 默认是no,在没有持久性的情况下删除复制中使用的rdb文件启用

 

 

二、AOF

AOF是以日志的形式来记录每个写操作,读操作不记录,只能追加文件但不能改写文件。Redis启动时会读取该文件重新构建数据,也就是redis重启会根据日志文件的内容,重新执行写的指令完成数据的恢复。

默认情况下,redis没有开启aof,需要在配置文件中配置 appendonly yes

aof的保存文件叫做:appendonly.aof

 

工作流程

image-20240830150506352

  1. Client作为命令的来源,会有多个源头源源不断的请求命令(写操作)

  2. 在这些命令到达Redis Server 以后并不是直接写入AOF文件,会先将这些命令放到AOF缓存中进行保存,这里的AOF 缓存区实际上是内存中的一片区域,存在的目的是当这些命令达到一定量后再写入磁盘,避免频繁的IO操作

  3. aof缓冲会根据aof缓冲区同步文件的三种写回策略将命令写入磁盘上的aof文件

  4. 随着写入aof内容的增加为避免文件膨胀,会根据规则进行命令的合并(又称为aof重写),从而起到aof文件压缩的目的。

  5. 当redis服务器重启时会从aof文件载入数据

 

三种写回策略:

  • Always:同步写回,每个写命令执行完立刻同步地将日志写回磁盘。优点可靠性高,数据基本不丢失,缺点每个写命令都要落盘,性能影响较大

  • everysec:每秒写回,每个命令执行完,先把日志写到aof缓存区,每隔一秒把缓存区内容写入磁盘。优点性能适中,缺点宕机时丢失1秒内的数据。

  • no:操作系统去控制写回,每个命令执行完,只是先把日志写到aof地内存缓冲区,由操作系统决定何时将缓存区内容写回磁盘。优点性能好,缺点宕机丢失数据较多

 

 

配置文件

redis7的新特性:Multi-part AOF

image-20240830155350287

 

开启aof是在配置文件中 将appendonly 设置为yes。默认是no

设置写回策略是 设置 appendfsync,默认是 everysec

 

设置aof文件保存路径:

  • redis6 中aof文件位置和rdb文件位置一致,都是通过配置文件的 dir属性配置

  • redis7之后多了一个配置项是 appenddirname ,就是在 dir配置的目录下再新建一个目录,在该目录下存放aof文件。所以aof文件的目录是 dir+appenddirname

 

设置aof文件名称:

  • redis6时有且仅有一个,用appendfilename配置

  • redis7由于有了 Multi-part AOF 新特性,所以文件结构发生了变化,由原来的单个文件拆分成多个aof文件,分为三个类型

    • BASE:表示基础aof,它一般由子进程通过重写产生,该文件最多只有一个

    • INCR:表示增量aof,一般在aofrw开始执行时被创建,该文件可能存在多个

    • HISTORY:表示历史aof,由BASE 和 INCR变化而来,每次aofrw完成时,本次aofrw之前对应的BASE和INCR aof 都将变成HISTORY,HISTORY类型的aof会被redis自动删除

    为了管理这些aof文件,我们引入了一个 manifest文件来跟踪和管理这些aof

    所以redis7之后一共有三份文件 base基本文件、incr增量文件、manifest清单文件

    这几种文件命名的前缀还是用 appendfilename 来配置

 

数据恢复

当执行写操作时,会在 dir(通过dir配置的文件名)文件下生成 appenddirname,在该目录下会生成三个文件

image-20240830163827295

 

测试恢复:先写几个值,生成了aof文件后,复制一份改个名,清空库,重启redis发现库是空的,然后把之前复制的aof文件改回去,再次重启redis,发现之前写的值回来了

 

进行写操作,会把数据写到 appendonly.aof.1.incr.aof 中

 

上面那种情况是正常恢复,当aof文件发生错误时,该如何恢复呢?

发生错误可以手动给aof文件添加一些错误内容

重启redis之后,发现redis-cli 根本连接不上,而且redis服务也根本没有启动。

也就是说aof文件损坏之后,redis无法启动。如果要修复可以使用

redis-check-aof --fix appendonly.aof.1.incr.aof

修复之后,redis可以启动并连接,之前的数据也回来了

 

aof的优缺点

优点:

  • 使用aof更加持久,有不同的fsync策略

  • aof日志是一个仅附加日志,不会出现断电时损坏的问题,即使出现问题,也可以通过redis-check-aof进行修复

  • 当aof文件变得很大时,redis能够在后台自动重写aof。

  • aof以易于理解和解析的格式依次包含所有操作日志,你甚至可以轻松导出 aof文件,并对其修改

缺点:

  • aof文件通常比相同数据集的等效rdb文件大

  • 根据确切的fsync策略,aof可能比rdb慢

 

aof重写机制

由于aof持久化是redis不断将写命令记录到aof文件中,随着redis的不断进行,aof文件越来越大,占用服务器内存越大以及aof恢复要求时间越长。

为了解决这个问题,redis新增了重写机制,当aof的文件大小超过所设定的峰值时,redis就会自动启动aof文件内容压缩,只保留可以恢复数据的最小指令集(如果命令的key相同,只保留最后一条设置该key对应值的命令,也就是 set k1 v1、set k1 v2、set k1 v3,最后只保留 set k1 v3)

上面那种方式是自动触发重写机制,除此之外还可以使用 bgrewriteaof 手动触发

自动触发需要设置的内容:

  • auto-aof-rewrite-percentage 100

    • 会自动记录上一次重写后aof文件的大小,如果超过了该大小的1倍,就触发

  • auto-aof-rewrite-min-size 64mb

    • 设置aof文件的最大容量,如果超过该容量就触发

上面两个条件必须同时满足才会触发自动重写

 

当aof文件满足上面两个条件,增量文件 appendonly.aof.1.incr.aof 会变成 appendonly.aof.2.incr.aof

基础文件 appendonly.aof.1.base.aof 会变成 appendonly.aof.2.base.aof,2里面存放的就是之前增量文件中的最小指令集

步骤:

image-20240910151114208

给k1 设置值,使aof文件超过1k(我们之前设置了最大容量是1k)

当超过1k并且是上一次重写的1倍后,出发了重写机制,aof文件变成了如下:

image-20240910151421200

基本文件中的内容是:

image-20240910151456510

只有最后的值

 

如果使用 bgrewriteaof 会立刻生成下一个重写文件

 

aof文件重写并不是对原文件进行重新整理,而是直接读取服务器现有的键值对,然后用一条命令去替代之前记录这个键值对的多条命令,生成一个新的文件后去替换原来的文件。

重写原理:

  • 在重写开始前,redis 会创建一个重写子进程,这个子进程会读取现有的aof文件,并将其包含的指令进行分析压缩并写入到一个临时文件。

  • 与此同时,主进程会将新接收到的写指令一边累积到内存缓冲区中,一边继续写入到原有的aof文件,这样做是保证原有的aof文件的可用性,避免在重写过程中出现意外。

  • 当重写子进程完成重写工作后,它会给父进程发一个信号,父进程收到信号后就会将内存中缓存的写指令追加到新aof文件中

  • 当追加结束后,redis就会用新aof文件来代替旧aof文件,之后再写指令,就会追加到新aof文件

 

常用aof配置:

image-20240910152904796

 

三、RDB+AOF 混合持久化

在redis的配置文件中将 aof-use-rdb-preamble 设置为 yes

RDB 镜像做全量持久化,AOF做增量持久化

先使用RDB进行快照存储,然后使用AOF持久化记录所有的写操作,当满足重写机制或手动触发重写时,将最新的数据存储为新的RDB记录。这样的话,重启服务的时候会从 RDB和 AOF 两部分恢复数据,既保证了数据完整性,又提高了恢复数据的性能,简单来说混合持久化方式产生的文件一部分是 RDB 文件,一部分是 AOF 文件

 

纯缓存模式:关闭rdb 和 aof

posted @ 2024-09-11 11:20  GrowthRoad  阅读(37)  评论(0编辑  收藏  举报