为什么Redis执行bgsave时会导致响应延迟增高_排查磁盘I/O瓶颈与文件系统写缓存

云磊君_8070

云磊君_8070

2026-06-11

1004人浏览

原创

bgsave会触发cpu和延迟双高峰,因fork复制页表阻塞父进程、cow引发大量minor page fault、子进程write被i/o队列阻塞;需通过info、iostat、/proc/pid/stack及vm参数调优定位与缓解。

为什么redis执行bgsave时会导致响应延迟增高_排查磁盘i/o瓶颈与文件系统写缓存

bgsave 本身不直接写磁盘,但 fork + COW + 写入 RDB 文件的整条链路,会在特定条件下显著拖慢 Redis 响应——核心矛盾不在“是否写盘”,而在“何时写、怎么写、写多少”。

为什么 bgsave 会触发 CPU 和延迟双高峰

执行 bgsave 时,Redis 父进程调用 fork() 创建子进程,子进程继承父进程内存页表(只读),随后开始将内存数据序列化写入临时 RDB 文件。关键点在于:

  • fork 阶段:若 Redis 占用内存大(比如 >10GB)、写负载高,内核需为子进程复制页表并标记所有内存页为 COW(Copy-on-Write)。这个过程本身就会短暂阻塞父进程,尤其在内存碎片率高或 NUMA 架构下更明显
  • COW 后续开销:一旦父进程修改任意被共享的内存页(如写新 key、更新过期时间),内核必须立刻为该页分配新物理内存并复制内容——这会引发大量 minor page fault,CPU 被频繁打断
  • 子进程写盘:虽然子进程独立运行,但其 write() 系统调用最终仍走内核页缓存,若系统 I/O 负载已高(如其他进程刷脏页、日志写入、swap 活跃),write() 可能被阻塞在 dirty_ratio 或 congested 状态,导致子进程 hang 住,进而影响父进程调度(尤其在单核或 CPU 绑核场景)

如何确认是 bgsave 引发的 I/O 瓶颈而非网络或业务问题

先排除干扰项,再聚焦 I/O:

Redis Skill - 高性能缓存管理
Redis Skill - 高性能缓存管理

Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。

下载
  • 查 redis-cli info persistence 中的 rdb_bgsave_in_progress 和 rdb_last_bgsave_status,确认是否正在执行或最近失败过
  • 比对监控图:把 Redis 的 latency(如 redis-cli --latency 输出的 P99)和系统 iostat -x 1 的 %util、await、avgqu-sz 曲线叠在一起——若每次 bgsave 开始后 await 突增且 avgqu-sz > 1,基本锁定 I/O 队列积压
  • 看 /proc/[redis-pid]/stack:在延迟高峰时执行 cat /proc/$(pgrep redis-server)/stack,若看到大量 wait_on_page_bit、io_schedule、ext4_writepages,说明主线程或子进程卡在文件系统层
  • 注意 swap:即使没显式启用 swap,vm.swappiness=1 也可能让内核在内存压力下回收 file cache,间接加剧 writeback 压力;检查 grep -i "swapped\|pgpg" /proc/vmstat

file system write cache 设置不当会放大 bgsave 影响

Linux 默认使用 page cache 缓冲写入,但它的行为受多个参数控制,配置不合理会让 bgsave 的写放大效应翻倍:

  • vm.dirty_ratio(默认 20%):当脏页占系统内存比例超此值,内核强制同步刷盘——若 Redis 内存占主机 70%,那只需 14% 的脏页就触发阻塞式 writeback,而 bgsave 子进程正是主力产脏者
  • vm.dirty_background_ratio(默认 10%):低于此值时不主动刷,但一超过就开始后台异步刷;若设得太低(如 5%),会导致 writeback 线程常年满负荷,抢占 I/O 带宽
  • ext4 挂载选项:data=ordered(默认)会在 commit 日志前先把文件数据写入 page cache,加重脏页压力;data=writeback 可降低延迟但牺牲崩溃一致性——生产环境慎用
  • SSD 场景下,vm.vfs_cache_pressure=50(默认 100)可减少 dentry/inode 缓存回收,避免因目录项缓存不足导致 ext4 查找路径变慢,间接缓解 writeback 延迟

真正有效的缓解手段不是关 bgsave,而是切分压力源头

