一、steal 到底是什么:它不是你的程序慢,是宿主机抢走了你的 CPU 时间

CPU steal 不是你的程序跑不满 CPU,而是虚拟化宿主机把本该分给你的 CPU 时间拿去跑别人的负载了。这个数字在 Linux 的 /proc/stat 里有原始记录,含义是「虚拟化层报告的、你的 guest 没有在运行的 CPU 时间占比」。换句话说,你的进程明明在排队等 CPU,但调度器把物理核分给了同一台宿主机上的另一个 guest,你只能干等。
先说清它和另外两个相近指标的区别,这三个搞混是绝大多数误判的源头:
| 指标 | 含义 | 归因 | 你的处理方向 |
|---|---|---|---|
| user | 你的进程在用户态实际执行的 CPU 时间 | 你的代码 | 优化代码 |
| sys | 内核态时间,包括系统调用、中断处理 | 你的系统配置 | 调内核参数、减少 I/O |
| steal | 宿主机抢走的时间,你的 guest 根本没拿到 | 宿主机超售 | 换机器或找商家 |
steal 高意味着「你的 CPU 时间被卖了两遍」。一台物理机上如果超售严重,宿主机给每个 guest 都承诺了完整的 CPU 核数,但物理核根本不够,于是调度器抢时间,steal 就上去了。常见的技术实现是 hypervisor 把 vCPU 绑定到 CPU 池上统一调度,池里的物理核不够时,超出承诺的那部分时间就直接被记为 steal。所以 steal 这个数字,本质上是虚拟化层给宿主机超售行为开的账,不是你的内核统计出来的。
三个必须先排除的干扰项:
第一,steal 高但 idle 也高,往往不是超售。top 里看到 %st 高的时候,同时看 %id。如果 %id 也在 60% 以上,说明这个 vCPU 大部分时间是闲着的,宿主机没有在抢——正常空闲的 VPS 就是这个样子。这时候 %st 高只是采样窗口的假象,是「没在用的时候统计出来的比例」,数值本身没有业务含义。很多人第一次看到自己的机器 steal 有 8%,紧张了半天才发现 CPU 使用率才 3%,这就是把空占比当成了故障。
第二,steal 高但 load average 很低,通常也是假象。load 是就绪队列长度,你的 guest 没活干时 load 自然是 0,而 steal 统计的是虚拟化层的记账方式。两者背离时以 steal 的持续性为准,而不是以某个瞬时数值为准。一个持续十分钟都在 15% 的 steal,和一个偶尔跳一下到 15% 的 steal,完全是两回事。前者影响业务,后者只是宿主机上某个邻居跑了个一次性任务。
第三,宿主机上的真实超售,你在 guest 里是看不到根因的。你只能看到结果(steal 数值),看不到宿主机上跑的是谁、还有多少个邻居。这决定了后面所有处置动作只能是「要求补偿或换机器」,而不是「自己去修」——试图在 guest 内部优化来消除 steal,是方向性的错误,浪费时间且不会有任何效果。
还有一个概念要分清:steal 和「你的程序在等 I/O」是两回事。iowait 表示 CPU 空闲但有请求在排队等磁盘或网络;steal 表示 CPU 被别人拿走了。前者你换更快的硬盘有用,后者你换什么硬盘都没用。判断方法是看 vmstat 的 wa 列和 st 列谁高,以及 iostat 的 await 数值。
最后提醒一个术语陷阱:不同资料里 steal 也叫「被窃取时间」「CPU 窃取」「超售损失」「调度延迟」。搜索时把这几个词都试一遍,能找到更多实战案例和不同云厂商的实现差异,也能避免搜到一堆讲 CPU 缓存被窃取的无关内容。
二、判读阈值:多少算异常,看这三个数字的组合

