英文:
In docker cpu usage calculation what are: TotalUsage, SystemUsage, PercpuUsage and what does the calculation means?
问题
我看到了关于CPU计算的Docker源代码,但我不太明白以下几点:
- TotalUsage:总使用量
- SystemUsage:系统使用量
- PercpuUsage:每个CPU的使用量
为什么要将cpuDelta
除以SystemDelta
,然后再乘以PercpuUsage
呢?
文档中对于cpuDelta
的解释是:
// 计算两次读取之间容器的CPU使用量变化
对于systemDelta
的解释是:
// 计算两次读取之间整个系统的变化
所以这两个增量应该都是累加,并且在该增量时间内除以总CPU使用量(或总纳秒数)。毕竟container
既消耗了cpuDelta
,也消耗了systemDelta
。
更新:我想我明白了,TotalUsage是容器的使用量,而SystemUsage不是容器使用的systemCPU
,而是整个系统的CPU使用量,这就是为什么要进行除法运算的原因。
英文:
I see in docker sources for cpu calculation but I don't get what are exactly
- TotalUsage
- SystemUsage
- PercpuUsage
why is cpuDelta
divided by SystemDelta
and also why then multiplied by PercpuUsage
?
The documentation says for cpuDelta
> // calculate the change for the cpu usage of the container in between
> readings
and for systemDelta
:
> // calculate the change for the entire system between readings
so shouldn't these delta's both be summed and divided by the total cpu (or total nanoseconds passed) during that delta time? after all the container
was consuming both the cpuDelta
and also systemDelta
Update: I think I get it the totalUsage is the container usage and the SystemUsage is not the systemCPU
used by the container but the whole system beyond the container cpu this is why they are divided.
答案1
得分: 6
以下是有关在Docker中计算CPU利用率的清晰概念:
-
带有"system"关键字的指标始终指的是运行Docker的主机指标。
-
不带关键字"system"的指标始终指的是与Docker内运行的容器相关的指标。
-
记住百分比公式。
-
SystemUsage = 运行Docker的主机的CPU利用率。这相当于百分比公式中的"整体"。
-
TotalUsage = 运行在Docker内的容器每个核心的CPU利用率。这相当于百分比公式中的"部分"。
-
PercpuUsage = 分配给容器的各个CPU核心的单独利用率。这也告诉我们分配给容器的CPU核心数量。
-
容器每个核心的CPU利用率变化 = 容器CPU的先前值 - 容器CPU的当前值。
-
主机CPU利用率变化 = 主机CPU的先前值 - 主机CPU的当前值。
-
容器CPU利用率的总变化 = 容器每个核心的CPU利用率变化 * 分配给容器的核心数[PercpuUsage核心数]。
-
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
cpuDelta = float64(v.CPUStats.CPUUsage.TotalUsage) - float64(previousCPU)
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
}
来自Docker统计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
}
},
用于计算初始和最终差异所需的先前CPU统计信息:
```json
"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
}
},
英文:
Below mention points will give an clear idea about CPU utilization calculation in docker:
- Metric with "system" keyword always refer to the HOST metric on which docker is running.
- Metric without the keyword "system" always refer to the metric related with
CONTAINER running inside docker. - REMEMBER the percentage formula
-
SystemUsage = The CPU utilization of the HOST on which docker is running.This is equivalent to "WHOLE" in the percentage formula.
-
TotalUsage = The CPU utilization per core of the CONTAINER which is running inside docker.This is equivalent to "PART" in the percentage formula.
-
PercpuUsage = Individual utilization of CPU cores allocated to the CONTAINER.This also let us know the number of CPU cores allocated to the CONTAINER.
-
Change in CONTAINER CPU per core utilization
= Previous value of CONTAINER CPU - Current value of CONTAINER CPU
-
Change in HOST CPU utilization
= Previous value of HOST CPU - Current value of HOST CPU
-
Total change in CONTAINER CPU utilization= Change in CONTAINER CPU per core utilization * Number of core allocated to container[PercpuUsage core count]
-
CPU utilization(%)=(Total change in CONTAINER CPU utilization / Change in HOST CPU utilization) * 100
The CPU utilization code written for docker in golang makes it easier to understand the terminologies mentioned above:
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
}
CPU stats from Docker stats API
"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
}
},
Previous CPU stats from Docker stats API [Which is required to calculate the initial and final difference]
"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
}
},
答案2
得分: 3
在问题18615中有一个类似的讨论,导致了PR 13627 "更新"docker stats"计算"
> 我认为cpuPercent = (cpuDelta / systemDelta) * float64(len(v.CpuStats.CpuUsage.PercpuUsage))
是正确的,因为:
> - cpuDelta
是所有核心消耗的总时间,
systemDelta
也是所有核心消耗的总时间,
> 所以(cpuDelta / systemDelta)
是每个核心的平均CPU使用率,因此需要乘以CPU核心数来计算总CPU使用率。
> 例如,在一个4核系统上,CPU使用率可以在0%和400%之间,因此必须乘以核心数。
英文:
There was a similar discussion in issue 18615 which led to PR 13627 "Update "docker stats " calculations"
> I think cpuPercent = (cpuDelta / systemDelta) * float64(len(v.CpuStats.CpuUsage.PercpuUsage))
is right, because:
> - cpuDelta
is total time consumed of all cores and
systemDelta
is also the total time consumed of all cores,
> so (cpuDelta / systemDelta)
is the average cpu usage of each core, so it need multiply the number of cpu cores to calculate the total cpu usage.
> for example, on a 4-core system, cpu usage can be anywhere between 0 and 400%, so it has to be multiplied by the number of cores.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论