复制大量数据时传输速率降低

use*_*126 9 performance hard-drive transfer iowait

我使用的是 Ubuntu 16.04.3 LTS 系统(4.10.0-40-generic),每个磁盘上有两个 HDD 和几个分区。当我在两个磁盘之间复制数据 (<5GB) 时,我的传输速率约为 70 MB/s。但是,当我尝试将大量数据 (>30GB) 从一个磁盘复制到另一个磁盘时,我注意到了几个性能问题。

我的问题是这种行为在 Linux 系统中是否正常并且是预期的?
谁能向我解释这一点并建议我如何避免这种性能下降?

下面我将描述我的观察。在示例中,我将 54GB 的磁盘映像文件从 sda8(325 GB 分区)复制到 sdb8(1.6TB 分区)

1) 传输速率降低,iowait 增加
当我尝试复制超过 50 GB 时,我注意到传输速率逐渐降低。我正在使用glances、atop、iotop 和iostat 监控性能。在 30GB 进程中,传输速率下降到 58 MB/s、46 GB 到 36MB/s、52GB 到 12 MB/s。之后,传输速率真正开始波动并降至 1MB/s 以下。同时我看到 iowait 从最初的 0% 增加到最后的 62%。在复制磁盘 sd8 期间,“忙碌”百分比在 40% 到 60% 之间。磁盘 sdb 一直处于 100% 忙碌状态。不仅传输速率下降,而且我的系统响应也变慢了。我希望 iowait 是造成这种情况的原因。
这是正常行为吗?如何避免性能下降?

2) IOwait 复制后保持高位
当复制结束时,我注意到 iowait 仍然很高,并逐渐开始降低到正常值。这需要几分钟。我认为在那段时间数据仍然以大约 1 或 2 MB/s 的速率写入 sdb。使用 iotop 看起来进程“jdb2/sdb4-8”正在导致此磁盘写入。在 IOwait 减少期间,我的系统仍然响应不良。还可以看到磁盘 sda 不再繁忙,但磁盘 sdb 仍以 100% 繁忙运行。
是什么导致我的系统在复制操作后几分钟内响应不佳?
这可以避免吗?

3) 从网络驱动器复制会增加效果
当我尝试从 Synology NAS 复制到本地磁盘 (sdb8) 时,效果更糟。首先将网络驱动器安装到我的系统,然后开始复制。最初也实现了 70MB/s 的传输速率,但传输速率下降得更快。在几 GB 之后,传输速率已远低于 1 MB/s。尝试使用从 Nautilus 拖放、命令“cp”、命令 rsync、FreeFileSync 应用程序进行复制,但都表现出较差的性能。
使用网络驱动器性能下降效果更差的原因可能是什么?

附加信息
复制期间使用“iostat -dx 5”来监控磁盘性能。大约 5 GB 的复制进度监控显示:

Device:         rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
sda               0,00     0,00  530,40    0,00 68064,80     0,00   256,65     1,62    3,06    3,06    0,00   1,63  86,72
sdb               0,00 18767,20    0,20  112,40    23,20 73169,60  1300,05   144,32 1345,39  308,00 1347,23   8,88 100,00
Run Code Online (Sandbox Code Playgroud)

当复制进展到大约 52 GB 时,它会显示:

Device:         rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
sda               0,00     0,00   64,60    0,00  8268,80     0,00   256,00     0,22    3,41    3,41    0,00   1,76  11,36
sdb               0,00  1054,40    0,20   10,60     6,40  6681,60  1238,52   148,56 9458,00    0,00 9636,45  92,59 100,00

Device:         rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
sda               0,00     0,00   50,20    0,00  6425,60     0,00   256,00     0,16    3,09    3,09    0,00   1,64   8,24
sdb               0,00  2905,80    0,40   17,00     8,80 10289,60  1183,72   141,86 10199,77  652,00 10424,42  57,47 100,00
Run Code Online (Sandbox Code Playgroud)

我意识到这些是多个问题,但我怀疑这些都与同一个原因有关,并希望有人能向我澄清这一点。

ubf*_*an1 4

不幸的是,这是正常的,并且对于您的大文件用例来说是预期的。您的两个硬盘和一个 50GB 以上文件的情况消除了许多有关“慢速设备”、“慢速总线”和“慢速文件系统”的误导性言论,并且您留下了无法解释的慢速复制问题。您必须有相当多的内存才能获得处理 30GB 文件的性能。系统缓冲区被使用、填满,并且在复制命令完成后,最终将被刷新到目标,使得真正的计时/速率有些困难(即使“时间”命令也会在缓冲区最终刷新之前很久完成。

我发现的唯一“解决方法”是使用“复制”命令,它允许您自己设置显式缓冲区,就像 tar 或 cpio 可以做的那样。在 tar 上设置 2MB 缓冲区使我能够将 50G 文件的 10MB/秒复制速度加快到大约 35MB/秒——仍然比我在较小文件(或在 Windows 中)上获得的标称 100MB/秒慢得多。


另一个可能是更好的解决方案的解决方法是安装 nocache 软件包并使用 nocache cp 文件目标来限制填充系统缓冲区并拖慢系统。将 43G 文件复制到 /dev/null 的速度为 53MB/秒,比 tar 复制的大缓冲区要好。


某些使用叠瓦式磁记录 (SMR) 的磁盘在进行大量写入时变得非常慢。如果您的复制速度确实很低,但您仍然有大量可用内存缓冲区,这可能就是原因。

特定情况可能会通过swappiness、vm_dirty字节/比率、renice、ionice、nocache、预分配文件空间、调度等设置有所帮助,但基本问题仍然是,如果没有足够的可用内存,系统就无法正常工作。

请参阅启动板错误 1208993并将您自己添加到“这会影响我吗?” 列表。