我正在寻找一种方法来将进程磁盘 io 限制为设定的速度限制。理想情况下,该程序的工作方式类似于:
$ limitio --pid 32423 --write-limit 1M
Run Code Online (Sandbox Code Playgroud)
将进程 32423 限制为每秒 1 兆字节的硬盘写入速度。
我最近检查了一个几乎完全挂起的 RHEL7.2,因为它写入了 CIFS 文件系统。dirty_ratio = 30
和 cifs的默认设置被缓存(用于读取和写入),这些脏页大多是 cifs 的。
在内存压力下,当系统回收大部分读缓存时,系统顽固地尝试刷新和回收脏(写)缓存。所以情况是一个巨大的 CPU iowait 伴随着极好的本地磁盘 I/O 完成时间,D 中的许多进程不间断等待和一个完全无响应的系统。OOM杀手从来没有从事过,因为是免费的内存系统没有给出来。(我认为 CIFS 也有一个错误,它使刷新速度慢得令人难以置信。但别介意这里。)
我惊讶地发现内核处理刷新页面到一些慢速远程 CIFS 盒的方式与处理超快速本地 SSD 驱动器完全相同。拥有一个dirty_ratio
包是不明智的,它很快就会导致 30% 的 RAM 包含来自最慢设备的脏数据的情况。真是浪费钱。
这种情况是可重现的;设置dirty_ratio = 1
彻底解决问题。但是为什么我需要因为使用cifs挂载而牺牲本地磁盘的缓存?
除了完全禁用某些设备的缓存或设置vm.dirty_ratio
为非常低的值之外,还有什么方法可以将快速设备“列入白名单”以获得更多写入缓存?或者让慢速设备(或像 //cifs/paths 这样的远程“设备”)使用更少的写缓存?
RHEL 7.2 的内核版本称为 3.10.0-327。(它基于 3.10.0,但包括数年的向后移植)。