内核memory的多级内存回收策略
需求背景
在容器高密度混合部署场景中,IO读写较多的离线业务消耗大量page cache,导致系统空闲内存降低,达到全局空闲内存水位线后触发全局内存回收,使得在线任务申请内存时进入内存回收的慢路径,引发时延抖动。
为解决此问题,HCE 2.0新增支持多级内存回收策略。申请内存时,设置内存警示值,可触发内存回收任务,保证可用内存空间;回收内存时,设置多级内存保护水位线,保护任务可用性。
约束与限制
memory.min和memory.low只在叶子节点生效。创建memory cgroup时,会将父节点的memory.min和memory.low清零。
多级内存回收接口说明
memory.min、memory.low和memory.high接口在非根的memory cgroup下面默认存在,可以向文件内写值配置,也可以读取当前配置。合理的取值大小顺序为memory.min≤memory.low<memory.high,三者可独立使用,也可联合使用。
内存回收机制如下图。
接口 |
说明 |
---|---|
memory.min |
硬保护内存保护值,默认值为0。系统没有可回收内存的时候,也不会回收在该值边界及以下的内存。读写说明如下:
|
memory.low |
尽力而为的内存保护值,默认值为0。 系统优先回收未被保护的cgroup组的内存。如果内存还不足,再回收memory.min到memory.low之间的内存。 读写说明如下:
|
memory.high |
内存回收警示值,默认为max。当cgroup组内存使用量达到high值,会触发对该cgroup及子节点的同步内存回收任务,将内存尽量限制在high之下,避免触发memory.limit限制导致OOM。读写说明如下:
|
接口示例
按如下所示创建6个cgroup节点A、B、C、D、E、F,配置memory.min接口,示例说明多级内存回收策略。
cgroup组 |
memory.limit_in_bytes |
memory.min |
memory.usage_in_bytes |
---|---|---|---|
A |
200M |
0 |
- |
B |
- |
0 |
- |
C |
- |
75M |
50M |
D |
- |
25M |
50M |
E |
- |
0 |
50M |
F |
- |
125M |
- |
- 创建cgroup节点A,并配置memory.limit_in_bytes=200M。
mkdir /sys/fs/cgroup/memory/A echo 200M > /sys/fs/cgroup/memory/A/memory.limit_in_bytes
- 创建cgroup节点B。
mkdir /sys/fs/cgroup/memory/A/B
- 创建cgroup节点C,并配置memory.min=75M,在当前节点创建申请50M cache的进程。
mkdir /sys/fs/cgroup/memory/A/B/C echo 75M > /sys/fs/cgroup/memory/A/B/C/memory.min
- 创建cgroup节点D,并配置memory.min=25M,在当前节点创建申请50M cache的进程。
mkdir /sys/fs/cgroup/memory/A/B/D echo 25M > /sys/fs/cgroup/memory/A/B/D/memory.min
- 创建cgroup节点E,并配置memory.min=0,在当前节点创建申请50M cache的进程。
mkdir /sys/fs/cgroup/memory/A/B/E
- 创建cgroup节点F,并配置memory.min=125M,申请125M保护内存,触发内存回收。
mkdir /sys/fs/cgroup/memory/A/F echo 125M > /sys/fs/cgroup/memory/A/F/memory.min
返回结果:
C节点memory.min=75M,memory.usage_in_bytes=50M。
D节点memory.min=25M,memory.usage_in_bytes=25M。
E节点memory.min=0,memory.usage_in_bytes=0。
B节点memory.usage_in_bytes=75M。