Linux 文件系统缓存:将数据从 Dirty 移至 Writeback

Linux 文件系统缓存:将数据从 Dirty 移至 Writeback

我的软件 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。

抱歉,我不知道您应该如何调整mdRAID 设备与单个磁盘设备。

(您也可以尝试测量排队的 IO 请求数。 atopsar -d 1,或sar -d 1,或iostat -dx 1。但是“平均队列大小”统计数据是源自利用率(“io_ticks”),这是自内核版本 5.0 以来报告不正确。瞬时队列大小仍然准确。但是现有工具往往只显示平均队列大小,因为这是更有用的值)。

相关内容