我的软件 RAID 可以持续写入 800 MB/s。我发现当cat /proc/meminfo |grep Writeback:
返回 > 2 GB 时会发生这种情况。但是,大多数时候写回大约为 0.5 GB,性能约为 200 MB/s。
有大量数据需要写入。cat /proc/meminfo |grep Dirty:
表示脏缓存为 90 GB。
据我了解,Dirty 是需要写入的内容,而 Writeback 是主动写入磁盘的内容。因此,磁盘上可能存在 Dirty 中的块,它们紧挨着 Writeback 中的块,而这些块不会同时写入。
这可以解释为什么当 Writeback 较小时我会得到更差的性能,因为寻找所花费的时间比写入几 MB 额外数据所花费的时间要长得多。
所以我的问题是:我能否以某种方式告诉内核更积极地将更多数据从Dirty移动到Writeback,从而增加Writeback?
- 编辑 -
这是在性能低下期间:
$ cat /proc/meminfo
MemTotal: 264656352 kB
MemFree: 897080 kB
Buffers: 72 kB
Cached: 233751012 kB
SwapCached: 0 kB
Active: 3825364 kB
Inactive: 230327200 kB
Active(anon): 358120 kB
Inactive(anon): 47536 kB
Active(file): 3467244 kB
Inactive(file): 230279664 kB
Unevictable: 0 kB
Mlocked: 0 kB
SwapTotal: 204799996 kB
SwapFree: 204799996 kB
Dirty: 109921912 kB
Writeback: 391452 kB
AnonPages: 404748 kB
Mapped: 12428 kB
Shmem: 956 kB
Slab: 21974168 kB
SReclaimable: 21206844 kB
SUnreclaim: 767324 kB
KernelStack: 5248 kB
PageTables: 7152 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
WritebackTmp: 0 kB
CommitLimit: 337128172 kB
Committed_AS: 555272 kB
VmallocTotal: 34359738367 kB
VmallocUsed: 544436 kB
VmallocChunk: 34124336300 kB
HardwareCorrupted: 0 kB
AnonHugePages: 0 kB
HugePages_Total: 0
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
DirectMap4k: 149988 kB
DirectMap2M: 17649664 kB
DirectMap1G: 250609664 kB
cat /proc/sys/vm/dirty_background_ratio
1
降低 dirty_writeback_centisecs 只会将 Dirty 切成更小的位。
答案1
您没有提供完整的 /proc/meminfo 输出,所以我不知道您是否事先做过任何调整。
您可以立即使用两个可调参数。
/proc/sys/vm/dirty_background_ratio
dirty_background_ratio
Contains, as a percentage of total system memory, the number of pages at which
the pdflush background writeback daemon will start writing out dirty data.
默认值为 10。将其增加到 30 或 40 并进行测试。
/proc/sys/vm/dirty_writeback_centisecs
dirty_writeback_centisecs
The pdflush writeback daemons will periodically wake up and write `old' data
out to disk. This tunable expresses the interval between those wakeups, in
100'ths of a second.
Setting this to zero disables periodic writeback altogether.
默认是500,设置为300然后测试。
请记住这些不是绝对值。您必须通过反复试验才能找到最适合您环境的值。
我只是根据您提供的描述推算出这些值并假设它们是正确的。
如果您安装了 kernel-doc 包,请转到 sysctl,然后打开 vm.txt 阅读相关内容。
答案2
真正的问题是 Linux 内核脏页刷新算法不能扩展到大内存大小,因此只要 /proc/meminfo 中的脏页超过 1GB 左右,写回速度就会逐渐减慢,最终超过 /proc/sys/vm/dirty_ratio 或 /proc/sys/vm/dirty_bytes 限制,内核就会开始限制所有写入,以防止脏页进一步增长。
为了保持较高的写入速度(在 OP 情况下高达 800Mb/秒,对于带缓存的硬件 RAID 控制器来说很容易达到 2 Gb/秒),您需要直观地将 /proc/sys/vm/dirty_bytes 和 dirty_background_bytes 分别降低到 256M 和 64M
确保先进行同步,否则系统将在写入时冻结几个小时,直到 /proc/meminfo 中的脏页值降至 /proc/sys/vm/dirty_bytes 中的新值以下。同步也将需要几个小时,但至少系统在此期间不会冻结。
答案3
Writeback
表示IO队列的大小。
nr_requests
可以通过增加(并且可能)来增加 IO 队列的最大大小max_sectors_kb
。考虑到您拥有的内存量Dirty
,我怀疑您已经达到了此限制。
https://www.google.com/search?q=linux+block+queue+nr_requests+OR+max_sectors_kb
在较新的内核中,您还应该留意 的效果wbt_lat_usec
。您可以通过写入0
来禁用此功能,并通过写入 将其重置为默认值-1
。
还有 I/O 调度程序的问题。许多服务器建议使用deadline
调度程序,而不是 CFQ。CFQ(以及某种程度上的 BFQ)故意“闲置”磁盘,试图一次从一个进程请求连续的顺序 I/O。
抱歉,我不知道您应该如何调整md
RAID 设备与单个磁盘设备。
(您也可以尝试测量排队的 IO 请求数。 atopsar -d 1
,或sar -d 1
,或iostat -dx 1
。但是“平均队列大小”统计数据是源自利用率(“io_ticks”),这是自内核版本 5.0 以来报告不正确。瞬时队列大小仍然准确。但是现有工具往往只显示平均队列大小,因为这是更有用的值)。