因此,在Linux桌面上,我正在将一些大文件写入本地磁盘或NFS挂载。
有某种系统缓冲区可缓存要写入的数据。(我认为我的系统在0.5-2GB范围内吗?)
如果缓冲区已满,则所有文件访问块都将有效冻结系统,直到写入完成。(我非常确定,即使读取访问也被阻止。)
我需要配置什么以确保永远不会发生?
我想要的是:
如果某个进程不能足够快地将数据写入磁盘(或网络安装等),则该进程可能会阻塞,直到磁盘出现问题为止,但是其他进程仍可以以合理的速率和延迟读取/写入数据,而不会发生任何中断。
理想情况下,我将能够设置特定类型的程序(cp,git,mplayer,firefox等)可使用的dsik的总读写速率有多少,例如“所有mplayer进程加起来至少10MB / s,无论系统其余部分在做什么。但是“无论什么情况,所有mplayer实例加起来至少要达到总速率的50% ”也是可以的。(即,我不太在乎是否可以设置绝对比率或占总比率的比例)。
更重要的是(因为最重要的读/写操作很小),我需要类似的延迟设置。再次,我保证单个进程的读/写操作无论在任何情况下都不会阻塞超过10毫秒(或任何其他时间)的系统其余时间。理想情况下,我会保证“无论系统在做什么,mplayer都不必等待10毫秒以上的时间来进行读/写操作”。
无论有问题的流程如何开始(包括运行该用户的用户等),这都必须起作用,因此“将大型cp封装在ionice中”或任何几乎没有用的东西。如果我记得要使它们停顿,那只会阻止某些任务冻结所有内容,但是cron作业,某个正在运行的守护程序的exec调用又如何呢?
(我想我可以用一个总是使他们离子化的shell脚本来包装最严重的违规者,但是即使如此,通过查看ionice的手册页,似乎仍然可以确切知道它能为我提供什么保证,所以我宁愿选择一个更加系统化的方案和可维护的替代方案。)
通常,Linux使用缓存将数据异步写入磁盘。但是,可能会发生写请求和实际写之间的时间跨度或未写(脏)数据量非常大的情况。在这种情况下,崩溃将导致大量数据丢失,因此,如果脏缓存变大或变旧,Linux将切换到同步写入。由于还必须遵守写入顺序,因此您不能仅绕过小型IO,而不能保证小型IO完全独立于所有较早的排队写操作。因此,依赖的写入可能会导致巨大的延迟。(这种依赖性也可能在文件系统级别上引起:请参阅https://ext4.wiki.kernel.org/index.php/Ext3_Data%3DOrdered_vs_Data%3DWriteback_mode)。
我的猜测是,您正在经历某种缓冲区膨胀和相关写入的结合。如果您写入一个大文件并具有一个较大的磁盘缓存,那么最终您将不得不写入大量数据,然后才能执行同步写入。在LWN上有一篇很好的文章,描述了问题:https : //lwn.net/Articles/682582/
调度程序的工作仍在进行中,新内核版本的情况可能会变得更好。但是,到目前为止:有一些开关可能会影响Linux上的缓存行为(还有更多开关,请参阅:https : //www.kernel.org/doc/Documentation/sysctl/vm.txt):
在这种情况下,减少最大延迟的最简单解决方案是减少脏磁盘高速缓存的最大数量,并使后台作业尽早写入。当然,在原本较大的缓存将完全阻止同步写入的情况下,这可能会导致性能下降。例如,您可以在/etc/sysctl.conf中配置以下内容:
vm.dirty_background_ratio = 1
vm.dirty_ratio = 5
请注意,适合您系统的值取决于可用RAM的数量和磁盘速度。在极端条件下,上述脏污率可能仍然很大。例如,如果您有100GiB的可用RAM,并且磁盘写入的速度约为100MiB,则上述设置将导致最大数量的5GiB脏缓存,并且可能需要大约50秒的时间来写。使用dirty_bytes
和dirty_background_bytes
也可以以绝对方式设置缓存的值。
您可以尝试的另一件事是切换io调度程序。在当前的内核发行版中,没有noop,最后期限和cfq。如果您使用的是较旧的内核,那么与cfq相比,使用截止时间调度程序可能会遇到更好的响应时间。但是,您必须对其进行测试。在这种情况下,应避免出现Noop现象。还有一个非主线BFQ调度程序,它声称与CFQ相比减少了延迟(http://algo.ing.unimo.it/people/paolo/disk_sched/)。但是,它并不包含在所有发行版中。您可以使用以下方法在运行时检查和切换调度程序:
cat /sys/block/sdX/queue/scheduler
echo <SCHEDULER_NAME> > /sys/block/sdX/queue/scheduler
第一个命令还将为您提供可用调度程序及其确切名称的摘要。请注意:重新启动后,该设置将丢失。要永久选择时间表,您可以添加一个内核参数:
elevator=<SCHEDULER_NAME>
NFS的情况与此类似,但还存在其他问题。以下两个错误报告可能会提供一些有关NFS的处理状态的内幕,以及为什么写入大文件会导致状态非常慢的原因:
https://bugzilla.redhat.com/show_bug.cgi?id=688232 https://bugzilla.redhat.com/show_bug.cgi?id=469848
更新:(2017年8月14日)内核4.10新内核选项CONFIG_BLK_WBT
及其子选项BLK_WBT_SQ
,并CONFIG_BLK_WBT_MQ
相继出台。它们可以防止由硬件缓冲区引起的缓冲区膨胀,该缓冲区缓冲区的大小和优先级不能由内核控制:
Enabling this option enables the block layer to throttle buffered
background writeback from the VM, making it more smooth and having
less impact on foreground operations. The throttling is done
dynamically on an algorithm loosely based on CoDel, factoring in
the realtime performance of the disk
此外,BFQ-Scheduler的内核为4.12。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句