单看一个 steal 百分比一定会误判。下面是可执行的验收标准,按这三个读数组合判断:
| 场景 | steal(vmstat 第四列 st) | idle(id) | 判定 |
|---|---|---|---|
| 持续 5 分钟以上 | 低于 5% | 任意 | 正常,忽略 |
| 持续 5 分钟以上 | 5% 到 10% | 高于 40% | 轻度,可观察不报警 |
| 持续 5 分钟以上 | 10% 到 25% | 任意 | 异常,需要找商家 |
| 持续 5 分钟以上 | 高于 25% | 任意 | 严重异常,应当要求换机 |
| 任意 | 高于 10% | 低于 20% | 最严重:真超售 |
关键在于最后一行。如果 steal 超过 10% 而 idle 低于 20%,意味着你的 guest 明明想跑满 CPU 却拿不到,这是典型的宿主机超售证据。实测时负载要压上去,否则 idle 高,数字没有说服力,商家也会以「你机器是空闲的」为由直接驳回。
配套的量化标准,三个都要满足才算通过:
- CPU 忙时 steal 低于 5%,持续 10 分钟采样窗口
- 业务 P99 延迟相对空闲基线劣化不超过 20%
- 压测期间 guest 实际可用算力不低于标称核数的 95%
第三条最关键。你买的 4 核,理论上应该有 4 核的算力。如果压满负载后实测可用算力只有 3.4 核,损耗超过 15%,那就是超售的直接量化证据,比「机器很卡」这种主观描述有力得多。前两条是相对指标,第三条是绝对指标,三者结合才能既说明「有多严重」又说明「严不严重」。
还要注意采样持续时间这个门槛。瞬时的 30% steal 可能只是宿主机上某个邻居在做一次性的大批量任务,几秒钟就过去了。要求 5 分钟以上的持续窗口,是因为业务受损也必须是持续的才算数。把连续 30 个采样点按分钟间隔采下来,是最有说服力的证据形式。
阈值不是用来「测过没过」的,是用来分档采取动作的。5% 以下不用管,5% 到 10% 记下来继续观察,10% 到 25% 开工单,高于 25% 直接准备迁移数据。把分档标准事先定好,比事后争论「到底算不算高」有效得多,也比每次都从头吵一遍更省时间。
三、怎么查:四条命令定位到具体数值和时段

第一步,看瞬时值和趋势(最常用)。
vmstat 1 10
输出里第四列 st 就是 steal 百分比。连续采样 10 次,每次间隔 1 秒,能看出是稳定偏高还是尖峰。
第二步,看累计占比(判断是否长期如此)。
cat /proc/stat | head -1
第一行开头是 cpu 后跟 8 个数字,依次是 user、nice、system、idle、iowait、irq、softirq、steal。用最左边两个数算出 steal 占总时间比例:
awk '/^cpu /{total=0; for(i=2;i<=NF;i++) total+=$i; printf "steal累计占比: %.2f%%\n", ($9/total)*100}' /proc/stat
这个数字叫累计占比,和瞬时值不一样。累计占比低(比如 2%)说明这台机器长期没有被明显超售;累计占比高(比如 18%)说明从开机到现在被抢过很多次。累计占比还有一个隐藏用处:如果它远高于你印象中的常态,说明超售不是最近才开始的,而是长期存在的。
第三步,看 top 里的 steal 显示。
top -b -n 1 | head -5
%st 这一列就是 steal。但要注意 top 的 CPU 显示是归一化后的相对占比,不是绝对百分比。top 的显示逻辑是:%us + %sy + %ni + %id + %wa + %hi + %si + %st = 100%,其中 %id 是空闲,不是「百分之百减去忙碌」。所以 top 里的 %st 要和 %id 一起看,两者分开看必然得出错误结论。
第四步(推荐):压测同时采样,把证据固定下来。
# 终端 1:后台压测,4 核全开
stress-ng --cpu 4 --timeout 600 --metrics-brief
# 终端 2:持续采样
for i in $(seq 1 30); do vmstat 1 2 | tail -1 | awk '{print strftime("%H:%M:%S"), "st="$16, "id="$15}'; sleep 2; done
这样你就有了「时间 + steal + idle」的对照表,谈赔付时这比一句「很卡」有用得多。
vmstat 输出里第一列是运行中的进程数,第二列是在可运行队列里的进程数,第四列才是 steal。写 awk 取字段时注意:tail -1 取的是「距现在这一秒」的即时行,前面还有一个「自开机以来的平均」行,两者 steal 值可能差很多。
如果服务器上没有 stress-ng,用 dd 也能压满 CPU:
dd if=/dev/zero of=/dev/null bs=1M count=1000000 &
一条命令一个核,要压满 4 核就开 4 条。压测期间用另一个终端跑 vmstat,效果和 stress-ng 基本一致。这个方法在最小化安装的系统上特别有用,因为 stress-ng 需要额外安装,而很多 VPS 镜像里并没有。
四、top 与 vmstat 读数对不上,是采样机制不同造成的

