20220730-Redis面试宝典-持久化篇

在这里插入图片描述

一:Redis持久化有哪些方式?
二:RDB持久化触发方式有哪些?
三:RDB持久化优缺点?
四:简述bgsave过程?
五:简述AOF工作流程?
六:AOF缓冲区同步文件策略有哪些?
七:AOF重写触发条件?
八:简述AOF重写过程?
九:RDB和AOF持久化文件损坏如何处理?

一: Redis持久化有哪些方式?

1.RDB 持久化

将当前进程数据生成快照保存到硬盘。

2.AOF 持久化 (append only file)

以独立日志方式记录每次写命令,重启时再重新执行 AOF 文件中的命令达到恢复数据的目的。 AOF 的主要作用是解决了数据持久化的实时性,目前已经是 Redis 持久化的主流方式。

二: RDB 持久化触发方式有哪些?

触发 RDB 持久化过程分为手动触发和自动触发。
手动触发命令有 save 和 bgsave :

save 命令:

阻塞当前 Redis 服务器,直到 RDB 过程完成为止,对于内存较大的实例会造成长时间阻塞,线上环境不建议使用,运行 save 命令对于 Redis 日志如下 :

* DB saved on disk

bgsave 命令:

Redis 进程执行 fork 操作创建子进程, RDB 持久化过程由子进程负责,完成后自动结束。
阻塞只发生 fork 阶段,一般时间较短。运行 bgsave 命令对应 redis 日志如下 :

* Backgroup saving start by pid xxx
* DB saved on disk
* RDB:0 MB of memory used by copy-on-write
* Backgroup saving terminated with success

RDB 自动触发有如下几个场景:

  1. 使用 save 相关配置,如 save m n 。表示 m 秒内数据集存在 n 次修改时,自动触发 bgsave 。
  2. 从节点执行全量复制操作,主节点自动执行 bgsave 生成 RDB 文件并发送给从节点。
  3. 执行 debug reload 命令重新加载 redis 时。
  4. 默认情况下执行 shutdown 命令时,如果没有开启 AOF 持久化功能,则自动执行 bgsave 。

三: RDB 持久化优缺点?

优点 :

1.RDB 是一个紧凑压缩的二进制文件,代表 Redis 在某个时间点上的数据快照,适合用于备份,全量复制等场景。
2.Redis 加载 RDB 恢复数据远远快于 AOF 的方式。

缺点:

1.RDB 方式数据没办法做到实时持久化 / 秒级持久化。
2.bgsave 每次运行都需要执行 fork 操作创建子进程,属于重量级操作,频繁执行成本过高。
3.RDB 文件使用特定二进制格式保存, Redis 版本演进过程中有多个格式 RDB 版本,存在老版本 Redis 服务无法兼容新版本 RDB 格式的问题。

四:简述 bgsave 过程?

  1. 执行 bgsave 命令, Redis 父进程判断当前是否存在正在执行的子进程,如果 RDB/AOF 子进程,如果存在,直接返回。
  2. 父进程执行 fork 操作创建子进程, fork 操作过程中父进程会阻塞,通过 info stats 命令查看 lastest_fork_usec 选项,可以获取最近一个 fork 操作耗时,单位为微秒。
    fork 创建子进程不需要拷贝父进程物理内存空间,但是会复制父进程空间内存页表。例如 10GB 的 redis 进程,需要复制大约 20MB 的内存页表,因此 fork 操作耗时跟进程总内存量息息相关。
    对于高流量的 redis 实例 OPS(operation per second 每秒操作次数 ) 可达 5 万以上,如果 fork 操作耗时在秒级别,将会拖慢 redis 几万条命令执行。正常情况下 fork 耗时应该是每 GB 耗时 20 毫秒左右。
  3. 父进程 fork 完成后, bgsave 命令返回” Backgroup saving started “信息并不再阻塞父进程,可以继续响应其他命令。
  4. 子进程创建 RDB 文件,根据父进程内存生成临时快照文件,完成后对原有文件进行原子替换。执行 lastsave 命令可以获取最后一次生成 RDB 时间,对应 inof 统计的 rdb_last_save_time 选项。
  5. 进程发送信号给父进程表示完成,父进程更新统计信息,具体见 info Persistence 下的 rdb_* 相关选项。

五:简述 AOF 工作流程

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

六: AOF 缓冲区同步文件策略有哪些?

由参数 appendfsync 控制,主要有下面三种配置:

1.always

命令写入 aof_buf 后调用系统 fsync 操作同步到 AOF 文件, fsync 完成后返回。

2.everysec

命令写入 aof_buf 后调用系统 write 操作, write 完成后线程返回。 fsync 同步文件操作由专门线程每秒调用一次。这也是建议的同步策略,也是默认配置,做到兼顾性能和数据安全性。

3.no

命令写入 aof_buf 调用系统 write 操作,不对 AOF 文件做 fsync 同步,同步硬盘操作由操作系统负责,通常同步周期最长 30 秒。

七: AOF 重写触发条件?

手动触发:

直接调用 bgrewriteaof 命令。

自动触发:

