Redis 持久化

发布于:2024-04-26 ⋅ 阅读:(25) ⋅ 点赞:(0)

Redis 持久化机制主要有RDB和AOF两种

RDB

RDB 持久化是把当前进程数据⽣成快照保存到硬盘的过程。

RDB 触发机制

命令触发:
①save 命令:阻塞当前 Redis 服务器,直到 RDB 过程完成为⽌,对于内存⽐较⼤的实例造成⻓时间阻塞,基本不采⽤。
②bgsave 命令:Redis 进程执⾏ fork 操作创建⼦进程,RDB 持久化过程由⼦进程负责,完成后⾃动
结束。阻塞只发⽣在 fork 阶段,⼀般时间很短。
⾃动触发:
1.使⽤ save 配置。如 “save m n” 表⽰ m 秒内数据集发⽣了 n 次修改,⾃动 RDB 持久化。
2. 从节点进⾏全量复制操作时,主节点⾃动进⾏ RDB 持久化,随后将 RDB ⽂件内容发送给从结点。
3. 执⾏ shutdown 命令关闭 Redis 时,执⾏ RDB 持久化

RDB 机制流程

由于只有bgsave才会在生产环境下采用,且自动触发的流程也和bgsave指令执行流程一致,故对bgsave指令的执行流程进行说明:

bgsave的执行过程如下:

  1. 执⾏ bgsave 命令,Redis ⽗进程判断当前进是否存在其他正在执⾏的⼦进程,如 RDB/AOF ⼦进
    程,如果存在 bgsave 命令直接返回。
  2. ⽗进程执⾏ fork 创建⼦进程,fork 过程中⽗进程会阻塞,通过 info stats 命令查看latest_fork_usec 选项,可以获取最近⼀次 fork 操作的耗时,单位为微秒。
  3. ⽗进程 fork 完成后,bgsave 命令返回 “Background saving started” 信息并不再阻塞⽗进程,可
    以继续响应其他命令。
  4. ⼦进程创建 RDB ⽂件,根据⽗进程内存⽣成临时快照⽂件,完成后对原有⽂件进⾏原⼦替换。执
    ⾏ lastsave 命令可以获取最后⼀次⽣成 RDB 的时间,对应 info 统计的 rdb_last_save_time 选项。
  5. 进程发送信号给⽗进程表⽰完成,⽗进程更新统计信息
    在这里插入图片描述

RDB 文件处理

RDB ⽂件保存在 dir 配置指定的⽬录(默认 /var/lib/redis/)下,⽂件名通过 dbfilename配置(默认 dump.rdb)指定。可以通过执⾏ config set dir {newDir} 和 config set dbfilename{newFilename} 运⾏期间动态执⾏,当下次运⾏时 RDB ⽂件会保存到新⽬录。
压缩:Redis 默认采⽤ LZF 算法对⽣成的 RDB ⽂件做压缩处理,压缩后的⽂件远远⼩于内存⼤⼩,默认开启。
校验:如果 Redis 启动时加载到损坏的 RDB ⽂件会拒绝启动。这时可以使⽤ Redis 提供的 redischeck-dump ⼯具检测 RDB ⽂件并获取对应的错误报告。

RDB 的优缺点

RDB 是⼀个紧凑压缩的⼆进制⽂件,代表 Redis 在某个时间点上的数据快照。⾮常适⽤于备份,全量复制等场景。⽐如每 6 ⼩时执⾏ bgsave 备份,并把 RDB ⽂件复制到远程机器或者⽂件系统中(如 hdfs)⽤于灾备。
②Redis 加载 RDB 恢复数据远远快于 AOF 的⽅式
③RDB ⽅式数据没办法做到实时持久化 / 秒级持久化。因为 bgsave 每次运⾏都要执⾏ fork 创建⼦进程,属于重量级操作,频繁执⾏成本过⾼
④ RDB ⽂件使⽤特定⼆进制格式保存,Redis 版本演进过程中有多个 RDB 版本,兼容性可能有⻛险

AOF

AOF(Append Only File)持久化:以独⽴⽇志的⽅式记录每次写命令,重启时再重新执⾏ AOF⽂件中的命令达到恢复数据的⽬的。

AOF 触发机制

手动触发:
调⽤ bgrewriteaof 命令。
自动触发:
在 redis.conf配置文件中进行配置。
开启 AOF 功能需要设置配置:appendonly yes,默认不开启。AOF ⽂件名通过appendfilename 配置(默认是 appendonly.aof)设置。保存⽬录同 RDB 持久化⽅式⼀致,通过 dir 配置指定。

AOF ⼯作流程

在这里插入图片描述

  1. 所有的写⼊命令会追加到 aof_buf(缓冲区)中。
  2. AOF 缓冲区根据对应的策略向硬盘做同步操作。
  3. 随着 AOF ⽂件越来越⼤,需要定期对 AOF ⽂件进⾏重写,达到压缩的⽬的。
  4. 当 Redis 服务器启动时,可以加载 AOF ⽂件进⾏数据恢复。

