我编写了一个程序(监控插件),用于从中读取 CPU 使用率数字/proc/stat
。不幸的是,这些数字似乎与手册页不符proc(5)
,尤其是我得到了真实机器和 Xen 半虚拟化机器的不同比例:
这些机器的空闲时间有所不同:
(关于“代码块”的解释如下:第一部分显示了“ cpu
”行的字段(例如:“ cpu#1
”是 行的第一个字段CPU
),后面跟着引导计数(“epoch”)、UNIX 时间和实际值,每个值都用冒号 ( ) 分隔:
。下一行以“ stat: OK
”开头是我的监控插件的输出;这里它输出差异以用于调试目的,但通常它会输出差异率。它还为数字添加了用户可读的标签。“ time
”是自上次调用以来的时间差(以秒为单位)。最后,我添加了与 CPU 相关的行/proc/stat
(自插件输出以来经过了一些时间)。)
首先是每台物理机双 CPU、6 核、2 个线程:空闲时间似乎是其他 CPU 状态总和的 900 倍左右,对应 99.89%闲置的和 0.06%用户CPU。还请注意,空闲时间与已用时间的关系约为 2398.5;除以USER_HZ
(100) 后,您可以粗略地得到 CPU 的数量。这对我来说看起来很奇怪:
# physical two 6-core cpus, 2 threads each
cpu#1=0:1596547833:2667804
cpu#2=0:1596547833:90388
cpu#3=0:1596547833:1257514
cpu#4=0:1596547833:2735255340
cpu#5=0:1596547833:142707
cpu#6=0:1596547833:0
cpu#7=0:1596547833:107191
cpu#8=0:1596547833:0
cpu#9=0:1596547833:0
cpu#10=0:1596547833:0
stat OK: epoch=0, time=354, cpu.usr=581, cpu.ni=24, cpu.sys=288, cpu.idl=849070, cpu.iow=29, cpu.hirq=0, cpu.sirq=13, cpu.st=0, cpu.vgst=0, cpu.usr0=0
# cat /proc/stat
cpu 2668778 90430 1257998 2736664140 142741 0 107213 0 0 0
cpu0 116314 1436 53622 113861868 3864 0 81296 0 0 0
cpu1 142008 4782 32464 114026161 9767 0 4396 0 0 0
cpu2 167052 3058 63902 113932120 12818 0 1966 0 0 0
cpu3 120029 4260 28712 114058016 3337 0 1478 0 0 0
cpu4 145332 2972 61798 113983716 16115 0 1037 0 0 0
cpu5 114346 6809 27875 114060364 4110 0 1124 0 0 0
cpu6 126193 3720 54701 113999094 12348 0 968 0 0 0
cpu7 108188 4859 27436 114067537 6028 0 976 0 0 0
cpu8 121890 2820 51548 114020211 13474 0 940 0 0 0
cpu9 102942 4235 26150 114076765 3423 0 977 0 0 0
cpu10 125984 2724 48521 114014015 13950 0 845 0 0 0
cpu11 89154 4047 26674 114085160 7735 0 885 0 0 0
cpu12 116730 3894 397743 113663892 2352 0 884 0 0 0
cpu13 84306 4424 26164 114096015 2767 0 871 0 0 0
cpu14 127293 3539 44438 114033462 1294 0 922 0 0 0
cpu15 77740 3958 26201 114105245 358 0 854 0 0 0
cpu16 133217 3043 41476 114034324 737 0 958 0 0 0
cpu17 88893 4497 25736 114094645 662 0 838 0 0 0
cpu18 125887 2812 39150 114024555 1309 0 806 0 0 0
cpu19 65198 3560 25976 114092343 21838 0 802 0 0 0
cpu20 109361 3292 37270 114059144 1381 0 764 0 0 0
cpu21 71055 4094 26435 114111750 759 0 859 0 0 0
cpu22 118589 3643 37525 114052728 1567 0 883 0 0 0
cpu23 71069 3943 26468 114110998 737 0 875 0 0 0
然后是具有两个虚拟 CPU 的 Xen 半虚拟化机器。空闲时间约为其他 CPU 状态总和的 74 倍,对应 98.66%闲置的和 8%用户cpu。同样,如果你取空闲时间与已用时间的比例,你会得到 197.4,大致相当于 2 个 CPU。这里有一个问题:用户 CPU 和空闲时间超过 100%。
## virtual 2 cpus (Xen PV)
cpu#1=0:1596547988:1162034
cpu#2=0:1596547988:227660
cpu#3=0:1596547988:3036855
cpu#4=0:1596547988:701649884
cpu#5=0:1596547988:1037577
cpu#6=0:1596547988:0
cpu#7=0:1596547988:31478
cpu#8=0:1596547988:355862
cpu#9=0:1596547988:0
cpu#10=0:1596547988:0
stat OK: epoch=0, time=36, cpu.usr=16, cpu.ni=7, cpu.sys=28, cpu.idl=7108, cpu.iow=4, cpu.hirq=0, cpu.sirq=0, cpu.st=5, cpu.vgst=0, cpu.usr0=0
> cat /proc/stat
cpu 1162136 227690 3037149 701727879 1037664 0 31481 355901 0 0
cpu0 531438 112727 1469157 350497090 791387 0 31011 192100 0 0
cpu1 630698 114962 1567991 351230788 246276 0 470 163801 0 0
我知道这些数字/proc/stat
是 USER_HZ,但这不应该作为一个共同因素,对吗?
我觉得空闲比例与其余 CPU 状态不匹配(太高?),但我无法识别出问题所在。(我还意识到,对于多个核心,你永远无法一致地读取这些数字/proc/stat
,但差异足够小,可以忽略不计)
答案1
可能是因为/proc/stat
主要错误的“特殊性”是试图将 CPU 累积的滴答声与经过的时间联系起来:
除了多个 CPU 的读数不一致之外,甚至一个 CPU 的所有状态总和在不同的 CPU 之间也存在很大差异(有人会猜测任何 CPU 都必须处于任何列出的州)。
例如,在双插槽、6 核、2 线程的机器上,总和如下:
Total 100.00% ( 99539187188)
Total cpu #1 100.00% ( 4140261989)
Total cpu #2 100.00% ( 4144710272)
Total cpu #3 100.00% ( 4151313481)
...
Total cpu #22 100.00% ( 4148181711)
Total cpu #23 100.00% ( 4147345315)
Total cpu #24 100.00% ( 4154271398)
total sum is 99539187091
因此,正确的算法是将一个 CPU 的所有字段的所有滴答计数相加,然后将该 CPU(且仅限该 CPU)的各个字段除以该和。然后,您将获得如下所示的单独和总相对 CPU 统计数据:
user 0.24% ( 237735999)
nice 0.01% ( 5002498)
system 0.63% ( 630749296)
idle 98.41% ( 97954146521)
iowait 0.39% ( 385255182)
irq 0.00% ( 186187)
softirq 0.16% ( 157069844)
steal 0.17% ( 169041661)
guest 0.00% ( 0)
guest_nice 0.00% ( 0)
Total 100.00% ( 99539187188)
user 0.47% ( 19423699)
nice 0.01% ( 218870)
system 1.20% ( 49511456)
idle 97.49% ( 4036508813)
iowait 0.41% ( 17117301)
irq 0.00% ( 5014)
softirq 0.18% ( 7495287)
steal 0.24% ( 9981549)
guest 0.00% ( 0)
guest_nice 0.00% ( 0)
Total cpu #1 100.00% ( 4140261989)
...
user 0.27% ( 11119646)
nice 0.01% ( 272401)
system 0.55% ( 22956454)
idle 98.63% ( 4097537498)
iowait 0.32% ( 13130627)
irq 0.00% ( 3663)
softirq 0.09% ( 3893145)
steal 0.13% ( 5357964)
guest 0.00% ( 0)
guest_nice 0.00% ( 0)
Total cpu #24 100.00% ( 4154271398)
最后,如果您取所有单个 CPU 统计数据的平均值,您将或多或少地获得总体统计数据(总和不同;这就是我所说的“不一致的读数”):
Avg. user 0.24% ( 237735987)
mismatch for cpu stat #0: 237735999 - 237735987 is 12
Avg. nice 0.01% ( 5002486)
mismatch for cpu stat #1: 5002498 - 5002486 is 12
Avg. system 0.63% ( 630749284)
mismatch for cpu stat #2: 630749296 - 630749284 is 12
Avg. idle 98.41% ( 97954146509)
mismatch for cpu stat #3: 97954146521 - 97954146509 is 12
Avg. iowait 0.39% ( 385255171)
mismatch for cpu stat #4: 385255182 - 385255171 is 11
Avg. irq 0.00% ( 186174)
mismatch for cpu stat #5: 186187 - 186174 is 13
Avg. softirq 0.16% ( 157069830)
mismatch for cpu stat #6: 157069844 - 157069830 is 14
Avg. steal 0.17% ( 169041650)
mismatch for cpu stat #7: 169041661 - 169041650 is 11
Avg. guest 0.00% ( 0)
Avg. guest_nice 0.00% ( 0)
Total 100.00% ( 99539187091)
所有百分比数字都以 输出printf("%6.2f%%", ...)
,因此它们是四舍五入的。
最后,这是一台繁忙的“48 CPU”机器的总数:
Total 100.00% ( 21877206847)
Total cpu #1 100.00% ( 455281359)
Total cpu #2 100.00% ( 455501710)
Total cpu #3 100.00% ( 455015811)
Total cpu #4 100.00% ( 456004044)
Total cpu #5 100.00% ( 455909301)
Total cpu #6 100.00% ( 455981392)
Total cpu #7 100.00% ( 455729034)
Total cpu #8 100.00% ( 456028994)
Total cpu #9 100.00% ( 456049969)
Total cpu #10 100.00% ( 455860960)
Total cpu #11 100.00% ( 455870035)
Total cpu #12 100.00% ( 456039088)
Total cpu #13 100.00% ( 456028481)
Total cpu #14 100.00% ( 455902588)
Total cpu #15 100.00% ( 454901116)
Total cpu #16 100.00% ( 456039049)
Total cpu #17 100.00% ( 456079322)
Total cpu #18 100.00% ( 456018015)
Total cpu #19 100.00% ( 455811530)
Total cpu #20 100.00% ( 456048623)
Total cpu #21 100.00% ( 455174048)
Total cpu #22 100.00% ( 455986778)
Total cpu #23 100.00% ( 455045645)
Total cpu #24 100.00% ( 456062558)
Total cpu #25 100.00% ( 456074695)
Total cpu #26 100.00% ( 456046892)
Total cpu #27 100.00% ( 455889172)
Total cpu #28 100.00% ( 456067743)
Total cpu #29 100.00% ( 455975866)
Total cpu #30 100.00% ( 455998701)
Total cpu #31 100.00% ( 455324199)
Total cpu #32 100.00% ( 456078454)
Total cpu #33 100.00% ( 455430179)
Total cpu #34 100.00% ( 456052808)
Total cpu #35 100.00% ( 454948089)
Total cpu #36 100.00% ( 456056733)
Total cpu #37 100.00% ( 455406941)
Total cpu #38 100.00% ( 456040647)
Total cpu #39 100.00% ( 455873538)
Total cpu #40 100.00% ( 456075263)
Total cpu #41 100.00% ( 456020834)
Total cpu #42 100.00% ( 456053464)
Total cpu #43 100.00% ( 455017805)
Total cpu #44 100.00% ( 456063505)
Total cpu #45 100.00% ( 455146763)
Total cpu #46 100.00% ( 455838738)
Total cpu #47 100.00% ( 455278795)
Total cpu #48 100.00% ( 456077454)
Total (all CPUs)100.00% ( 21877206728)