我们在使用容器的过程中,可能会遇到一个问题,容器利用率很低,但是经常发生 oom,这是什么情况?
很可能是业务使用了一些不可回收的 page cache,其中最主要的应该就是 mlock
1. mlock 的背景
mlock 的作用就是防止页面被换出到 swap 分区,或者 page cache 被内核回收
由于线上服务器,基本默认都会关闭 swap 分区,所以这种情况暂不讨论,防止 page cache 被内核回首是主要作用
什么样的 page 需要 mlock?
1)通过 mmap 方式映射到内存中的 page cache,比如一些关键的索引数据,需要经常访问,那就得 mlock 住,否则 pgmajfault 带来的性能抖动是很大的
2)程序自身依赖的一些 so 动态链接库,由于内核的 page cache 回收算法,并不感知 page 具体是普通的文件 cache,还是 so 动态链接库,所以当容器内存不足时,内核通过一些粗略的回收算法回收 page cache,一旦把 so 的缓存页回收掉了,程序在调用相关函数时,会出现严重的性能抖动
因此,通过 mlock,显式的把一些关键的不希望被回收的 page cache 锁定起来,达到保证业务性能的目的
2. mlock 的内核实现
mlock 相关的系统调用可以参考:https://linux.die.net/man/2/mlock
2.1. unevictable 内存
cgroup 的 memory.stat 接口,包含一个容器内存使用的详细信息
cat /cgroups/v2/matrix/memory.stat anon 200723943424 file 158665015296 kernel_stack 0 slab 0 sock 229249024 shmem 4258582528 file_mapped 48234749952 file_dirty 8605696 file_writeback 0 inactive_anon 4258234368 active_anon 200570675200 inactive_file 73935654912 active_file 40680521728 unevictable 39942680576
其中 unevictable 表示不剔除的 page cache,mlock 属于 unevictable 的一部分,除此之外,unevictable 还有一些其他内存