快捷搜索:  MTU2Mjc2NDY0Mw`  MTU2MzI2NDE0Mw`  as

面试被问哭:Redis 如何做持久化与恢复?

一、媒介

本文主要讲了 Redis 的持久化相关功能,持久化不停是影响 Redis 机能的高发地,也是口试中常常被问到的。

包括 RDB 相关的特定和优毛病,AOF 的优毛病,事实上,因为 RDB 的数据实时性问题,今朝用 AOF 对照多了,而持久化规复也是优先 AOF。

RDB 是旧的模式,现在基础上都应用 AOF,当然,本日两个都邑一路聊聊。

二、RDB

RDB 流程图:

RDB 特征:

RDB 是一种快照模式,即——保存的是 key value 数据内容。

RDB 有 2 种持久要领,同步 save 模式和异步 bgsave 模式。因为 save 是同步的,以是可以包管数据同等性,而 bgsave 则不能。

save 可以在客户端显式触发,也可以在 shutdown 时自动触发;bgsave 可以在客户端显式触发,也可以经由过程设置设置设备摆设摆设由准时义务触发,也可以在 slave 节点触发。

save 导致 redis 同步壅闭,基础已经废弃。bgsave 则不会导致壅闭,但也有毛病:在 fork 时,必要增添内存办事器开销,由于当内存不敷时,将应用虚拟内存,导致壅闭 Redis 运行。以是,必要包管余暇内存足够。

默认履行 shutdown 时,假如没有开启 AOF,则自动履行 bgsave。

每次的 RDB 文件都是调换的。

关于优化:

Redis 会压缩 RDB 文件,应用 LZF 算法,让终极的 RDB 文件远小于内存大年夜小,默认开启。但会耗损 CPU。

RDB 毛病:

无法秒级持久化。

老版本 Redis 无法兼容新版本 RDB。

RDB 优点:

文件紧凑,得当备份,全量复制场景。例如每 6 小时履行 bgsave,保存到文件系统之类的。

Redis 加载 RDB 规复数据远远快于 AOF。

三、AOF

因为 RDB 的数据实时性问题,AOF(append only file) 是今朝 Redis 持久化的主流要领。

AOF 特征:

默认文件名是 appendonly.aof。和 RDB 一样,保存在设置设置设备摆设摆设中 dir 目录下。

AOF 相对照于 RDB,每次都邑保存写敕令,数据实时性更高。

AOF 因为每次都邑记录写敕令,文件会很大年夜,是以必要进行优化,称之为“重写机制”(下面具体说)。

AOF 每次保存的写敕令都放在一个缓冲区,根据不合的策略(下面具体说)同步到磁盘。

“重写机制” 细节:

fork 子进程(类似 bgsave)

主进程会写到2个缓冲区,一个是原有的 “AOF 缓存区”,一个是专门为子进程筹备的 “AOF 重写缓冲区”;

子进程写到到新的 AOF 文件中,批量的,默认 32m;写完后看护主进程。

主进程把“AOF 重写缓冲区”的数据写到新 AOF 文件中。

将新的 AOF 文件调换老文件。

重写流程图:

缓冲区同步策略,由参数 appendfsync 节制,一共3种:

always:调用系统 fsync 函数,直到同步到硬盘返回;严重影响redis机能。

everysec:先调用 OS write 函数, 写到缓冲区,然后 redis 每秒履行一次 OS fsync 函数。保举应用这种要领。

no: 只履行 write OS 函数,详细同步硬盘策略由 OS 抉择;不保举,数据不安然,轻易损掉数据。

四、持久化规复

AOF 和 RDB 文件都可以用于办事看重启时的数据规复,详细流程如下图:

从图中可以看出优先加载 AOF,当没有 AOF 时才加载 RDB。当 AOF 或者 RDB 存在差错,则加载掉败。

五、问题排查和机能优化

Redis 持久化是影响 Redis 机能的高发地,也是口试中常问的问题。

1、fork 操作

当 Redis 做 RDB 或者 AOF 重写时,一定要进行 fork 操作,对付 OS 来说,fork 都是一个重量级操作。而且,fork 还会拷贝一些数据,虽然不会拷贝主进程所有的物理空间,但会复制主进程的空间内存页表。对付 10GB 的 Redis 进程,必要复制大年夜约 20MB 的内存页表,是以 fork 操作耗时跟进程总内存量相互关注,再加上,假如应用虚拟化技巧,例如 Xen 虚拟机,fork 会加倍耗时。

一个正常的 fork 耗时大年夜概在 20毫秒阁下。为什么呢,假设一个 Redis 实例的 OPS 在 5 万以上,假如 fork 操作耗时在秒级,那么僵拖慢几万条敕令的履行,对临盆情况影响显着。

我们可以在 Info stats 统计中查询 latestforkusec 指标获取近来一次 fork 操作耗时,单位微秒。

