本页目录
文件慢,先别急着说磁盘慢
第 8 章先把“文件系统”和“磁盘设备”拆开。
一次文件读写,可能卡在很多地方:
- 路径名和目录项查找
- 元数据处理
- 页缓存命中和回写
- 文件系统内部锁和写放大
- 往下游块层发请求之前的等待
所以“文件慢”只说明问题在文件路径上,不足以直接说明问题已经落到设备层。
先把文件 I/O 路径分开
最少要把下面这些位置分开看:
- 应用发起读写
- VFS 和路径查找
- 页缓存命中或失配
- 文件系统内部处理
- 写回和脏页刷新
- 往下游块层发请求
这张路径图不立住,后面看到的延迟就很容易混成一团。
别把写回拖尾、元数据抖动和设备根因混在一起
最常见的错法有四种:
- 一看到 I/O 慢,就直接说磁盘慢
- 一看到写延迟大,就直接认定落盘慢
- 一看到
%iowait,就直接说文件系统是根因 - 把页缓存、写回、元数据和设备服务时间混成一个问题
这些错法都在跳层。
什么时候先怀疑缓存、元数据和写回
下面这些情况,更像文件系统层在制造症状:
- 读写时好时坏,工作负载一变形就抖
- 目录、创建、删除、rename 这类操作异常慢
- 数据写入看起来已经完成,但后台回写开始拖尾
- 上层延迟变差,下游设备却没出现同样程度的异常
这时候先别急着冲到磁盘章,先把文件系统内部路径补全。
一个最典型的错法:把写回拖尾当成设备根因
现场里经常会看到一种情况:应用写延迟突然变差,大家第一反应都是“底层盘不行了”。
但很多时候,前面先变坏的并不是设备服务时间,而是:
- 脏页积压
- 后台回写节奏不稳
- 文件系统内部锁或元数据路径变重
如果这一步不分开,后面就会把文件系统层的问题误读成块设备问题。
还要再补一层更硬的现实: 应用看到的逻辑 I/O 和底层真的发生的物理 I/O,常常不是一回事。记录对齐、读改写、日志保护和元数据更新,都会把很小的一次逻辑写放大成更大的物理读写。现场里最常见的争执,就是应用说“我没写这么多”,存储说“盘上就是这么忙”,中间丢的正是文件系统这层放大。
先把文件路径、元数据和写回拆开
先把文件 I/O 路径画完整
图里至少要有:
- 应用读写
- 路径查找和元数据
- 页缓存
- 文件系统实现
- 写回
- 块层
以后排查文件慢时,先把症状标回这张图。
先把“文件慢”和“设备慢”拆成两组证据
如果更像文件系统层问题,优先找:
- 缓存命中和失配变化
- 元数据操作异常
- 脏页和写回行为
- 文件系统内部等待
再补一个容易被忽略的读方向陷阱: 预取污染。文件系统如果把随机读误判成顺序读,会主动发起应用根本没要的预取 I/O,不只会平白打爆读带宽,还会把原本有用的页缓存冲掉。
如果更像设备层问题,再去看下一章的块层和服务时间。
上层慢、下层不明显时,先别越级
应用层和文件系统层都慢,但块层和设备层还没有同样强的证据时,先停在这一层继续拆。别急着越级宣布硬件根因。
文件路径拆开以后,再看块设备是不是真的慢
第 8 章解决的是“文件路径上哪里可能先变慢”。第 9 章接着解决“块设备、队列和服务时间到底怎么分开看”。