这是高频问题。同一台机器,top 显示 %st = 3%,vmstat 显示 st = 12%,到底信哪个?答案是两个都对,但问的不是同一个问题。
| 对比项 | top | vmstat 1 |
|---|---|---|
| 采样周期 | 默认 3 秒滚动平均 | 每次采样 1 秒 |
| 第一个样本 | 是开机以来的平均值(从累计值算) | 无历史,是瞬时值 |
| 分母 | 归一化后的 100% | 该秒内的全部 CPU 时间 |
| 尖峰敏感度 | 低,被 3 秒平均抹平 | 高,1 秒粒度 |
vmstat 1 的第一个数据行是「自开机以来的平均值」,第二行开始才是当前值。这是最容易踩的坑:
vmstat 1 3
输出三行,第一行不要看,从第二行开始看。很多教程写「vmstat 看 steal」,但没说要跳过第一行,于是你把开机以来的历史平均当成了当前值,还据此给商家发了一份错误的投诉,对方按错误数据回复你,两边都在浪费时间。
结论:判断「现在是否超售」用 vmstat 的第二行及以后;判断「这台机器历史上是否一直被超售」用 /proc/stat 的累计占比;top 只适合快速扫一眼趋势。
如果三者不一致,以 vmstat 瞬时值为准,因为 top 和 /proc/stat 都含历史累计成分。这也解释了为什么很多机器重启之后 top 里的 %st 变得很好看——累计值被清零了,但实际超售一点没变。
还有一个细节:top 的 %st 在低核数机器上会被放大。1 核机器上,一次 0.1 秒的抢占在 top 的 3 秒窗口里可能就显示成百分之几,看起来很吓人。核数越少,同样的绝对抢占量显示出来的比例越高,所以 1 核机器的 steal 读数要更谨慎地解读。
另外两个常被拿来对比的工具:mpstat 按核输出,pidstat 按进程输出。mpstat -P ALL 1 10 用来定位是哪个核被抢;pidstat -u 1 5 则是看你的哪个进程在消耗 CPU——它能帮你区分「是我的程序在跑」还是「是我的程序在等」。这两个工具装不上时,top 里按 1 键也能切到按核显示,勉强够用。
五、宿主机超售的间接证据:能拿到的和拿不到的

你无法直接看到宿主机上有多少个 guest,但可以拿到几类间接证据:
证据一:多核机器的 steal 曲线会同步。如果你的 VPS 是 4 核,而 steal 在多个核上同时升高(vmstat 的 st 是所有 CPU 的合计值),说明是整机级别的资源争抢,不是个别 vCPU 的调度抖动。
证据二:CPU 频率与 steal 的相关性。
grep MHz /proc/cpuinfo
如果压测期间 steal 高,同时 CPU 频率明显低于标称值,说明宿主机在争抢物理核心的同时也在降频。这是超售的双重证据。
证据三:磁盘和网络 IO 的异常抖动。超售的宿主机上,多个 guest 同时抢 CPU,IO 调度也会被拖慢:
iostat -x 1 5
关注 %util 和 await。若 %util 长期跑满而 await 数量级升高,是共享存储争抢的表现。
证据四:同商家的不同机器 steal 对比。如果你在同一家买了多台,同时压测多台,如果 steal 曲线形状高度相似,那基本可以确认是同一台物理宿主机上的超售。这是有力的一条,因为不同物理机的超售行为不会同步。
证据五:重启前后的对比。在业务低峰期重启一次机器,然后立刻重新跑同样的压测采样。如果重启后 steal 明显降低且能维持几个小时,说明问题出在那台宿主机当前的负载状态,而不是你的系统配置有误。
拿不到的证据:宿主机上一共塞了多少个 guest、你的 vCPU 和谁的 vCPU 共享物理核。这需要商家侧的超售比数据,只能要求对方提供,没有其他办法。也正因为如此,你的诉求只能是基于公开条款的补偿或迁移,而不是要求商家公开内部拓扑。这一条边界要提前认清,否则很容易把技术问题谈成互相指责,最后谁都拿不到想要的结果。
六、能向商家提出的具体处置要求(可执行清单)

