字节面试:Redis为什么要持久化?有几种方式?

文章目录

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

对比项 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

相关推荐
编程、小哥哥31 分钟前
设计模式之抽象工厂模式(替换Redis双集群升级,代理类抽象场景)
redis·设计模式·抽象工厂模式
李老头探索37 分钟前
Java面试之Java中实现多线程有几种方法
java·开发语言·面试
水月梦镜花13 小时前
redis:list列表命令和内部编码
数据库·redis·list
测试199813 小时前
2024软件测试面试热点问题
自动化测试·软件测试·python·测试工具·面试·职场和发展·压力测试
马剑威(威哥爱编程)14 小时前
MongoDB面试专题33道解析
数据库·mongodb·面试
掘金-我是哪吒14 小时前
微服务mysql,redis,elasticsearch, kibana,cassandra,mongodb, kafka
redis·mysql·mongodb·elasticsearch·微服务
独行soc16 小时前
#渗透测试#SRC漏洞挖掘#深入挖掘XSS漏洞02之测试流程
web安全·面试·渗透测试·xss·漏洞挖掘·1024程序员节
ketil2716 小时前
Ubuntu 安装 redis
redis
理想不理想v16 小时前
‌Vue 3相比Vue 2的主要改进‌?
前端·javascript·vue.js·面试
sszmvb123417 小时前
测试开发 | 电商业务性能测试: Jmeter 参数化功能实现注册登录的数据驱动
jmeter·面试·职场和发展