我的 cgroup 是否超载?

我的 cgroup 是否超载?

假设我限制了允许与 cgroup/cpuset 选项一起使用的一组进程的核心。

我需要知道是否有太多线程分配给该 cgroup,以及线程是否正在经历对可用核心的过度竞争。

我怎样才能做到这一点?

如果没有 cgroupups,我只需使用平均负载,根据top经验,平均负载应小于核心数。有没有类似的东西考虑cgroup/cpuset?

答案1

根据您具体关心的内容,有两种选择:

如果您关心 cgroup 中有多少线程/进程,而不是“平均负载”:

tasks只需计算cgroup 文件中的行数即可。每当 cgroup 中创建或删除线程或进程时,该文件都会自动更新。

如果您关心实际利用率:

这有点棘手。您可以从上述tasks文件中获取 cgroup 中的进程/线程列表,然后使用 检查每个 PID 的使用情况/proc,但这种方法有很多竞争条件,您可以将其作为一项竞技运动来货币化。或者,如果您使用版本 2 cgroup,则可以检查cpu.statcgroup 中的文件。该文件将有几行计算 cgroup 消耗的 CPU 时间的微秒数,因此您可以通过每隔一秒检查两次并将差值除以 10000 来获得利用率百分比(对于 100%一个核心的充分利用,两个核心的充分利用为 20%,等等)。可以使用带有 cpuacct 控制器的版本一 cgroup 来完成类似的方法(在该控制器下创建一个 cgroup,镜像您在 cpuset 控制器下创建的 cgroup)。

答案2

我编写了简单的脚本来计算执行该进程的 cgroup 的平均负载。

$ cat loadavg-cgroup.sh
#!/bin/bash

sample_time=${1:-1} # in seconds
sample_count=${2:-10}
sleep_time="$(echo "scale=2 ; ${sample_time}/${sample_count}" | bc)"

cgroup=$(grep '^2:cpu:' /proc/$$/cgroup)
export cgroup

{
        for _ in $(seq 1 "${sample_count}" ) ; do
                # note, for cgroup v2 use newest pgrep
                ps -eLo cgroup,stat | grep "${cgroup}" | grep ' R[l+]*$' --count
                sleep "${sleep_time}"
        done
} \
| awk '{ sum+=$1 } END { print (sum/NR) - 1 } ' 

用法:

# To calculate load average for period of 10 seconds
$ ./loadavg-cgroup.sh 10
1.6

评论:

  • 采样时间和数量样本的数量被参数化(分别作为第一和第二参数)
  • 这是针对 cgroups v1 的,因为我的 WSL2 环境中有这个
  • 最新的pgrep也可以与搜索 cgroup 一起使用,因此使用它比 ps+grep+grep trio 更好。
  • 不包括ps在平均负载中
  • 这对于进程不在 cgroup 中的情况不起作用,但调整它应该非常简单

相关内容