拿到证据之后,别只发「机器很卡」,按下面的清单提要求,商家处理效率高得多:
第一步:先要数据,再谈补偿。把这三样东西整理成一份材料:
# 一、累计占比
awk '/^cpu /{total=0; for(i=2;i<=NF;i++) total+=$i; printf "%.2f\n", ($9/total)*100}' /proc/stat
# 二、压测期间 30 个采样点(时间 + st + id)
for i in $(seq 1 30); do vmstat 1 2 | tail -1 | awk '{print strftime("%H:%M:%S"), $16, $15}'; sleep 2; done
# 三、可用算力实测
stress-ng --cpu 4 --timeout 120 --metrics-brief | grep -i "bogo"
第二步:提出明确的三档要求,不要说「要求赔偿」这种空话。
| 档位 | 触发条件 | 要求商家做的事 |
|---|---|---|
| 一档 | 瞬时 steal 10% 到 25% 持续出现 | 提供宿主机超售比说明 + 该机型 SLA 条款 |
| 二档 | 累计占比高于 15% 或多核同步 steal | 迁移到独享宿主机,或提供等值 CPU 补偿 |
| 三档 | 瞬时 steal 高于 25%,或压测可用算力低于标称 85% | 免费换机 + 未使用时长全额退 |
第三步:问清三个条款问题。这三个问题的答案直接决定你后续的所有决策:
- 该机型的超售比上限是多少(商务套餐通常会写,独享 CPU 套餐会写「不超售」)
- 出现超售时是否提供换机(有 SLA 的商家会承诺响应时限)
- 你买的套餐是否标注了 CPU 独占
如果商家明确写了「CPU 独占」或「不超售」,而你实测持续 steal 超过 10%,这就是违反条款,可以直接引用条款要求换机,不需要再讨论技术细节。这一步的沟通成本,比讲十分钟原理低得多。
第四步:提要求时把时间线讲清楚。给出「什么时候开始出现、持续多久、影响了哪个业务、造成了多少延迟」。商家排查超售需要时间范围,太笼统的描述会让工单被搁置。附上你的机器配置(CPU 核数、内存、当前套餐名)和采样命令的原始输出,比任何形容词都有用。工单里带原始数据,是把「投诉」变成「工单」的关键。
七、什么情况下不该选超售型套餐:四种明确的不适用场景

有些场景,宿主机超售带来的风险不是「慢一点」,而是业务直接不成立。以下四种情况,不应该选共享 CPU 的超售型套餐:
场景一:实时音视频、直播推流、游戏服。依据是业务特征——这类业务对抖动敏感,一次几百毫秒的调度延迟就能被用户感知。共享 CPU 的 steal 是不可预测的突发,无法通过优化代码消除。替代方案:选标注 CPU 独享的机型,或直接按「独立物理核」报价的套餐。
场景二:数据库与计算同机,且有 SLA 承诺。依据是资源争抢的传导路径——数据库连接池在 steal 突增时会出现大量超时,而超时又会让应用层重试,重试进一步放大负载,形成正反馈。替代方案:数据库与应用分离部署,数据库那台选独享 CPU。
场景三:需要稳定跑满 CPU 的批处理、编译、转码。依据是 steal 的定义本身——你要的就是「持续占满」,而超售环境下宿主机会在你最需要算力的时候收走时间。替代方案:先用 stress-ng 实测 30 分钟,可用算力低于标称 90% 就不要下单;或者用按小时计费的机型做一次性任务,跑完即删。
场景四:延迟敏感但访问量低的小型 API。依据是计费方式——小内存机型往往单位内存成本最高。例如真实在售的 1 GB 机型为 19.99 美元/月、内存单价 19.99 美元/GB,16 GB 机型为 59.99 美元/月、内存单价 3.75 美元/GB。在这种价格结构下,你完全有预算上更宽松的机型去规避超售风险,而不是在 1 GB 机型上赌宿主机不抢。
以上四种场景的判断依据全部是公开事实(业务特征、CPU 共享机制、计费方式、内存单价),不涉及对任何商家的评价。换句话说,这些结论在任何一家商家、任何一款套餐上都成立,套到谁家都能用。
还有一个通用的判断原则:你的业务对「延迟抖动」越敏感,越不该选共享 CPU。抖动比平均速度重要——平均慢 20% 用户还能忍,偶尔卡一下反而更容易流失。判断抖动的量化方法是把延迟采样做成直方图,看 P99 和 P50 的比值:这个比值越大,说明抖动越明显,也越值得为此多花钱买独享 CPU。
反过来说,什么情况下共享 CPU 完全够用?静态站点、镜像仓库、个人博客这类低并发场景,超售带来的争抢概率低、影响面小,用共享 CPU 是性价比最高的选择。问题从来不是「共享 CPU 好不好」,而是「你的业务能不能容忍抖动」。想清楚这一个问题,选型问题就解决了一大半,剩下的只是比价。
八、算账:不同价位机器上的超售风险敞口有多大

