Pne*_*cat 6 memory linux performance cache
在过去的几个月里,我的 Linux 系统遇到了一个非常恼人的问题:它在 Firefox 音频播放、鼠标移动等方面卡顿,每隔几秒就会出现亚秒级(但仍然很明显)的卡顿。当内存缓存填满时,或者当我运行高度磁盘/内存密集型程序(例如备份软件restic
)时,问题会恶化。然而,当缓存未满时(例如,在非常轻的负载下),一切都运行得非常顺利。
查看perf top
输出,我发现list_lru_count_one
在这些滞后期间有很高的开销(~20%)。htop
还显示kswapd0
使用了 50-90% 的 CPU(尽管感觉影响远大于此)。在极度滞后期间,htop
CPU 仪表通常由内核 CPU 使用率决定。
我发现的唯一解决方法是强制内核保留可用内存 ( sysctl -w vm.min_free_kbytes=1024000
) 或通过echo 3 > /proc/sys/vm/drop_caches
. 当然,两者都不是理想的,也都不能完全解决口吃问题;它只会使它不那么频繁。
有没有人对为什么会发生这种情况有任何想法?
-ck
Con Kolivas的补丁集(没有帮助)编辑:为清楚起见,这里的图片htop
和perf
这样的滞后穗期间。请注意高list_lru_count_one
CPU 负载和kswapd0
+ 高内核 CPU 使用率。
问题已经找到了!
\n\n事实证明,当存在大量容器/内存 cgroup 时,Linux 内存回收器会出现性能问题。(免责声明:我的解释可能有缺陷,我不是内核开发人员。)该问题已在此补丁集中的4.19-rc1+ 中修复:
\n\n\n\n\n此补丁集解决了在具有许多收缩器和内存 cgroup(即具有许多容器)的计算机上发生的收缩_slab() 缓慢的问题。问题是shrink_slab()的复杂度是O(n^2)并且随着容器数量的增长它增长得太快。
\n\n让我们有 200 个容器,每个容器有 10 个挂载点和 10\n 个 cgroup。所有容器任务都是隔离的,并且它们不接触外部容器挂载。
\n\n在全局回收的情况下,任务必须遍历所有 memcgs 并\n 为所有这些调用所有 memcg 感知的收缩器。这意味着,任务必须为每个 memcg 访问 200 * 10 = 2000 个收缩器,并且由于有 2000 个 memcg,因此 do_shrink_slab() 的调用总数为 2000 *\n 2000 = 4000000。
\n
我的系统受到的打击特别严重,因为我运行了大量容器,这可能是导致问题出现的原因。
\n\n我的故障排除步骤,以防它们对面临类似问题的任何人有帮助:
\n\nkswapd0
当我的计算机出现卡顿时,会使用大量 CPUftrace
(遵循Julia Evan 精彩的解释博客)来获取踪迹,看看它kswapd0
往往会卡在shrink_slab
、super_cache_count
、 和中list_lru_count_one
。shrink_slab lru slow
,找到补丁集!