根据 auto-aof-rewrite-min-size 和 auto-aof-rewrite-percentage 参数确定自动触发时机。
其中:
auto-aof-rewrite-min-size: 表示运作 AOF 重写时文件最小体积,默认 64MB 。
Auto-aof-rewrite-percentage: 表示运行 AOF 文件空间 (aof_current_size) 和上一次重写后 AOF 空间 (aof_base_size) 的比值。
自动触发时间 = aof_current_size > auto-aof-rewrite-min-size && (aof_current_size - aof_base_size) / aof_base_size >= auto-aof-rewrite-percentage 。
其中 aof_current_size 和 aof_base_size 可以在 info Persistence 统计信息中查看。

八:简述 AOF 重写过程

  1. 执行 AOF 重写请求。
    如果当前进程正在执行 AOF 重写,请求不执行并返回如下响应 :
    ERR Backgroud append only file rewriting already in progress
    如果当前进程正在执行 bgsave 操作,重写命令延时到 bgsave 完成之后再执行,返回如下响应: Background append only file rewriting scheduled
  2. 父进程执行 fork 创建子进程,开销等同于 bgsave 过程。
  3. 主进程 fork 操作完成后,继续响应其他命令。所有修改命令依然写入 AOF 缓冲区,并根据 appendfsync 策略同步到硬盘,保证原有 AOF 机制正确性。
    由于 fork 操作运用写时复制技术,子进程只能共享 fork 操作时的内存数据。由于父进程依然响应命令, Redis 使用 AOF 重写缓冲区保存这部分新数据,防止新 AOF 文件生成期间丢失这部分数据。
  4. 子进程根据内存快照,按照命令合并规则写入到新 AOF 文件。每次批量写入硬盘数据量由配置 aof-rewrite-incremental-fsync 控制,默认 32MB ,防止单次刷盘数据过多造成硬盘阻塞。
  5. 新 AOF 文件写入完成后,子进程发送信号给父进程,父进程更新统计信息,具体见 info persistence 下的 aof_* 相关统计。
    父进程把 AOF 重写缓冲区的数据写入到新的 AOF 文件。
    使用新 AOF 文件替换老文件,完成 AOF 重写。

九: RDB 和 AOF 持久化文件损坏如何处理?

1.RDB 文件损坏

RDB 文件保存位置在 dir 配置指定的目录下,文件名通过 dbfilename 配置指定。
可以通过执行 config set dir {newDir} 和 confg set dbfilename {newFileName} 动态修改,当下次运行 RDB 文件会保存到新目录。
当遇到坏盘或磁盘写满等情况,可以通过 config set dir {newDir} 在线修改文件路径到可用磁盘路径,之后执行 bgsave 进行磁盘切换,同样适用于 AOF 持久化文件。
如果在 redis 启动时加载的 RDB 文件已经损坏,会拒绝启动,并打印如下日志:

Short read or OOM loading DB. Unrecoverable error,aborting now.

这时可以使用 redis 提供的 redis-check-dump 工具检测 RDB 文件并获取对应的错误报告。

2.AOF 文件损坏

对于错误格式的 AOF 文件,先进行备份,然后采用 redis-check-aof --fix 命令进行修复,修复后使用 diff -u 对比数据差异,找出丢失数据,有些可以人工修补全。
AOF 文件可能存在结尾不完整的情况,比如机器突然断电导致 AOF 尾部文件命令写入不全。 Redis 提供了 aof-load-truncated 配置来兼容这种情况,默认开启。加载 AOF 时,当遇到此问题时会忽略并继续启动,同时打印如下警告日志 :

# !!! Warning: short read while loading the AOF file !!!
# !!! Truncatin the AOF at offset xxxxxx!!!
# AOF loaded anyway because aof-load-truncated is enabled

十:简述 AOF 追加阻塞

当开启 AOF 持久化时,常用的同步硬盘的策略是 everysec ,用于平衡性能和数据安全性。对于这种方式, Redis 使用另一条线程每秒执行 fsync 同步硬盘。当系统硬盘资源繁忙时,会造成 redis 主线程阻塞。
阻塞流程分析:

  1. 主线程负责写入 AOF 缓冲区。
    2.AOF 线程负责每秒执行一次同步磁盘操作,并记录最近一次同步时间。
  2. 主线程负责对比上次 AOF 同步时间 :

如果距离上次同步成功时间在 2 秒内,主线程直接返回。
如果距离上次同步成功时间超过 2 秒,主线程将会阻塞,直到同步完成。
当发生 AOF 追加阻塞时,在 info Persistence 统计中, aof_delayed_fsync 指标会累加,查看这个指标方便定位 AOF 阻塞问题。日志会提示如下内容 :

Asynchronous AOF fsync is taking too long (disk is busy?). Writing the AOF buffer without waiting for fsync to complete,this may slow down Redis.

通过 AOF 阻塞流程可以发现两个问题:
1.everysec 配置最多可能丢失 2 秒数据,不是 1 秒。
2. 如果系统 fsync 缓慢,将会导致 Redis 主线程阻塞,影响效率。

参考:

《 Redis 开发与运维》
欢迎关注我的公众号《IT小Chen

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值