很有可能是在第一次cp
操作期间没有将数据刷新到磁盘上,而是在第二次操作期间将数据刷新到了磁盘上。
尝试将其设置vm.dirty_background_bytes
为较小的值,例如1048576(1 MiB),看看是否是这种情况;运行sysctl -w vm.dirty_background_bytes=1048576
,然后您的第一个cp
方案应显示I / O。
除了在同步和/或直接I / O的情况下,对磁盘的写入都会在内存中缓冲,直到达到阈值为止,这时它们开始在后台刷新到磁盘。此阈值没有正式名称,但由vm.dirty_background_bytes
和来控制vm.dirty_background_ratio
,因此我将其称为“脏背景阈值”。从内核文档:
vm.dirty_background_bytes
包含后台内核刷新程序线程将开始写回的脏内存量。
注意:
dirty_background_bytes
是的对应项dirty_background_ratio
。一次只能指定其中之一。写入一个sysctl时,将立即考虑评估脏内存限制,而另一个在读取时显示为0。
dirty_background_ratio
在包含可用页面和可回收页面的总可用内存的百分比中,包含后台内核刷新程序线程将开始写出脏数据的页面数。
总可用内存不等于系统总内存。
vm.dirty_bytes
和 vm.dirty_ratio
还有第二个门槛,超越这个门槛。好吧,它是一个极限,而不是一个阈值,它是由vm.dirty_bytes
和控制的vm.dirty_ratio
。同样,它没有正式名称,因此我们将其称为“脏污限制”。一旦“写入”了足够的数据但没有将其提交给底层块设备,write
就必须进一步尝试等待写入I / O完成。(我不清楚他们将要等待什么数据的确切细节,这可能是I / O调度程序的功能。我不知道。)
磁盘很慢。特别是旋转锈蚀,因此,当磁盘上的R / W磁头移动以满足读取请求时,在读取请求完成并且可以启动写入请求之前,无法处理任何写入请求。(反之亦然)
这就是为什么我们将写请求缓冲在内存中并缓存已读取的数据的原因。我们将工作从慢速磁盘转移到更快的内存。当最终将数据提交到磁盘时,我们需要处理大量数据,并且可以尝试以最小化查找时间的方式写入数据。(如果使用的是SSD,请用重新刷新SSD块来替换磁盘寻道时间的概念;重新刷新会消耗SSD的寿命,并且运行速度很慢,SSD试图(以不同程度的成功来完成)以自己的方式隐藏缓存。)
我们可以调整内核在尝试使用vm.dirty_background_bytes
和将数据写入磁盘之前要缓冲多少数据vm.dirty_background_ratio
。
如果您要写入的数据量太大,无法到达磁盘,那么最终将消耗所有系统内存。首先,您的读取缓存将消失,这意味着较少的读取请求将由内存处理,而必须从磁盘进行处理,从而进一步降低了写入速度!如果您的写压力仍然没有释放,最终像内存分配一样,您将不得不等待写缓存释放一些内存,这将更具破坏性。
所以我们有vm.dirty_bytes
(和vm.dirty_ratio
); 它可以让我们说:“嘿,等一下,这实际上是我们将数据存入磁盘的时候了,否则情况会变得更糟。”
但是,对I / O进行硬性停止是非常破坏性的。从读取过程的角度来看,磁盘已经很慢,刷新数据可能需要几秒钟到几分钟。考虑vm.dirty_bytes
默认的20。如果您的系统具有16GiB的RAM并且没有交换,则在等待3.4GiB数据刷新到磁盘时可能会发现I / O被阻塞。在具有128GiB RAM的服务器上?等待27.5GiB数据时,服务将超时!
因此,保持vm.dirty_bytes
(或vm.dirty_ratio
,如果您愿意)相当低的值很有帮助,这样,如果您达到此硬阈值,则只会对您的服务造成最小的干扰。
使用这些可调参数,您始终可以在吞吐量和延迟之间进行交易。缓冲过多,您将拥有很大的吞吐量,但延迟却很糟糕。缓冲区太少,您将获得可怕的吞吐量,但延迟很大。
在仅具有单个磁盘的工作站和笔记本电脑上,我希望将其设置vm.dirty_background_bytes
为1MiB左右,并设置为8MiBvm.dirty_bytes
和16MiB之间。对于单用户系统,我很少发现吞吐量超过16MiB的好处,但是对于任何同步工作负载(如Web浏览器数据存储),延迟挂起都会变得非常糟糕。
在具有条带化奇偶校验数组的任何对象上,我发现该数组的条带宽度的倍数是的一个很好的起始值vm.dirty_background_bytes
;它减少了在更新奇偶校验时需要执行读/更新/写序列的可能性,从而提高了阵列吞吐量。
对于vm.dirty_bytes
,这取决于您的服务可能遭受多少延迟。我自己喜欢计算块设备的理论吞吐量,用它来计算它在100ms左右可以移动多少数据,并进行vm.dirty_bytes
相应的设置。100ms的延迟是巨大的,但这并不是灾难性的(在我的环境中)。
但是,所有这一切都取决于您的环境。这些只是寻找适合您的起点。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句