今天主要分享继Redis持久化方式RDB、AOF之后的一些常用的Redis问题定位于优化方式。
这里主要分析开启持久化后的一些Redis常遇到的疑难杂症!
01
Fork操作
当Redis做RDB或AOF重写时,一个必不可少的操作就是执行fork操作创建子进程,对于大多数操作系统来说fork是个重量级操作
虽然fork创建的子进程不需要拷贝父进程的物理内存空间,但是会复制父进程的空间内存页表。例如对于10GB的Redis进程,需要复制大约20MB的内存页表,因此fork 操作耗时跟进程总内存量息息相关,如果使用虚拟化技术,特别是Xen虚拟 机,fork操作会更耗时
在做 RDB 或 AOF 重写时, fork 是必不可少的
对于大多数操作系统来说, fork 是个重量级错误
fork 会复制符进程的空间内存页表
如果使用虚拟化技术, 特别是 Xen 虚拟机, fork 操作会更耗时
fork 耗时问题定位:
高流量的 Redis 实例 ops 可达5万以上
正常情况 fork 耗时应该是每 GB 消耗 20ms 左右
可以用 info stats 命令查看 latest_fork_usec 指标, 获取最近一次 fork 操作耗时, 单位微秒
如何改善 fork 操作的耗时:
优先使用物理机或者高效支持 fork 操作的虚拟化技术, 避免使用 Xen
控制 Redis 实例最大可用内存, fork 耗时跟内存量成正比, 线上建议每个 Redis 实例内存控制在 10GB 以内
合理配置 Linux 内存分配策略, 避免物理内存不足导致 fork 失败, 具体细节见12.1节 “Linux 配置优化”
降低 fork 操作的频率, 如适度放宽 AOF 自动触发时机, 避免不必要的全量复制等
02
AOF追加阻塞
当开启AOF持久化时,常用的同步硬盘的策略是everysec,用于平衡性 能和数据安全性。对于这种方式,Redis使用另一条线程每秒执行fsync同步 硬盘。当系统硬盘资源繁忙时,会造成Redis主线程阻塞!如下图所示
阻塞流程分析:
如果距上次同步成功时间在2秒内,主线程直接返回
如果距上次同步成功时间超过2秒,主线程将会阻塞,直到同步操作完 成。
主线程负责写入AOF缓冲区
AOF线程负责每秒执行一次同步磁盘操作,并记录最近一次同步时 间
主线程负责对比上次AOF同步时间:
通过对AOF阻塞流程可以发现两个问题:
everysec配置最多可能丢失2秒数据,不是1秒
如果系统fsync缓慢,将会导致Redis主线程阻塞影响效率
AOF阻塞问题定位:
每当发生AOF追加阻塞事件发生时,在info Persistence统计中, aof_delayed_fsync指标会累加,查看这个指标方便定位AOF阻塞问题。
AOF同步最多允许2秒的延迟,当延迟发生时说明硬盘存在高负载问 题,可以通过监控工具如iotop,定位消耗硬盘IO资源的进程
发生 AOF 阻塞时, Redis 输出如下日志, 用于记录 AOF fsync 阻塞导致拖慢 Redis 服务的行为
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 追加阻塞事件发生时, 在info Persistence 统计中, aof_delayed_fsync 指标会累加, 查看这个指标方便定位 AOF 阻塞问题
AOF 同步最多允许2秒的延迟, 当延迟发生时说明硬盘存在高负载问题, 可以通过监控工具如 iotop, 定位消耗硬盘 IO 资源的进程
03
多实例部署
Redis 单线程架构导致无法充分利用 CPU 多核特性, 通常的做法是在一台机器上部署多个 Redis 实例。当多个实例开启 AOF 重写后, 彼此之间会产生对 CPU 和 IO 的竞争。本节主要介绍针对这种场景的分析和优化。
优化方式:
- 把子进程工作进行隔离, 具体方法是利用监控程序, 遍历每个 Redis 实例进行同步
监控子进程运行状态的度量指标:
基于以上指标, 可以通过外部程序轮询控制 AOF 重写操作的执行:
说明:
外部程序定时轮询监控机器 (machine) 上所有 Redis 实例
对于开启 AOF 的实例,查看 (aof_current_size-aof_base_size/aof_base_size) 确认增长率
当增长率超过特定阈值 (如100%), 执行 bgrewriteaof 命令手动触发当前实例的 AOF 重写
运行期间循环检查 aof_rewrite_in_progress 和 aof_current_rewrite_time_sec 指标, 直到 AOF 重写结束
确认实例 AOF 重写完成后, 再检查其他实例并重复2)~4)步操作。从而保证机器内每个 Redis 实例 AOF 重写串行化执行
- END -
本文分享自微信公众号 - 码农架构(iByteCoding)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。