为什么linux cp命令不消耗磁盘IO?

太ry

操作系统:centos7

测试文件:a.txt 1.2G

监视命令:iostat -xdm 1

The first scene:
cp a.txt b.txt        #b.txt is not exist

在此处输入图片说明

The second scene: 
cp a.txt b.txt        #b.txt is exist

在此处输入图片说明

为什么第一个场景不消耗IO,而第二个场景却消耗IO?

迈克尔·莫尔

很有可能是在第一次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_bytesvm.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] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

为什么使用管道进行排序(Linux命令)很慢?

当系统内存大于8GB时,为什么Linux禁用磁盘写缓冲区?

为什么第二次cp命令更快

为什么高IO速率操作会减慢Linux上的所有速度?

为什么我在Linux上的服务会消耗大量CPU?

为什么IO 99.99%尽管磁盘读写似乎很小

C ++字符串流,为什么getline不消耗流的内容?

为什么未通过管道传递此Linux命令的结果?

为什么在Linux中需要“ at”命令?

为什么要使用'&'运行Linux shell命令?

什么在消耗我的磁盘?

为什么要在Centos上修补Linux内核以使用Docker.io

为什么此无限循环不消耗100%的CPU

为什么kworker在Linux 3.0.0-12服务器上消耗了这么多资源?

为什么通过HttpURLConnection getInputStream传递的内容与通过Linux命令curl或wget传递的内容不同?

为什么Chromium在Gentoo Linux上占用了如此多的磁盘空间?

为什么我的系统进程在做磁盘IO?

为什么某些Linux Shell脚本使用exec运行命令?

为什么Linux会显示没有分区的磁盘的设备分区阻止文件?

为什么我的cp命令不能复制整个目录?

为什么我出现fsync()失败:Linux计算机上的磁盘配额超出限制?

为什么Linux不清理磁盘缓存并自动交换?

为什么使用dd而不是cp创建可启动磁盘?

Linux Shell:为什么在此telnet命令中需要“打开”

为什么 free 命令说的与实际消耗的内存不同

Linux。为什么我的 Linux 命令在终端上有效,但在脚本中无效

Linux shell:为什么“发送”命令不运行

为什么命令 udhcpc 无法在 linux 上设置超时?

为什么我在 linux 中使用 -cp 函数会出现命名错误?