文档首页/ Huawei Cloud EulerOS/ 用户指南/ 内核功能与接口/ 内核memory的OOM进程控制策略
更新时间:2024-09-14 GMT+08:00

内核memory的OOM进程控制策略

背景信息

现有操作系统中,支持配置离线业务和在线业务。当内存发生OOM时,会优先选择离线业务控制组中的消耗内存最多的进程,结束进程回收内存,但是对于某些离线业务也有核心业务,因此会造成很大的影响。

针对这个问题,HCE调整了OOM时回收内存的策略,增加了配置cgroup优先级的功能。 内存紧张情况下内核会遍历cgroup,对低优先级的cgroup结束进程,并回收内存,使离线业务中重要的业务可以存活下来。

前提条件

vm.panic_on_oom接口默认开启,系统OOM时panic。故使用memcg OOM优先级配置时(即memcg_qos_enable配置为1或2),须先执行sysctl -w vm.panic_on_oom=0命令,关闭系统参数vm.panic_on_oom。

memcg OOM优先级接口功能说明

接口

说明

取值

memcg_qos_enable

memcg OOM优先级策略开关。

  • 0:不开启优先级配置。当OOM时,按照系统原有的OOM操作结束进程,结束内存消耗最大的进程,回收内存。
  • 1:开启优先级配置并以cgroup为粒度。当OOM时,结束优先级低的cgroup所有进程,并回收内存。
  • 2:开启优先级配置并以单个进程个为粒度。当OOM时,结束优先级低的cgroup中的最大的一个进程,并回收内存。

整数形式,取值范围为0~2,默认值为0。

memory.qos_level

配置cgroup组优先级。值越小cgroup组优先级越低。

  • 当memcg OOM时,会以当前cgroup组为父节点,查找子节点优先级最低的cgroup组中内存使用最大的进程,结束该进程,回收内存。
  • 当OOM时,对于优先级相等的cgroup组,会根据组的内存使用量进行二次排序,选择内存使用最大的进行OOM操作。
说明:
  • 使用memory.qos_level的前提条件为memcg_qos_enable取值须为1或2。
  • 新创建的cgroup组的memory.qos_level值默认会继承父节点的memory.qos_level的值,但是子节点的优先级不受父节点的限制。
  • 如果修改cgroup组父节点的优先级,子节点的优先级会自动调整,和父节点保持一致。

整数形式,取值范围为-1024~1023,默认值为0。

接口配置示例

按如下所示创建6个cgroup子节点A、B、C、D、E、F,配置memcg_qos_enable接口,并通过memory.qos_level接口设置OOM的优先级,优先级取值如图所示。

表1 数据规划

cgroup组

memory.qos_level取值

说明

A

-8

当在root中进行OOM操作时,内核遍历root所有cgroup组,最终选择优先级最低的A、E。由于A和E优先级相同,内核继续对A和E使用的内存进行比较。

  • 如果设置memcg_qos_enable=1,优先对A/E中内存使用量大的一个cgroup组回收内存,结束cgroup组中的所有进程,并回收内存。
  • 如果设置memcg_qos_enable=2,优先对A/E中内存使用量最大的一个进程回收内存。

B

10

C

1

D

2

E

-8

F

3

  1. 关闭系统参数vm.panic_on_oom。
    sysctl -w vm.panic_on_oom=0
  2. 开启memcg OOM优先级策略功能。
    echo 1 > /proc/sys/vm/memcg_qos_enable
  3. 运行以下命令创建两个cgroup节点 A、B,并分别设置A、B节点的memcg OOM优先级值为-8、10。
    mkdir /sys/fs/cgroup/memory/A
    mkdir /sys/fs/cgroup/memory/B
    cd /sys/fs/cgroup/memory/A
    echo -8 > memory.qos_level
    cd /sys/fs/cgroup/memory/B
    echo 10 > memory.qos_level
  4. 运行以下命令分别在A节点下创建C、D子节点,在B节点下创建E、F子节点, 并分别设置C、D、E、F子节点的memcg OOM优先级值为1、2、-8、3。
    mkdir /sys/fs/cgroup/memory/A/C
    mkdir /sys/fs/cgroup/memory/A/D
    mkdir /sys/fs/cgroup/memory/B/E
    mkdir /sys/fs/cgroup/memory/B/F
    cd /sys/fs/cgroup/memory/A/C
    echo 1 > memory.qos_level
    cd /sys/fs/cgroup/memory/A/D
    echo 2 > memory.qos_level
    cd /sys/fs/cgroup/memory/B/E
    echo -8 > memory.qos_level
    cd /sys/fs/cgroup/memory/B/F
    echo 3 > memory.qos_level