我们在 docker 中运行一个反向代理应用程序,该应用程序对网络的占用非常大。Dockerd 偶尔会使用 madv_hugepage 分配内存,我们观察到这有时会导致应用程序停顿,而 dockerd 会暂停清空容器日志缓冲区并发生阻塞写入。这些停顿时间足够长,会导致大量流量丢失。
检查 buddyinfo 确认这些问题发生在我们没有可用的高阶分配时。通常是繁忙的主机,正常运行时间很长。
我们已经采取措施从 [madvise] 切换到 [defer],以试图限制 compact 停滞的影响,同时保留透明大页面的好处,而不是完全禁用它们。我们还没有再次遇到这个问题,但现在还为时过早。
这些设置是由我们添加的 systemd 单元在启动期间设置的。
[foobar.local:/root]:mgmt:$ cat /sys/kernel/mm/transparent_hugepage/defrag
always [defer] defer+madvise madvise never
[foobar.local:/root]:mgmt:$ cat /sys/kernel/mm/transparent_hugepage/enabled
always [madvise] never
[foobar.local:/root]:mgmt:$ cat /sys/kernel/mm/transparent_hugepage/khugepaged/defrag
1
用简单的英语来说,我理解这意味着...仅在 madv_hugepage 区域上分配一个 thp,如果不可用,则回退并唤醒 kswapd/kcompactd。khugepaged 稍后将尝试将页面折叠成 thp。
[foobar.local:/root]:mgmt:$ egrep 'thp|compact' /proc/vmstat
compact_migrate_scanned 7153737
compact_free_scanned 994921216
compact_isolated 7446472
compact_stall 510
compact_fail 336
compact_success 174
compact_daemon_wake 508
compact_daemon_migrate_scanned 845040
compact_daemon_free_scanned 146659185
thp_fault_alloc 1260
thp_fault_fallback 313
thp_collapse_alloc 1118
thp_collapse_alloc_failed 1703
thp_file_alloc 0
thp_file_mapped 0
thp_split_page 152
thp_split_page_failed 0
thp_deferred_split_page 2102
thp_split_pmd 719
thp_split_pud 0
thp_zero_page_alloc 4
thp_zero_page_alloc_failed 0
thp_swpout 0
thp_swpout_fallback 0
鉴于上述设置,我很惊讶地看到 compact_stall 指标仍在增加。为什么我们会看到 compact_stalls 增加?我们应该担心吗,还是这只是延迟分配的副作用?thp_fault_fallback 正在增加,因此似乎正在发生一些延迟。