控制群组(control group)简称为cgroup,是Linux的内核功能。系统通过cgroup可以对系统内的资源进行分配、管理、监控等操作。不合理的cgroup层级或数量可能引起系统中应用性能的不稳定。本文主要介绍问题现象以及如何避免该类问题的出现。

问题现象

在容器相关的业务场景下,系统中的应用偶然会出现请求延时增大,并且容器所属宿主机的CPU使用率中,sys指标(内核空间占用CPU的百分比)达到30%及以上。例如,通过top命令查看Linux系统性能数据时,CPU的sy指标达到30%。
top - 16:21:19 up 22 days,  1:59,  3 users,  load average: 40.02, 30.02, 25.06
Tasks: 193 total,   3 running, 190 sleeping,   0 stopped,   0 zombie
%Cpu(s):  20.0 us,  30.0 sy,  0.0 ni, 45.0 id,  5.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem : 24130808 total,  2071424 free,  1832512 used, 20226872 buff/cache
KiB Swap:        0 total,        0 free,        0 used. 19737776 avail Mem

可能原因

例如,运行cat /proc/cgroups 查看当前所有控制群组的状态,发现memory对应的cgroup数目高达2040。
#subsys_name  hierarchy num_cgroups enabled
cpuset  2     200     1
cpu     2     200     1
cpuacct 2     200     1
blkio   6     62      1
memory  10    2040    1
devices 5     59      1

此时您可以通过perf工具动态分析,定位出现问题的原因。

  1. 运行以下命令,安装perf工具。
    yum install perf -y
  2. 运行以下命令,对系统的进程进行采样、分析。
    perf record -a -g sleep 10
  3. 运行以下命令,查看分析结果。
    perf report
    命令行返回结果示例,如下所示:
    31.04%  [kernel]                                      [k] memcg_stat_show
    18.61%  [kernel]                                      [k] memcg_sum_events.isra.22
    9.41%  [kernel]                                      [k] mem_cgroup_iter
    6.94%  [kernel]                                      [k] css_next_descendant_pre
    6.11%  [kernel]                                      [k] _find_next_bit
    3.96%  [kernel]                                      [k] mem_cgroup_usage.part.43
    1.75%  [kernel]                                      [k] find_next_bit
    1.38%  [kernel]                                      [k] mem_cgroup_node_nr_lru_pages
    从分析结果中,可得出Linux内核运行时间大多集中在memcg_stat_show函数,这是由于memory对应的cgroup数量过多,系统在遍历这些cgroup所导致的内核长时间运行。

    除了memory之外,cpuacct、cpu对应的cgroup过多还可能使CFS、load-balance的性能受影响。

解决方案

当您对Linux实例运维时,可参考以下两条建议,避免因cgroup引起的应用性能抖动。
  • cgroup的层级建议不超过10层。
  • cgroup的数量上限建议不超过1000,且应当尽可能地减少cgroup的数量。