把真实在售价格折算成单位成本,可以看出「单位内存越贵,越不该赌超售」这条规律。
按月付费的真实机型数据:
| 机型 | 月费 | 内存 | 系统盘 | 月流量 | 内存单价 | 磁盘单价 | 流量单价 |
|---|---|---|---|---|---|---|---|
| RosCloud-01 | 19.99 美元 | 1 GB | 20 GB | 1024 GB | 19.99 美元/GB | 0.999 美元/GB | 19.99 美元/TB |
| RosCloud-02 | 29.99 美元 | 2 GB | 40 GB | 2048 GB | 14.99 美元/GB | 0.75 美元/GB | 14.995 美元/TB |
| RosCloud-03 | 39.99 美元 | 4 GB | 80 GB | 3072 GB | 10.00 美元/GB | 0.5 美元/GB | 13.33 美元/TB |
| RosCloud-04 | 49.99 美元 | 8 GB | 160 GB | 4096 GB | 6.25 美元/GB | 0.312 美元/GB | 12.498 美元/TB |
| RosCloud-05 | 59.99 美元 | 16 GB | 240 GB | 5120 GB | 3.75 美元/GB | 0.25 美元/GB | 11.998 美元/TB |
| RosCloud-06 | 69.99 美元 | 24 GB | 320 GB | 6144 GB | 2.92 美元/GB | 0.219 美元/GB | 11.665 美元/TB |
内存单价从 19.99 美元/GB 降到 2.92 美元/GB,降幅 85%。这意味着:如果你只有 20 美元的月预算,买 1 GB 机型后,一个 200 MB 的额外服务就吃掉你 20% 的内存;同样的服务放在 16 GB 机型上只占 1.25%。在小内存机器上,你的容错空间被压到了极限——一次宿主机超售,你的业务就直接崩,而不是「有点慢」。
换成超售视角来算这笔账。假设你的业务实测 steal 为 15%,业务需要 2 核持续算力:
| 机型 | 标称 CPU | steal 15% 后可用算力 | 需要几台才能凑够 2 核可用算力 | 月成本 |
|---|---|---|---|---|
| RosCloud-01 | 2 核 | 1.7 核 | 2 台 | 39.98 美元 |
| RosCloud-03 | 4 核 | 3.4 核 | 1 台 | 39.99 美元 |
| RosCloud-05 | 6 核 | 5.1 核 | 1 台 | 59.99 美元 |
RosCloud-01 跑两台和 RosCloud-03 跑一台的月成本几乎相同(39.98 与 39.99 美元),但后者是单台机器,管理成本减半,故障面减半。这就是「单位内存越贵,越不该赌超售」的具体含义。买两台小机器对冲超售,等于用双倍的管理成本换同样的算力,还多了一个机房不通、IP 分散、备份复杂的新问题。
再看年付线上的机型,单位成本还有进一步空间:
| 机型 | 年费 | 折合月费 | 内存 | 系统盘 | 月流量 | 内存单价 | 磁盘单价 | 流量单价 |
|---|---|---|---|---|---|---|---|---|
| LAX-STARTER | 200 美元 | 16.67 美元 | 2 GB | 40 GB | 5000 GB | 8.33 美元/GB | 0.417 美元/GB | 3.413 美元/TB |
| LAX-MICRO | 400 美元 | 33.33 美元 | 4 GB | 80 GB | 10000 GB | 8.33 美元/GB | 0.417 美元/GB | 3.413 美元/TB |
| LAX-Storage-500G | 400 美元 | 33.33 美元 | 4 GB | 500 GB | 10000 GB | 8.33 美元/GB | 0.067 美元/GB | 3.413 美元/TB |
| LAX-MEDIUM | 800 美元 | 66.67 美元 | 8 GB | 160 GB | 20000 GB | 8.33 美元/GB | 0.417 美元/GB | 3.413 美元/TB |
| LAX-LARGE | 1600 美元 | 133.33 美元 | 16 GB | 320 GB | 40000 GB | 8.33 美元/GB | 0.417 美元/GB | 3.413 美元/TB |
LAX-STARTER 折合月费 16.67 美元,比 RosCloud-01 的 19.99 美元还低,内存单价 8.33 美元/GB 也低于 19.99 美元/GB。在「低预算 + 高风险规避」这个组合上,年付小规格机型是更优解,前提是你能接受年付的锁定成本,以及选的是标注了独享 CPU 的型号。
最后一条算账结论:不要为了「省下一点点钱」去接受一个会毁掉你 SLA 的风险敞口。steal 超售的代价不是每月多花十几美元,而是业务降级、赔付、工单扯皮,代价远高于差价。
再补一条流量维度的账。按月付费的 RosCloud 系列流量单价在 11.665 到 19.99 美元/TB 之间,年付的 LAX 系列是 3.413 美元/TB。如果你既对抖动敏感又跑大流量,年付线在这两个维度上同时占优——这解释了为什么同样标称 4 GB,年付机型和月付机型在单位成本上能差出一倍以上。
九、处理流程:发现 steal 高之后,按四步走

