在外部磁盘上执行大量读/写操作时系统滞后

在外部磁盘上执行大量读/写操作时系统滞后

在 Ubuntu 18.04 系统上执行大型磁盘映像操作时,我遇到了一些系统范围的延迟/滞后问题。这是系统规格:

处理器:Intel Core i7(任何核心都不会接近容量)

内存:12GB(切勿接近容量)

系统盘:SSD(切勿接近容量)

外部磁盘:USB 3.0 5400 和 7200RPM 旋转磁盘

这些大型磁盘映像操作基本上是:

nice ionice dd if=/dev/usbdisk1 of=/dev/usbdisk2

由于我的系统文件都不位于任何 USB 磁盘上,因此从理论上讲,这不会带来太多延迟。但我发现当我对多个 USB 磁盘进行映像时,系统就会变得缓慢。为什么?我的理解是每个磁盘都有自己的IO队列,那么这里是怎么回事呢?我该如何补救?

另外,FWIW,我根本不关心 USB 磁盘的成像速度,因此减慢这些操作以有利于系统平稳运行的解决方案对我来说很好。

答案1

我该如何补救?

当您写入磁盘映像时,请使用ddwith oflag=direct。 O_DIRECT 写入将避免通过页缓存写入数据。注意oflag=direct需要更大的块大小,才能获得良好的性能。这是一个例子:

dd if=/dev/usbdisk1 of=/dev/usbdisk2 oflag=direct bs=32M status=progress

注意:有时您可能希望从另一个程序(例如gunzip.在这种情况下,良好的性能还取决于iflag=fullblock并通过另一个dd命令进行管道传输。这里的答案中有一个完整的例子:为什么从gunzip到dd管道最后会变慢?

(另一种解决方案是使用oflag=sync代替oflag=direct。这可以通过不构建大量不成文缓存页面)。

我的理解是每个磁盘都有自己的IO队列,那么这里是怎么回事呢?

他们是这样。但是,写入的数据首先存储在系统页缓存(RAM 中)中,然后再对 IO 进行排队...


编辑:

由于这个答案被接受,我假设您重新测试了oflag=direct,它解决了您的问题“系统刚刚爬行”。伟大的。

iflag=direct最安全的选择是也添加。没有这个选项, dd仍然是阅读数据通过系统页面缓存。我假设您没有在没有告诉我的情况下添加此选项。这是对您的具体问题的一种暗示。

应该清楚的是通过页缓存读取了过多的数据可以影响系统性能。您通过页面缓存推送的数据总量比系统 RAM 大几倍:-)。根据读取模式,内核可能决定开始删除(或交换)其他缓存数据以腾出空间。

内核没有绝对正确的远见。如果您需要使用从缓存中删除的数据,则必须从磁盘/SSD 重新加载它。证据似乎告诉我们这不是你的问题。

脏页缓存限制

但是,您的问题更有可能与写作数据通过页面缓存。未写缓存,又名“脏”页缓存,是有限的。例如,您可以想象整个脏页缓存限制为 RAM 的 20%。 (这是方便想象的谎言,真相写得乱七八糟这里)。

如果您的dd命令设法填充最大脏页缓存,它们将被迫“阻塞”(等待),直到某些数据被写出。

但同时,任何其他想要写入的程序也会被阻止(除非它使用 O_DIRECT)。这可能会导致许多桌面程序停止运行,例如当它们尝试写入日志文件时。即使他们正在写入不同的设备。

总体脏限制被命名为dirty_ratioor dirty_bytes。但整个故事要复杂得多。不同设备的脏缓存之间应该存在某种程度的仲裁。有较早的阈值启动,并尝试限制任何一台设备使用的最大脏缓存的比例。但很难确切地理解这一切的运作效果如何。

我认为您提到在对“多个 USB 磁盘”进行映像时遇到问题。例如,当您尝试写入其中一个磁盘时,每设备阈值可能运行良好,但一旦同时写入多个磁盘,就会崩溃。但这只是一个想法;我不知道到底发生了什么。

有关的:

一些用户观察到,当写入速度较慢的 USB 盘时,整个系统会出现延迟,并发现降低总体脏限制有助于避免延迟。我不知道对此有什么好的解释。

为什么 2013 年会出现“U 盘失速”问题?为什么现有的“无 I/O 脏节流”代码没有解决这个问题?

“写回限制”是解决“USB 存储卡停顿问题”的方法吗?

相关内容