线上不能停持久化,但可以隔离影响面:

  • 主从分离:让主节点关闭 save 配置(即禁用自动 bgsave),仅靠 AOF + 从节点 RDB 备份;从节点开启 save 并调大 save 时间间隔(如 save 900 1 → save 3600 1),避开业务高峰
  • 调整 fork 行为:在 /etc/sysctl.conf 中设 vm.overcommit_memory=1(允许 fork 时乐观分配),配合 echo never > /sys/kernel/mm/transparent_hugepage/enabled 关闭 THP——后者能大幅降低 fork 时的内存拷贝开销
  • 限制子进程 I/O 优先级:启动 Redis 前加 ionice -c2 -n7,让 bgsave 子进程使用 idle I/O class,避免抢占业务请求的磁盘带宽
  • RDB 文件位置:不要和系统盘、数据库日志盘共用物理设备;若用云盘,确保是专用 EBS gp3/io2 卷,并开启 queue_depth 调优(AWS 上设 nvme_core.default_ps_max_latency_us=0)

最容易被忽略的是:bgsave 的延迟不是“固定值”,它随内存使用率非线性增长——当 used_memory_rss_human / total_system_memory > 0.7 时,fork 开销可能从毫秒级跳到数百毫秒,而多数人只盯着 used_memory_human 看,漏掉了 RSS 和碎片率这两个关键信号。

相关专题

更多
常用的数据库软件
常用的数据库软件

常用的数据库软件有MySQL、Oracle、SQL Server、PostgreSQL、MongoDB、Redis、Cassandra、Hadoop、Spark和Amazon DynamoDB。更多关于数据库软件的内容详情请看本专题下面的文章。php中文网欢迎大家前来学习。

2023.11.02

4269

19

内存数据库有哪些
内存数据库有哪些

内存数据库有Redis、Memcached、Apache Ignite、VoltDB、TimesTen、H2 Database、Aerospike、Oracle TimesTen In-Memory Database、SAP HANA和ache Cassandra。更多关于内存数据库相关问题,详情请看本专题下面的文章。php中文网欢迎大家前来学习。

2023.11.14

3775

11

mongodb和redis哪个读取速度快
mongodb和redis哪个读取速度快

redis 的读取速度比 mongodb 更快。原因包括:1. redis 使用简单的键值存储,而 mongodb 存储 json 格式的数据,需要解析和反序列化。2. redis 使用哈希表快速查找数据,而 mongodb 使用 b-tree 索引。因此,redis 在需要高性能读取操作的应用程序中是一个更好的选择。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.04.02

6812

6

redis怎么做缓存服务器
redis怎么做缓存服务器

redis 作为缓存服务器的答案:redis 是一款开源、高性能、分布式的键值存储,可作为缓存服务器使用。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.04.07

623

6

redis怎么解决数据一致性
redis怎么解决数据一致性

redis 提供了两种一致性模型,以维护副本数据一致性:强一致性 (sync) 确保写操作仅在复制到所有从节点后才完成;最终一致性 (async) 则在主节点上写操作后认为已完成,牺牲一致性换取性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.04.07

736

6

mysql和redis怎么保证双写一致性
mysql和redis怎么保证双写一致性

确保 mysql 和 redis 双写一致性的技术包括:1、事务性更新:同时更新 mysql 和 redis,保证一致性;2、主从复制:mysql 主服务器更改同步到 redis 从服务器;3、基于事件的更新:mysql 记录更改并发送到 redis等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.04.07

6422

6

redis缓存一般存些什么数据
redis缓存一般存些什么数据

redis缓存中存储的数据类型包括:字符串、哈希、列表、集合、有序集合、位图、地理空间数据和hyperloglog。这些数据类型适用于存储各种数据,从简单信息到复杂对象和地理位置。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.04.07

1140

6

redis的8种数据类型有哪些
redis的8种数据类型有哪些

redis 提供 8 种数据类型:字符串(文本、数字、二进制)、哈希(键值对)、列表(有序集合)、集合(无序唯一元素)、有序集合(按分数排序)、地理空间(地理位置)、hyperloglog(估计大数据基数)和位图(位序列存储)。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.04.07

1016

6

redis主要作用有哪些
redis主要作用有哪些

redis 的主要作用包括:1. 缓存数据,提高访问速度;2. 充当消息队列,实现消息传递;3. 存储各种数据类型,如字符串、散列和集合;4. 管理会话信息,确保可靠性和可用性;5. 限制请求速率,防止服务器超载等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.04.07

5738

6

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
phpEnv手册
phpEnv手册

共0课时 | 0人学习

进程与SOCKET
进程与SOCKET

共6课时 | 0.5万人学习