我一直在尝试解决磁盘上的 I/O 问题。设置如下:
- 操作系统:CentOS 5.6
- 磁盘布局:
- 磁盘(
/dev/sda
,/dev/sdb
) - 分割 (
/dev/sda1
,/dev/sdb1
) - MD 阵列 (RAID-1) (
/dev/md0
) - LVM 堆栈 (
/dev/VolGrp00/RootLV
)
- 磁盘(
最初,我注意到,在执行大量 I/O(即mkfs
)时,系统会变得非常缓慢,以至于我无法在 X 会话中移动鼠标指针。我开始记录一些指标,发现平均负载会缓慢上升,在我的双核服务器上最高达到 5.0 以上。同时,我的内存情况从近 2GB 可用变为约 10MB 可用,缓冲区接近 2GB。基于此,我怀疑某种缓存是罪魁祸首,但我对 LVM、MD 和 Linux I/O 子系统的具体细节不够熟悉,不知道从哪里开始查找。
我发现一个奇怪的地方:如果我剥离 LVM 层并直接写入阵列,这似乎无关紧要,甚至删除阵列也没有多大帮助(尽管直接写入分区似乎比写入阵列引起的延迟更短)。
我的大部分测试都是使用命令进行的mkfs.ext4 -i 4096 -m 0 <device>
,但我也使用命令测试了此行为dd if=/dev/urandom bs=4K of=<device>
并得到了类似的结果,因此我很确定这不是 mkfs 的错误。此外,我在另一个系统上尝试过此操作(来自另一个硬件供应商,但仍然是 CentOS 5.6),再次看到了类似的结果。
我可以接受任何导致我的 I/O 操作需要更长时间才能完成的解决方案,但像“使用直接 I/O 标志”这样的答案是不可接受的,因为它们会导致 mkfs 从 10 分钟到 16 小时(我遇到过这种情况,也试过)。我正在寻找调整参数,也在考虑更改 I/O 调度程序,但我认为向社区寻求一些正确方向的指导可能会有所帮助。
编辑 :
事实证明,问题更多地与内存压力和虚拟内存管理器导致 I/O 请求阻塞有关。这是我目前对这个问题的理解:在mkfs
或dd
运行时,它们生成的 I/O 超过磁盘可以跟上的量,因此缓冲区开始填满。当vm.dirty_ratio
达到时,来自所有进程的 I/O 请求开始阻塞,直到缓存清除一些空间(来源)。同时,低内存条件会触发内核开始将进程从物理内存交换到磁盘上……这会产生更多的 I/O,并且这些 I/O 请求可能会在等待缓存清除时被阻塞。
我尝试过调整vm.dirty_ratio
和其他相关参数,但它们只会在系统开始变慢时发生变化(比率越低 = 锁定越快)。我还尝试过更换 I/O 调度程序并调整其参数以尝试更快地清除缓存,但没有成功。作为最后的手段,我尝试使用 运行mkfs
,ionice -c3
但由于运行 时磁盘大多处于空闲状态mkfs
,因此出现了相同的问题。我认为如果有办法限制特定进程的 I/O 请求率,则可以避免速度变慢,但我不知道有什么可以做到这一点。
我当然仍然愿意接受关于尝试的建议 —— 谁能推动我朝着正确的方向发展,谁就会得到绿色的对勾。
另一项编辑:
我偶然发现对照组,但不幸的是它们只能从 RHEL6 开始使用。可以使用 Cgroups 在具有节流块 I/O 的组中启动 mkfs,但由于这些系统暂时必须保留 5.6,我将不得不继续寻找其他解决方案或处理速度缓慢的问题,直到升级为止。
答案1
从您提供的少量详细信息来看,我认为您需要调整 I/O 调度程序。这可能会对您遇到的锁定效果产生重大影响。我相信 CentOS 5.6 使用 CFQ。使用 deadline 可能会减少锁定。