第一步,先排除自己这边的干扰(10 分钟)。
# 1) 确认没有本地负载在跑
uptime
# 2) 确认 steal 是不是历史累计造成的错觉
awk '/^cpu /{total=0; for(i=2;i<=NF;i++) total+=$i; printf "%.2f\n", ($9/total)*100}' /proc/stat
# 3) 压测中重新采样
vmstat 1 10 | tail -9
第二步,确定性判定(30 分钟)。用第二节的组合表:压测期间 steal 是否持续高于 10%、idle 是否低于 20%、可用算力是否低于标称 85%。三条都满足,就是宿主机超售。
第三步,同商家横向验证(可选但强烈建议)。如果手里有同商家的多台机器,同时压测并采样。steal 曲线同步 = 同一物理宿主机超售,这一条证据几乎无法反驳。
第四步,按第六节的三档清单提要求。同时准备迁移方案——查好备选机型的实际价格,确认新机器的 steal 实测在 5% 以内再迁数据。
还有一个「零成本」动作别漏:核对商家条款里有没有写 CPU 独享或不超售。写了而实测超标,是条款问题,处理路径比技术协商短得多。这一步花五分钟,可能直接省掉后面一周的扯皮。
迁移时的顺序也有讲究:先在新机器上跑同样的压测并采样,确认可用算力达标,再切流量。不要反过来——先切流量再验证,出了问题你既回不去,也说不清是迁移引起的还是超售引起的。数据同步和流量切换之间留一段观察期,这段观察期不要接任何关键业务。
最后把这一轮的采集脚本存成定时任务。每隔十分钟自动采一次 steal 和 idle,写进一个日志文件。这样你手上就有了跨越几天的趋势曲线,比单次快照更能说明问题,也让商家无法用「那是偶发」来搪塞。这一步的收益会随着时间累积,前期只花几分钟。
按你的情况,下一步该看哪家
上面讲的是判断标准,但多数人最后还是想问一句「那我该买谁」。按你的实际情况对照下面几条,直接去看对应的机型页比继续比价更快:
- 只想搭个站、预算优先:先看价格最低那档够不够用,别为用不上的配置付钱。看 iwebfusion 当前机型与价格
- 主要访客在国内、在意打开速度:先确认回程线路,再谈配置。看 racknerd 当前机型与价格
- 跑游戏服或实时业务:看上行抖动与防御能力,普通套餐往往不达标。看 cloudcone 当前机型与价格
- 只是开发测试、临时用:按小时或月付,用完就删,别买年付。看 digitalocean 当前机型与价格
价格与库存以商家页面当日显示为准,下单前建议先确认退款窗口与是否支持按月付费。
十、常见问题

