概述
今天,想尝试复现一个问题,需要达到一个效果就是将 CPU 打满,制造一个负载很高的情况,我的第一想法就是使用 stress,结果发现居然一直都打不满,只能打到一半(50%)就到顶了,所以就探索了一下什么问题,顺便记录一下。
操作过程
首先,我先看了一下这台机器上有几个核,总共有几个线程,然后以对应线程数量去启动 stress:
[root@liqiang.io]# cat /proc/cpuinfo | grep "core id" | wc -l
6
[root@liqiang.io]# cat /proc/cpuinfo | grep "processor" | wc -l
6
这里需要看的是逻辑核心数(线程数),实际上物理核是 6 个,每个核的线程数是 1 个,所以总共需要 6 个,没问题。接着就是启动 stress 了:
[root@liqiang.io]# stress -c 6
然后就看到 CPU 使用率是这样的:
图 1:stress cpu 使用率 |
---|
这就很厉害了,可以看到其实 stress 只占用了一个 core,然后使用率就是只有一个 100%,并没有达到我的预期,然后我就像,我多开两个不就行了,然后又开了一个 terminal,再跑一个,结果就变成这样了:
图 2:多开 stress cpu 使用率 |
---|
你看他们,波澜不惊,继续平分,多么气人。那么这是什么问题呢?为什么会另开 terminal 也会跑到同一个 core 里面去呢,这应该有一些猫腻。
问题定位
所以我的怀疑方向是有同事限制了 shell 的 cgroup,导致我只能用固定的 core,于是我就先看看 stress 的 cgroup 是啥:
[root@liqiang.io]# cat /proc/5813/cgroup
11:perf_event:/
10:cpuset:/zbs/app
9:devices:/system.slice/sshd.service
8:freezer:/
7:pids:/
6:blkio:/system.slice/sshd.service
5:net_prio,net_cls:/
4:hugetlb:/
3:cpuacct,cpu:/system.slice/sshd.service
2:memory:/system.slice/sshd.service
1:name=systemd:/system.slice/sshd.service
ok,从这里可以看到使用的 cpuset 是一个叫做 /zbs/app 的 cgroup 项,那再一步看看具体是怎么限制的:
[root@liqiang.io]# cat /etc/cgconfig.conf | grep -A 7 zbs/app
group zbs/app {
cpuset {
cpuset.cpus = "4,5";
cpuset.mems = "0";
cpuset.cpu_exclusive = "0";
cpuset.mem_hardwall = "1";
}
}
可以看到是被限制到了 cpu 4 和 5 上了,对照一下 top 的 cpu 使用率看是否吻合:
图 3:详细的 cpu 使用率 |
---|
ok,看上去就是这个问题,那么我要将 CPU 打满的话, 最简单的处理方式就是去掉这个 cgroup 限制就好了,但是这不太友好,所以更友好的方式应该是单独过滤我的 stress 进程,其他的照旧。