在 docker cpu 使用率计算中,什么是:TotalUsage、SystemUsage、PercpuUsage 以及计算的含义是什么?

Jas*_*Jas 4 go docker

我在docker 资源中看到cpu 计算,但我不明白到底是什么

  1. 总使用量
  2. 系统使用
  3. PercpuUsage

为什么cpuDelta除以SystemDelta然后又乘以PercpuUsage

文档说 cpuDelta

// 计算两次读数之间容器 CPU 使用率的变化

systemDelta

// 计算两次读数之间整个系统的变化

那么这些 delta 不应该在那个 delta 时间内相加并除以总 cpu(或通过的总纳秒数)吗?毕竟container是耗时两个cpuDelta,也systemDelta

更新:我想我明白了,totalUsage 是容器使用量,而 SystemUsage 不是容器使用的,systemCPU而是容器 cpu 之外的整个系统,这就是它们被划分的原因。

小智 6

下面提到的几点将清楚地了解 docker 中的 CPU 利用率计算:

  1. 带有“system”关键字的指标始终是指运行 docker 的 HOST 指标。
  2. 没有关键字“系统”的指标总是指与在 docker 中运行的 CONTAINER 相关的指标。
  3. 记住百分比公式

  4. SystemUsage = 运行 docker 的 HOST 的 CPU 利用率。这相当于百分比公式中的“WHOLE”。

  5. TotalUsage = 在 docker 中运行的 CONTAINER 每个核心的 CPU 利用率。这相当于百分比公式中的“PART”。
  6. PercpuUsage = 分配给 CONTAINER 的 CPU 内核的单独利用率。这也让我们知道分配给 CONTAINER 的 CPU 内核数。
  7. 每个内核利用率的 CONTAINER CPU 变化

    = CONTAINER CPU 的先前值 - CONTAINER CPU 的当前值

  8. 主机 CPU 利用率的变化

    = 主机 CPU 的先前值 - 主机 CPU 的当前值

  9. CONTAINER CPU 利用率的总变化=每个核心利用率的 CONTAINER CPU 变化 * 分配给容器的核心数[PercpuUsage 核心数]
  10. CPU 利用率(%)=(容器 CPU 利用率的总变化/主机 CPU 利用率的变化)* 100

golang中为docker编写的CPU利用率代码更容易理解上面提到的术语:https : //github.com/moby/moby/blob/eb131c5383db8cac633919f82abad86c99bffbe5/cli/command/container/stats_helpers.go#L175-L188

func calculateCPUPercentUnix(previousCPU, previousSystem uint64, v *types.StatsJSON) float64 {
    var (
        cpuPercent = 0.0
        // calculate the change for the cpu usage of the container in between readings
        cpuDelta = float64(v.CPUStats.CPUUsage.TotalUsage) - float64(previousCPU)
        // calculate the change for the entire system between readings
        systemDelta = float64(v.CPUStats.SystemUsage) - float64(previousSystem)
    )

    if systemDelta > 0.0 && cpuDelta > 0.0 {
        cpuPercent = (cpuDelta / systemDelta) * float64(len(v.CPUStats.CPUUsage.PercpuUsage)) * 100.0
    }
    return cpuPercent
}
Run Code Online (Sandbox Code Playgroud)

来自 Docker stats API 的 CPU 统计信息

 "cpu_stats": {
    "cpu_usage": {
      "total_usage": 18730109057613,
      "percpu_usage": [
        2037710936955,
        1481642385431,
        1344435820732,
        1163032744042,
        1204372068508,
        5758852306067,
        1170010183583,
        988020711114,
        1191435357423,
        743892480387,
        715658853679,
        931045209692
      ],
      "usage_in_kernelmode": 856990000000,
      "usage_in_usermode": 17572550000000
    },
    "system_cpu_usage": 123541016890000000,
    "throttling_data": {
      "periods": 0,
      "throttled_periods": 0,
      "throttled_time": 0
    }
  },
Run Code Online (Sandbox Code Playgroud)

来自 Docker stats API 的先前 CPU 统计数据 [计算初始和最终差异所需]

"precpu_stats": {
    "cpu_usage": {
      "total_usage": 18730095876882,
      "percpu_usage": [
        2037709694286,
        1481641884454,
        1344434727538,
        1163031727858,
        1204370950455,
        5758849538503,
        1170009778051,
        988019895578,
        1191434644418,
        743892204863,
        715658782597,
        931042048281
      ],
      "usage_in_kernelmode": 856980000000,
      "usage_in_usermode": 17572550000000
    },
    "system_cpu_usage": 123541004930000000,
    "throttling_data": {
      "periods": 0,
      "throttled_periods": 0,
      "throttled_time": 0
    }
  },
Run Code Online (Sandbox Code Playgroud)