调整Linux虚拟内存来解决磁盘I/O问题

调整Linux虚拟内存来解决磁盘I/O问题

我的 Linux 服务器存在一个问题,它向磁盘写入太多数据,因此由于长时间的 IO 等待,导致响应时间变慢。我已经检查了磁盘的智能值,一切正常。这是 RAID1 软件中的双磁盘设置,Raid,ext4 文件系统。

由于我暂时无法升级硬件,也无法摆脱密集的 I/O 应用程序,因此我计划配置 Linux vm 设置以尝试简化 I/O 等待时间。

我正在考虑调整交换,但主要是 dirty_background_ratio 和 dirty_ratio。

问题:

如何根据当前系统负载和内存使用情况估计这些值的调整?

答案1

你想要的东西很少。首先,你想减少 swappiness

sysctl -w vm.swappiness=10

这将节省一些磁盘 IO;因为当内核尝试从内存中分页出某些内容时,您最不需要的就是对磁盘进行额外的写入。目标是调整事物,以便需要的交换很少。但是,不要通过将其设置为 0 或禁用来关闭 swappiness。我建议采取极端措施,将 swappiness 设置为 1。如果您观察 dstat 输出一段时间,您会很快注意到实际从 swap 写入和读取的数据量。

现在新内核(3.2+)中有一种机制,称为写回限制。为了能够像您所说的那样使用它,您需要调整脏比率。查看更多详细信息 此链接. 那里的引文让你感兴趣

Once dirty_ratio (resp. dirty_bytes) limit is hit then the process which 
writes gets throttled.

因此默认情况下,dirty 相当高,特别是如果您有大量内存和较慢的磁盘子系统。因此您需要调低它们;尽可能低以不影响正常使用*,但值将决定在内核生成进程将其写入磁盘之前内存中存在的数据量,此时您的磁盘 IO 瓶颈情况开始发生。此时您希望该进程受到限制,内核通过在其中注入睡眠来实现这一点。

* 弄清楚什么是正常使用;我建议安装在顶部并观察那里发生了什么;您需要检查dirty那里的数字并查看 D 概览,其中跟踪磁盘读/写。有列 WCANCL;这些实际上是在内存中处理的写入,并且永远不需要写入磁盘(脏页),但用于一些临时数据。Mysql 在执行复杂查询时有这些,编译器在制作一堆不需要很长时间的小 obj 文件时也有这些……

除此之外,它可能有助于切换到截止期限磁盘调度程序,并调整读取与写入的亲和力以更好地适应您的环境。例如,如果您的读取次数是写入次数的 10 倍,您可能需要设置

/sys/block/<device>/queue/iosched/writes_starved

设置为 5,而不是默认值 2。设置更高的

/sys/block/<device>/queue/iosched/write_expire

也会有所帮助。此外,如果你将批量处理的请求数量12832

/sys/block/<device>/queue/nr_requests

答案2

如果您有大量写入操作,系统将因没有可用的写入缓存层而受到限制。两个磁盘和软件 RAID 使这种情况变得困难。通常,这是硬件 RAID 的功能。您现在拥有的硬件配置不适合您的工作负载。

为了提供更好的答案,我们需要有关您的应用程序正在做什么、操作系统、文件系统上是否启用了写屏障等详细信息。

编辑:如果基础不好,你只能调整到这个程度。也许你应该考虑使用 SSD 而不是旋转磁盘。

答案3

我最近在我的博客中写了关于 dirty_background_ratio 和 dirty_ratio 等的内容:

http://models.street-artists.org/2016/10/09/nfs-syncasync-some-of-the-issue-solved-or-how-to-set-vm-dirty_bytes-and-vm-dirty_background_bytes/

简而言之,不使用 *_ratio 变量,而是使用 *_bytes 版本,并通过获取带宽(或数据生成率)并乘以在大量写入开始到达磁盘之前您愿意承受的最大延迟来估算字节数。

通过将 dirty_background_bytes 值设置得相对较低(在完全数据接收/生成速率下延迟不到一秒),您可以确保缓冲区不会在无人执行任何操作时累积。将 dirty_bytes 设置为 2 或 3 倍(至少,可能高达 10 倍或更多,具体取决于您的 RAM 数量)将确保突发进程不会受到限制。您可以通过考虑数据生成速率和磁盘写入速度之间的差异来估算 dirty_bytes 值。这是一个缓冲区填充率,然后您可以将其乘以填充受到限制之前的最大缓冲时间。例如,如果您以速率 Rg 生成数据并以速率 Rd 写入磁盘,并且 Rg 大于 Rd,则可以将 dirty_background_bytes 设置为 Rg*(0.5 秒),这样您的磁盘在您开始将数据猛击到缓冲区后约 0.5 秒开始写入,然后将 dirty_bytes 设置为 max(2*Rg*0.5, (Rg-Rd)*(2 秒))。突发进程将能够写入最多 2 秒,然后缓冲区会变得足够大,以至于受到限制。

相关内容