我在将 SSD 驱动器配置为 RAID 1 的 Debian 服务器上运行此命令:
ionice -c 3 find . -type f -amin -1440 -mmin +1441 -not -path custom/ -print0
在包含超过 1.7M 个文件和目录的路径上。
我注意到每次运行此命令时,服务器负载都会激增,我想知道是否有任何方法可以限制find
速度,这样它就不会产生如此高的负载。
此外,我想知道是否有特定于 SSD 的选项可以减少负载生成find
答案1
这归结为文件系统和 procfs 调整。您解释的“高”负载是指系统上其他正常进程无法读取并被迫等待的情况。
情况特点是
- CPU 等待时间占比高(检查 top %wa)
- 许多进程处于 D 状态(由于等待从磁盘读取而处于不间断睡眠状态)
使用 noop 调度程序在这里没有帮助,因为 noop 是简单的 FIFO 调度程序,无法帮助您为磁盘访问游戏带来更多公平性。所以我建议使用 deadline 调度程序。
截止期限调度程序的理念是为某些磁盘 IO 操作设计最终截止期限,同时维护两个简单队列 - 一个用于读取,一个用于写入;您可以调整读取与写入的亲和力,以及在当前操作停止和接近过期的 IO 任务得到满足之前,您可以容忍某些读/写在队列中停留多长时间。
此外,您还需要在 RAM 中缓存大量目录条目和文件 inode 数据。这种缓存将在遍历如此大的目录/文件结构时大大节省磁盘 IO。
grep ^Slab /proc/meminfo
这将告诉您有多少内存完全专用于目录条目和文件缓存。有关 Slab 内存的拆分/使用方式的详细信息,请参阅
/proc/slabinfo
您可以运行slabtop
以获取交互式使用情况统计数据。
最终,如果你决定增加这种类型的缓存,你会想要降低
sysctl -w vm.vfs_cache_pressure=20
默认情况下,该值设置为 100,这是在系统内存不足的情况下尝试合理地减少用于缓存 d_entry 文件 inode 与页面缓存(即 RAM 中的文件/程序数据缓存)的内存量。通过减少该值,您将更愿意保留那些 d_entry/文件 inode 缓存,因此如果由于内存压力而从缓存中删除了相同的数据,则需要更少的读取操作来从磁盘重新读取相同的数据。
此外,为了提高您的磁盘读取能力,我建议增加预读能力。
blockdev --getra /dev/sda
blockdev --setra 2048 /dev/sda
这应该可以帮助您挤出一些额外的 IOPS,特别是当您的系统读取次数多于写入次数时。(检查 iostat 是否有帮助;第一行始终是自启动以来的总使用量,因此很容易从中得出比率)
接下来我要考虑调整的是缩小 nr_requests
回显 32 > /sys/block/sda/queue/nr_requests
通过这样做,您实际上将拥有更短的批次,这将允许更多的延迟,但会牺牲我们在上面获得的吞吐量。具有许多进程的系统将从中受益,因为单个进程将更难主宰 IO 队列,而其他进程则处于饥饿状态。
更多相关信息请参见此处:硬件 RAID 控制器调整
另一种可能出现高负载的情况是,如果您的正常系统活动被一些间歇性的大型写入批次(例如大文件下载、复制、解压操作)打断。写入也很容易使磁盘 IO 饱和,为了解决这些问题,我建议稍微调低以下设置。
vm.dirty_background_ratio
vm.dirty_ratio
小心不要太低。要了解这一点,您可以使用atop
工具并检查磁盘统计信息,从中您可以看到内存中通常有多少脏数据;有多少进程受益于脏内存(磁盘统计信息中的 WCANCL 列),并略高于这些使用率。
这些将有助于引入内核写回节流机制,该机制试图减慢通过大量写入来影响系统 IO 的进程。有关更多信息,请查看写回限制
答案2
不惜一切代价试图保持低负载是没有意义的。重要的是,如果更重要的事情需要利用系统提供的资源,您的进程应该后退一步。
ionice
和nice
/renice
可用于降低优先级,以便它仅在系统空闲时运行。