Redis为什么需要持久化?

Redis是内存数据库,断电即失,这决定了它必须带有持久化的功能。常见持久化方式有两种,分别是rdb与aof。断电即失使得rdb模式下服务器宕机或redis进程意外停止的时候,会丢失部分数据。

持久化分类

Redis分类分为RDBAOF两种,由于这两种问题都存在问题,后续Redis推出了混合持久化的方式.

RDB(快照snapshot)

RDB文件的触发机制,简单来说,就是决定何时自动创建一个数据库的备份文件(我们称之为RDB文件)的过程。这个机制会在以下几个条件下触发:

  1. N 秒内数据集至少有 M 个改动(配置文件中可配,最常见的触发方式)
  2. 执行flushall命令
  3. 退出redis

以上都会生成备份文件dump.rdb

有了rdb文件后,怎么把rdb文件还原回来?很简单**将rdb文件放在redis的启动目录即可**,生成时默认在启动目录,可以通过config get dir 查看当前文件夹,默认配置基本就够用。

AOF (Append Only File)

该模式下保存的是所有redis的写命令,读的命令不记录。当redis重启的时候会将保存的命令重新执行一遍。恢复原来的数据。AOF的文件名是appendonly.aof。可以配置 Redis 多久才将数据 fsync 到磁盘一次,一般有三个选项:默认是每秒fsync一次,这种策略可以兼顾速度和安全。

由于Redis的只记录写命令,为了去除一些冗余命令,使用AOF作为持久化机制时会有自动重写与手动重写的两种优化方式。先看看什么时候会产生冗余命令,假设:

  1. 对一个整数键进行自增操作,如 INCR key2,写入 AOF 文件后键的值变为 1。
  2. 接着再次执行 INCR key2,键的值变为 2。
  3. 然后执行 DECR key2,键的值又变回 1。

在这个过程中,第二次 INCR 和 DECR 操作产生的命令对于最终数据库状态来说是冗余的,因为只需要第一次 INCR 操作的命令就可以恢复到最终的数据库状态。

除了自动重写,当然AOF还可以手动重写,进入redis客户端执行命令bgrewriteaof重写AOF 。这个过程会fork出一个子进程去做(与bgsave命令类似),不会对redis正常命令处理有太多影响。

AOF VS RDB

对比项AOFRDB
可靠性高,因为记录了所有写操作命令,可通过重放命令恢复数据。即使出现故障,丢失的数据相对较少。相对较低,取决于保存 RDB 的时间间隔,可能会丢失间隔期间的数据。
性能写入操作会带来一定的性能开销,尤其是在always
同步策略下。
在保存 RDB 时会fork子进程,会有短暂的性能影响,但总体对性能的影响相对较小。
存储空间占用通常比 RDB 大,因为记录了所有写操作。相对较小,只保存数据库在某一时刻的快照。
恢复时间相对较长,因为需要重放所有的写操作命令。通常较短,因为只需加载快照文件即可恢复数据库状态。

混合持久化

通过上方的表格可以清晰的看到,混合持久化要解决的问题是RDB的可靠性低,AOF的恢复时间慢的问题。

重启 Redis 时,很少使用 RDB来恢复内存状态,因为会丢失大量数据。通常使用AOF日志重放,但是重放AOF日志性能相对 RDB来说要慢很多,这样在 Redis 实例很大的情况下,启动需要花费很长的时间。 Redis 4.0 为了解决这个问题,带来了一个新的持久化选项——混合持久化。 通过如下配置可以开启混合持久化(必须先开启aof):aof‐use‐rdb‐preamble yes

如果开启了混合持久化,AOF在重写时,不再是单纯将内存数据转换为RESP命令写入AOF文件,而是将重写这一刻之前的内存做RDB快照处理,并且将RDB快照内容和增量的AOF修改内存数据的命令存在一 起(rdb在前,aof在后,都写入新的AOF文件,新的文件一开始不叫appendonly.aof,等到重写完新的AOF文件才会进行改名,覆盖原有的AOF文件,完成新旧两个AOF文件的替换。

于是在** Redis 重启的时候,可以先加载 RDB 的内容,然后再重放增量 AOF 日志就可以完全替代之前的 AOF 全量文件重放,因此重启效率大幅得到提升**。

混合持久化AOF文件结构如下:

扩展1:生成RDB快照命令对比

对比项SAVEBGSAVE
执行方式阻塞 Redis 服务器,直到 RDB 文件创建完毕在后台异步执行,不阻塞服务器
对性能影响严重影响服务器性能,阻塞所有客户端请求对服务器性能影响相对较小,不影响正常服务
资源消耗相对较少会 fork 子进程,消耗一定系统资源,特别是内存
数据一致性能保证数据一致性,但执行过程中可能延迟新写入操作由于在后台执行,数据一致性可能稍弱
适用场景无高并发请求时,如重要数据备份或服务器维护前生产环境,服务器运行期间需创建 RDB 快照且不能中断服务

总的来说,<font style="color:rgba(0, 0, 0, 0.85);">BGSAVE</font>是一种更常用的生成 RDB 快照的方式,因为它不会阻塞服务器,对性能的影响较小。但是,在某些特殊情况下,如需要立即创建一个可靠的 RDB 快照且可以接受服务器暂时不可用时,可以使用<font style="color:rgba(0, 0, 0, 0.85);">SAVE</font>命令。

扩展2:模拟断电恢复数据

先删除原来的持久化文件

模拟写操作,往redis中写入数据

此时可以看到重新生成了持久化文件

直接关闭进程,重启redis,根据上文可以知道redis重启会自动将持久化的数据恢复。使用get命令获取到了断电之前设置的数据

扩展3:设置持久化方式为AOF

首先Redis默认采用的是RDB的持久化方式,所以要把图中的no改为yes

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部