2核70%不是每小时70积分:用Python拆开CPU积分的消耗与补充
前一天回答一个突发性能型ECS的批处理问题时,我发现最容易混淆的不是公式,而是三个量:CPU使用率、积分消耗量和积分净变化。把它们直接当成同一条曲线,常常会算出看似合理、单位却不一致的结果。这篇把讨论中的估算独立整理成一个可运行的小例子,用于核对监控口径,没有新建云服务器,也没有对任何业务实例做压测。
先说明适用范围
截至2026年10月26日,华为云《CPU积分计算方法》区分了T6与S6:T6的突发能力受到积分余额约束,S6不能套用同样的耗尽结论。具体规格的发放速度必须查对应规格,不能看到“共享型”三个字就代入。
本文只建立一个简化模型:实例持续运行,使用率固定,积分按固定速率补充,没有碰到余额上限,也不处理初始积分与累积积分的优先级切换。模型用于检查单位和假设,不是官方计费器,也不预测实际调度性能。CPU积分与开发者成长积分是两个不同的系统,不能互相兑换。
官方文档给出的计量基准是:一个vCPU以100%利用率运行一分钟对应一个CPU积分。以下公式是据此进行的算术推导。
从一个小时的毛消耗开始
设vCPU数量为n,整机平均使用率为u,按小数输入,例如70%写0.70;每小时补充积分为r,当前可用余额为b。
- 每小时毛消耗g = 60 × n × u。
- 每小时净消耗d = g − r。
- 对应的每核平均基线u0 = r ÷ (60 × n)。
若d大于0,且后续负载和补充速率保持不变,线性估计的耗尽时间为b ÷ d小时。若d等于0,余额在这个模型中不下降;若d小于0,则是补充大于消耗,不能继续算成一个负数的“剩余时间”。
把2核、每小时补充24积分、70%使用率、余额60积分代入:毛消耗是84积分/小时,净消耗是60积分/小时,所以估计为1小时。这里的“1小时”来自一组人为设定的固定输入,不是从提问者机器或我的服务器上测出来的结果。
另一个容易误读的地方是20%。上述参数的每核平均基线是20%;两核合计相当于0.4个满载vCPU。它不代表每个核心只有20%的主频,更不意味着换一个同核数规格就必然快五倍。
用标准库把边界也写清楚
下面的函数只需要Python标准库。选择Decimal主要是让0.20这种十进制输入在演示中保持可读;它不能提高监控采样本身的准确度。函数返回每核平均基线、每小时毛消耗、每小时净消耗、线性耗尽时间,最后一项None表示当前固定条件下没有有限的耗尽时间。
from decimal import Decimal, InvalidOperation
def estimate(vcpus, credits_per_hour, utilization, balance):
"""Steady-utilization arithmetic only, not a live ECS prediction."""
if type(vcpus) is not int or vcpus <= 0:
raise ValueError('vcpus must be a positive integer')
try:
earn, use, left = map(Decimal, map(str, (
credits_per_hour, utilization, balance)))
except InvalidOperation as exc:
raise ValueError('numeric input required') from exc
if not all(x.is_finite() for x in (earn, use, left)):
raise ValueError('finite input required')
capacity = Decimal(60) * vcpus
if not (0 <= earn <= capacity and 0 <= use <= 1 and left >= 0):
raise ValueError('input outside supported range')
baseline = earn / capacity
gross = capacity * use
net = gross - earn
hours = left / net if net > 0 else None
return baseline, gross, net, hours
if __name__ == '__main__':
print(estimate(2, 24, '0.70', 60))
print(estimate(2, 24, '0.20', 60))
print(estimate(2, 24, '0.10', 60))
在本机实际运行后的输出:
(Decimal('0.2'), Decimal('84.00'), Decimal('60.00'), Decimal('1'))
(Decimal('0.2'), Decimal('24.00'), Decimal('0.00'), None)
(Decimal('0.2'), Decimal('12.00'), Decimal('-12.00'), None)
第二行专门检查除零边界;第三行保留负的净消耗,说明余额在增长,但不会输出负的倒计时。函数没有把增长无限外推,因为真实余额存在上限。为使示例输入自洽,代码还拒绝超过所有vCPU持续满载理论消耗的小时补充值;这是这个小模型的输入边界,不是在宣称平台提供了某种新规格限制。
验证结果与没有验证的部分
我先写了九项单元测试,让未实现的占位函数返回错误结果,确认测试出现断言失败,再补充计算与输入校验。最终九项通过,覆盖70%固定负载、低于基线、等于基线、满载得到0.625小时、空余额、无补充且空闲,以及无效核数、错误使用率、负余额和非有限数等输入。
这些测试验证的是本地算术函数。它们没有连接华为云API,没有验证某个实际账户的积分余额,也不能证明业务吞吐量、共享资源争用或网络延迟。特别是u应传0.70而不是70,错误单位应明确拒绝,不能悄悄当成满载处理。
拿真实监控核对时怎么用
实际使用时,先确定规格与基线,再在同一时间范围核对CPU使用率、CPU积分使用量、CPU积分累积量。华为云基础监控文档列出了cpu_credit_usage和cpu_credit_balance,具体支持范围与采样周期以该文档为准。不要把一个采样区间的用量直接当成每分钟速率,也不要把一天的平均使用率代入后,声称它能预测晚间短时峰值。
更合适的做法是标出批处理开始、排队增加和完成的时间,再观察积分下降是否与业务变慢同时发生。若余额仍充足而请求已经明显变慢,继续检查单核瓶颈、I/O等待、数据库锁和外部依赖;积分公式本身无法给这些原因排序。
是否换规格,还需要看任务完成时长、队列是否能在下一轮开始前清空、交互请求的延迟目标,以及低负载间隔能否补回积分。每天固定批处理和偶尔突发,可能得出不同选择;“每周运行三天”也不足以单独决定。真正比较新规格应在获准的测试环境中测同一份任务,本文没有执行升级、迁移、重启或新增资源。
这次练习最有用的结果,是把“消耗了多少”和“还剩多少”拆开,并让固定输入下的计算可以复跑。估算可以帮助检查监控解释,是否改变实例仍应由真实业务目标和受控测试决定。
参考资料
- 华为云《CPU积分计算方法》:https://support.huaweicloud.com/productdesc-ecs/ecs_01_0061.html
- 华为云《弹性云服务器支持的基础监控指标》:https://support.huaweicloud.com/usermanual-ecs/ecs_03_1002.html
两份文档于2026年10月26日核对。本文代码及合成输入为独立整理的演示;不包含他人问题原文、用户标识、机器标识、私有日志或访问凭据。
本文使用AI辅助整理,数值为合成输入,计算与测试范围如文中所述。
- 点赞
- 收藏
- 关注作者
评论(0)