Q:steal 一直 3% 到 5%,需要处理吗?不需要。5% 以下属于正常范围,任何虚拟化环境都会有一点点调度开销,不必焦虑。只有在持续超过 10% 且 idle 低于 20% 时才值得去谈。
Q:steal 高是不是说明我被限速了?不是。steal 是 CPU 层面的,限速通常在带宽层面。要区分得看两处:跑 iperf3 测实际带宽是否达到标称,跑 vmstat 看 steal 是否同时高。带宽达标而 steal 高,指向 CPU 超售。
Q:换个系统版本能降低 steal 吗?不能。steal 是宿主机层面的资源分配问题,与客户机操作系统无关。唯一的间接影响是:更精简的系统让 guest 本身少占一点 CPU,从而让你实际被抢走的比例看起来低一点,但那只是分母变了,总算力并没有变。
Q:hostwinds 这类写「不超售」的商家,实际 steal 就一定是 0 吗?不一定。「不超售」是条款承诺,不是运行时保证;宿主机在物理资源紧张时仍可能挤占。需要用实测验证——累计占比长期低于 2% 才算真正兑现。
Q:steal 高会不会是我自己的问题,比如内核 bug 或者 hypervisor 装错了?有可能是,但概率低,且可以排除。排除方法:在同商家的另一台机器上跑同样的压测和采样,如果只有一台高,那问题在宿主机这台;如果两台都高,检查你自己的脚本是否有忙循环(top 里 user 态会异常高)。另外 dmesg -T | grep -i -E "hypervisor|steal" 如果没有任何 hypervisor 警告输出,说明虚拟化层本身没报异常。
Q:怎么把 steal 的采样结果做成商家能直接采信的证据?做成一张时间表,三列:时间戳、steal 百分比、idle 百分比,加上一行压测命令和一行机器配置。关键是要有时间戳连续跨度(建议 30 分钟以上)和明确的压测负载,因为商家最容易质疑的就是「你是不是没压测就乱说」。命令模板:
for i in $(seq 1 30); do vmstat 1 2 | tail -1 | awk '{print strftime("%H:%M:%S"), "steal="$16, "idle="$15}'; sleep 60; done
Q:应该买 CPU 独享的套餐还是普通套餐?用一条线判断:如果你的业务在 steal 超过 10% 时会直接失败(实时类、数据库类、满载批处理类),买独享;否则买普通套餐并把实测数据存好,留作后续谈判筹码。独享套餐的成本通常体现在同配置下价格更高,需要自己比价确认。
Q:多核机器上 steal 是平均的还是每核独立的?vmstat 的 st 列是所有 CPU 的合计值。要区分是哪个核被抢,用 mpstat -P ALL 1 10,它会按 CPU 逐个列出 %steal。如果只有一个核高,那是那个 vCPU 所在队列的问题;如果全部同步升高,是整机争抢。
Q:steal 高但 CPU 使用率只有 30%,是不是超售更严重了?恰恰相反,那更可能是采样窗口问题。你的业务只用 30% 的 CPU,guest 大部分时间 idle,steal 的分母里 idle 占大头,看起来高但绝对量小。判断超售严重程度的正确指标是「压测满载后的可用算力」,不是空闲时的 steal 百分比。
Q:为什么同一台机器重启之后 top 显示的 steal 变好看了?因为 /proc/stat 的累计值被清零,top 的第一个采样值自然从零开始重新算。这不是超售被修好了,只是计数器归零。重启后要重新采集一轮 30 分钟以上的压测数据,才能判断真实情况。
Q:steal 高会自己恢复吗?会,但不可控。宿主机上的邻居负载下降后,steal 会自己回落。但你无法预测它什么时候降下来,也无法排除下一次高峰再来一次。如果你的业务有 SLA,不能把「可能会自己好」当成解决方案——把它当成「已知风险」,要么换机,要么降级业务对它的依赖。
Q:不同厂商的 VPS,steal 的正常基线一样吗?不一样。不同 hypervisor(KVM 常见的云厂商自研栈、部分厂商用的 Xen 或 Hyper-V)实现不同,统计口径存在差异。所以阈值要按「同厂商同类机器的对比」来定,而不是套用网上的通用数字。最靠谱的基线是你自己手头机器的累计占比——跑一周看看正常值是多少,超过自己基线两倍才值得报警。

喜欢
高兴
鬼脸
呵呵
无聊
伤心