AOF 文件同步

AOF 过程中为什么需要 aof_buf 这个缓冲区?Redis 使⽤单线程响应命令,如果每次写 AOF ⽂件都直接同步硬盘,性能从内存的读写变成 IO 读写,必然会下降。先写⼊缓冲区可以有效减少 IO 次数,同时,Redis 还可以提供多种缓冲区同步策略,让⽤⼾根据⾃⼰的需求做出合理的平衡。

Redis提供了多种AOF缓冲区同步文件策略,主要包括:

Always(always):每次收到写命令时都会同步AOF缓冲区到磁盘。这种策略可以保证数据完全持久化,但会降低性能,因为每次写操作都会引发一次磁盘写入操作。

Everysec(everysec):每秒钟同步一次AOF缓冲区到磁盘。这种策略在性能和持久化之间取得了一种平衡,可以在一定程度上保证数据持久化,同时性能较好。

No(no):不进行AOF缓冲区的同步操作,完全依赖操作系统的缓存机制来处理同步。这种策略性能最好,但是在发生意外断电等情况下可能会导致数据丢失。

Everysec with fsync(每秒同步并强制写入):每秒钟同步一次AOF缓冲区到磁盘,并且在同步完成后执行一次强制写入操作(fsync)。这种策略在保证一定性能的同时,增加了数据的安全性,但相应地增加了磁盘IO的负担。

AOF 重写流程

随着命令不断写⼊ AOF,⽂件会越来越⼤,为了解决这个问题,Redis 引⼊ AOF 重写机制压缩⽂件体积。AOF ⽂件重写是把 Redis 进程内的数据转化为写命令同步到新的 AOF ⽂件。压缩的对象主要针对:进程内已超时的数据、⽆效命令、多条写操作合并为⼀条。 AOF重写的具体流程如下:
在这里插入图片描述

  1. 执⾏ AOF 重写请求。
    如果当前进程正在执⾏ AOF 重写,请求不执⾏。如果当前进程正在执⾏ bgsave 操作,重写命令延迟到 bgsave 完成之后再执⾏。
  2. ⽗进程执⾏ fork 创建⼦进程。
  3. 重写:主进程 fork 之后,继续响应其他命令。所有修改操作写⼊ AOF 缓冲区并根据 appendfsync 策略同步到硬盘,保证旧 AOF ⽂件机制正确。⼦进程只有 fork 之前的所有内存信息,⽗进程中需要将 fork 之后这段时间的修改操作写⼊AOF 重写缓冲区中。
  4. ⼦进程根据内存快照,将命令合并到新的 AOF ⽂件中。
  5. ⼦进程完成重写:新⽂件写⼊后,⼦进程发送信号给⽗进程,⽗进程把 AOF重写缓冲区内临时保存的命令追加到新 AOF ⽂件中,⽤新 AOF ⽂件替换⽼ AOF ⽂件。

服务数据恢复流程

在这里插入图片描述

补充说明

上述的一些自动操作的配置机制往往在redis.conf文件中能找到对应的配置字段

列如:
为了配置 Redis 的 AOF 缓冲区同步文件策略,你需要编辑 Redis 的配置文件,通常是 redis.conf。以下是配置 AOF 缓冲区同步文件策略的具体操作步骤:

①. 打开 Redis 的配置文件 redis.conf。

②. 找到以下配置项中的一项,根据你的需求选择其中一种:

appendonly yes # 启用 AOF 持久化,默认为关闭
appendfsync always # 设置 AOF 缓冲区同步文件策略为 Always
ppendfsync everysec # 设置 AOF 缓冲区同步文件策略为 Everysec
appendfsync no # 设置 AOF 缓冲区同步文件策略为 No
appendfsync everysec # 设置 AOF 缓冲区同步文件策略为 Everysec with fsync
appendonly yes:启用 AOF 持久化。
appendfsync always:设置 AOF 缓冲区同步文件策略为 Always,即每次收到写命令都会同步 AOF 缓冲区到磁盘。
appendfsync everysec:设置 AOF 缓冲区同步文件策略为 Everysec,即每秒钟同步一次 AOF 缓冲区到磁盘。
appendfsync no:设置 AOF 缓冲区同步文件策略为 No,即不进行 AOF 缓冲区的同步操作,完全依赖操作系统的缓存机制。
appendfsync everysec:设置 AOF 缓冲区同步文件策略为 Everysec with fsync,即每秒钟同步一次 AOF 缓冲区到磁盘,并在同步完成后执行一次强制写入操作(fsync)。
③. 根据你的选择,取消或者修改对应配置项的注释,并保存配置文件。

④. 重启 Redis 服务器以应用新的配置。