若何优化:

优先应用物理机或者高效支持 fork 的虚拟化技巧,避免应用 Xen。

节制 redis 实例最大年夜内存,只管即便节制在 10GB 以内。

合理设置设置设备摆设摆设 Linux 内存分配策略,避免内存不够导致 fork 掉败。

低落 fork 的频率,如适度放宽 AOF 自动触发机会,避免不需要的全量复制。

2、子进程开销

fork 完毕之后,会创建子进程,子进程认真 RDB 或者 AOF 重写,这部分历程主要涉及到 CPU,内存,硬盘三个地方的优化。

CPU 写入文件的历程是 CPU 密集的历程,平日子进程对单核 CPU 使用率靠近 90%。若何优化呢?既然是 CPU 密集型操作,就不要绑定单核 CPU,由于这样会和父 CPU 进行竞争。同时,不要和其他 CPU 密集型办事不是在一个机械上。假如支配了多个 Redis 实例,尽力包管统一时候只有一个子进程履行重写事情。

内存子进程经由过程 fork 操作孕育发生,占用内存大年夜小等同于父进程,理论上必要两倍的内存完成持久化操作,但 Linux 有 copy on write 机制,父子进程会共享相同的物理内存页,当父进程处置惩罚写操作时,会把要改动的页创建对应的副本,而子进程在 fork 操作历程中,共享全部父进程内存快照。即——假如重写历程中存在内存改动操作,父进程认真创建所改动内存页的副本。这里便是内存耗损的地方。若何优化呢?只管即便包管同一时候只有一个子进程在事情;避免大年夜量写入时做重写操作。

硬盘 硬盘开销阐发:子进程主要职责是将 RDB 或者 AOF 文件写入硬盘进行持久化,势必对硬盘造成压力,可经由过程对象例如 iostat,iotop 等,阐发硬盘负载环境。

若何优化:

不要和其他高硬盘负载的办事放在一台机械上,例如 MQ,存储。

AOF 重写时会耗损大年夜量硬盘 IO,可以开启设置设置设备摆设摆设 no-appendfsync-on-rewrite,默认关闭。表示在 AOF 重写时代不做 fsync 操作。

当开启 AOF 的 Redis 在高并发场景下,假如应用通俗机器硬盘,每秒的写速度是 100MB阁下,这时,Redis 的机能瓶颈在硬盘上,建议应用 SSD。

对付单机设置设置设备摆设摆设多个 Redis 实例的环境,可以设置设置设备摆设摆设不合实例分盘存储 AOF 文件,分摊硬盘压力。

3、AOF 追加壅闭

当开启 AOF 持久化时,常用的同步硬盘的策略是“每秒同步” everysec,用于平衡机能和数据安然性,对付这种要领,redis 应用另一条线程每秒履行 fsync 同步硬盘,当系统资本忙碌时,将造成 Redis 主线程壅闭。

流程图如下:

经由过程上图可以发明:everysec 设置设置设备摆设摆设最多可能损掉 2 秒数据,不是 1 秒;假如系统 fsync 迟钝,将会导致 Redis 主线程壅闭影响效率。

问题定位:

发生 AOF 壅闭时,会输入日志。用于记录 AOF fsync 壅闭导致拖慢 Redis 办事的行径。

每当 AOF 追加壅闭事故发生时,在 info Persistence 统计中,aofdelayedfsync 指标会累加,查看这个指标方便定位 AOF 壅闭问题。

AOF 同步最多运行 2 秒的延迟,当延迟发生时阐明硬盘存在机能问题,可经由过程监控对象 iotop 查看,定位耗损 IO 的进程。

4、单机多实例支配

Redis 单线程架构无法充分使用多核CPU,平日的做法是一台机械上支配多个实例,当多个实例开启 AOF 后,彼此之间就会孕育发生CPU 和 IO 的竞争。

若何办理这个问题呢?

让所有实例的 AOF 串行履行。

我们经由过程 info Persistence 中关于 AOF 的信息写出 Shell 脚本,然后串行履行实例的 AOF 持久化。

全部历程如图:

经由过程赓续判断 AOF 的状态,手动履行 AOF 重写,包管 AOF 不会存在竞争。详细的 Shell 编写以及 info 信息判断,可以查看下图:

六、总结

本文主要讲了 Redis 的持久化相关功能,持久化不停是影响 Redis 机能的高发地,也是口试中常常被问到的。包括 RDB 相关的特定和优毛病,AOF 的优毛病,事实上,因为 RDB 的数据实时性问题,今朝用 AOF 对照多了。而持久化规复也是优先 AOF。

关于持久化的问题排查,就很麻烦了,但无非几个方面,fork 耗时,子进程的 CPU,内存,硬盘开销,AOF 的同步壅闭,单机多实例支配。

这些优化,可以经由过程前面写的阐发进行排查。

您可能还会对下面的文章感兴趣: