调试 Linux I/O 延迟

Dol*_*000 13 linux performance latency io

我在管理的几个 Linux 系统上遇到了一些 I/O 问题。它们表现在进程经常在诸如 open()、unlink() 或 close() 之类的简单系统调用中阻塞长达几秒钟的文件(这是一个问题,因为一些涉及的程序需要相当低的 I/O 延迟才能运行适当地)。确实,有问题的系统会遇到一些中等的 I/O 负载,但我很难认为这足以证明如此巨大的延迟时间是合理的。有时,调用可能需要 15 秒以上才能完成(尽管更多情况下可能需要 1、2 或 3 秒左右)。

我的问题是:我怎样才能找出发生这种情况的原因?我想要的是一些工具,它可以告诉我有问题的进程在内核中被什么阻塞,为什么它们休眠的进程很忙,它发生了什么,等等。是否有这样的工具,或者是否有其他尝试调试发生的事情的方法?

另外,当然,如果您有任何线索,其实什么发生的事情,怎么能避免?

作为记录,我使用的文件系统是 XFS。

Dol*_*000 14

现在在适当的时候,我已经设法自己解决了这个问题,所以我至少可以为后代自己跟进。

不幸的是,我在内核升级中丢失了原来的问题,但是却得到了一个新的问题,性能更差,而且同样难以追踪。我发现的技术如下:

首先,blktrace/blkparse是我发现非常有用的工具。它允许跟踪单个 I/O 请求的进度,并提供许多有用的详细信息,例如提交请求的进程。将输出放在 上很有帮助tmpfs,这样跟踪存储的处理就不会开始跟踪本身。

不过,这只是到目前为止,所以我编译了一个具有更多调试功能的内核。特别是,我发现它ftrace非常有帮助,因为它允许我跟踪内核空间内性能不佳的进程,查看它做了什么以及它在哪里阻塞。编译调试内核也提供了工作WCHAN输出ps,这可以作为一种更简单的方式来查看进程在内核内部做什么,至少对于更简单的情况。

我也希望LatencyTop有用,但我发现它有很多问题,而且它只显示了太“高级”而无法真正有用的延迟原因,不幸的是。

此外,我发现它比iostat简单地/sys/block/$DEVICE/stat以非常接近的时间间隔查看内容更有帮助,就像这样:

while :; do cat /sys/block/sda/stat; sleep .1; done
Run Code Online (Sandbox Code Playgroud)

有关文件Documentation/iostats.txt格式,请参见内核源代码树stat。近距离查看它让我可以看到 I/O 突发的确切时间和大小等等。

最后,我发现我在内核升级后遇到的问题是由stable pages引起的,这是 Linux 3.0 中引入的一个特性,在我的情况下,导致 Berkeley DB 在其 mmap'ed 中的脏页时暂停了很长时间区域文件。虽然似乎可以修补这个功能,而且它引起的问题可能会在 Linux 3.9 中得到修复,但我已经解决了我现在遇到的最糟糕的问题,通过修补 Berkeley DB允许我将其区域文件放在不同的目录中(就我而言/dev/shm),让我可以完全避免这个问题。