文章目录
- Redis为什么需要持久化?
- 持久化分类
- RDB(快照snapshot)
- AOF (Append Only File)
- AOF VS RDB
- 混合持久化
- 扩展1:生成RDB快照命令对比
- 扩展2:模拟断电恢复数据
- 扩展3:设置持久化方式为AOF
Redis为什么需要持久化?
Redis是内存数据库,断电即失,这决定了它必须带有持久化的功能。常见持久化方式有两种,分别是rdb与aof。断电即失使得rdb模式下服务器宕机或redis进程意外停止的时候,会丢失部分数据。
持久化分类
Redis分类分为RDB和AOF两种,由于这两种问题都存在问题,后续Redis推出了混合持久化的方式.
RDB(快照snapshot)
RDB文件的触发机制,简单来说,就是决定何时自动创建一个数据库的备份文件(我们称之为RDB文件)的过程。这个机制会在以下几个条件下触发:
- N 秒内数据集至少有 M 个改动(配置文件中可配,最常见的触发方式)
- 执行flushall命令
- 退出redis
以上都会生成备份文件dump.rdb
有了rdb文件后,怎么把rdb文件还原回来?很简单**将rdb文件放在redis的启动目录即可**,生成时默认在启动目录,可以通过config get dir 查看当前文件夹,默认配置基本就够用。
AOF (Append Only File)
该模式下保存的是所有redis的写命令,读的命令不记录。当redis重启的时候会将保存的命令重新执行一遍。恢复原来的数据。AOF的文件名是appendonly.aof。可以配置 Redis 多久才将数据 fsync 到磁盘一次,一般有三个选项:默认是每秒fsync一次,这种策略可以兼顾速度和安全。
由于Redis的只记录写命令,为了去除一些冗余命令,使用AOF作为持久化机制时会有自动重写与手动重写的两种优化方式。先看看什么时候会产生冗余命令,假设:
- 对一个整数键进行自增操作,如 INCR key2,写入 AOF 文件后键的值变为 1。
- 接着再次执行 INCR key2,键的值变为 2。
- 然后执行 DECR key2,键的值又变回 1。
在这个过程中,第二次 INCR 和 DECR 操作产生的命令对于最终数据库状态来说是冗余的,因为只需要第一次 INCR 操作的命令就可以恢复到最终的数据库状态。
除了自动重写,当然AOF还可以手动重写,进入redis客户端执行命令bgrewriteaof重写AOF 。这个过程会fork出一个子进程去做(与bgsave命令类似),不会对redis正常命令处理有太多影响。
AOF VS RDB
对比项 | AOF | RDB |
---|---|---|
可靠性 | 高,因为记录了所有写操作命令,可通过重放命令恢复数据。即使出现故障,丢失的数据相对较少。 | 相对较低,取决于保存 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快照命令对比
对比项 | SAVE | BGSAVE |
---|---|---|
执行方式 | 阻塞 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