dd 为何会导致主机无响应?

dd 为何会导致主机无响应?

我昨天以 root 身份

dd if=/dev/zero of=/var/lib/libvirt/images/dat.img bs=1G count=1000

这使得服务器在几个小时内完全没有响应。

RAID 控制器是 HP P410,带有 4 个磁盘(RAID 1+0)。

是我使用的问题bs=1G还是 CentOS 需要内核参数,因此繁重的 I/O 不能使主机停止运行?

问题

谁能解释为什么会发生这种情况?

附言:下次我将创建一个稀疏文件,但是现在我想了解如何防止 I/O 超出主机最大容量。

答案1

简短回答:服务器变得无响应,因为您用脏页(即要刷新的数据)填充了几乎所有的内存。

长答案:通常,写入不会立即将数据推送到备份设备。相反,它们被缓存在页面缓存中。这样做是出于性能原因:与 CPU/内存相比,存储(尤其是 HDD)非常慢,因此尽可能多地缓存可以显著提高 I/O 速度。但是,如果你写入太多,页面缓存将疯狂地(并以高优先级)将尽可能多的数据刷新到磁盘。这会导致调用进程进入“深度睡眠” - 这意味着你不能中断它,因为它没有真的运行,而是等待被内核唤醒。而且,由于脏数据刷新是一项高成本、高优先级的操作,整个服务器会变得非常慢。

话虽如此,如何才能在不使服务器运行缓慢的情况下创建大型图像文件?你有不同的选择:

  • 启动你的dd命令附加oflag=direct选项:这将dd导致绕过页面缓存,直接写入磁盘。我还建议使用较小的缓冲区,即:1 MB,使用类似的东西dd if=/dev/zero of=/var/lib/libvirt/images/dat.img bs=1M count=1000000。请注意,上面的命令将要在执行过程中会稍微减慢服务器的速度(毕竟您正在写入磁盘),但不会达到您第一次尝试的速度;
  • 创建完全分配文件的更好方法是使用命令fallocate,即:fallocate /var/lib/libvirt/images/dat.img -l 1G。通过元数据处理进行分配,而不是写入任何实际数据,此命令将几乎立即返回,不会造成任何减速。许多现代文件系统都支持它,但 ZFS 除外;
  • 最后,你可以使用稀疏文件- 具有名义大小但未实际分配的文件。您可以通过发出来创建它truncate --size=1G /var/lib/libvirt/images/dat.img。此命令将立即返回,基本上几乎不会引起任何 I/O。

答案2

dd分配一个大小的缓冲区bs- 如果这是相当大一部分内存,它将取代其他内存并导致交换。

更糟糕的是,bs缓冲区在一次操作中就被写出。这可能会在一段时间内束缚你的存储系统。再加上上面的交换,这可能会严重束缚系统。

因此,对于您的任务来说,使用它是个合理的选择bs=16M。它有足够大的缓冲区大小,可以实现高效的 I/O,同时粒度足够细,不会占用太多空间。

相关内容