SSD Nodes Learn Hosting plans →
指南 Matt Connor作者: Matt Connor · 已更新 2026-08-30

VPS CPU steal time 與鄰居干擾怎麼看

了解 CPU steal time 的確切意義,讀懂 vmstat 的 st 欄位,並用具體方法判斷問題來自 noisy neighbour,還是 VPS 自身過載。

Verified Every command ran end-to-end on a fresh Ubuntu 24.04 server, August 7, 2026.

CPU steal time 實際衡量的內容

CPU steal time 是指虛擬 CPU 已可執行、沒有任何等待條件,但 hypervisor 將實體核心提供給其他 guest 的時間比例。工作已排入佇列,但核心正在其他地方執行。Linux 會個別計算這些週期,並將其回報為 st。藉此即可區分「我的伺服器很忙」與「我的伺服器正在等待排程」。

這正是建立此計數器的原因。您自己的程序在 CPU 上執行的時間會回報為 us(user)或 sy(system)。工作在儲存裝置上遭封鎖的時間會回報為 wa(I/O wait)。若 vCPU(virtual CPU)可執行、位於 run queue 中、沒有待處理的 I/O,卻仍未執行,則會回報為 st。伺服器內部的任何元件都無法清除這個狀態,因為排程決策是在更底層的主機上做出的。

這直接源自 VPS 如何在多個 guest 之間共用一台實體機器。最常見的原因是鄰近 guest:同一個 node 上的另一個 guest 負載很高,因此主機必須在各 guest 之間分配核心。另一個容易被忽略的原因是,許多供應商會將共用 vCPU 限制在實體核心的一部分,而在某些 hypervisor 上,這項強制套用的限制會在 guest 內計入 steal。因此,高 st 數值表示核心沒有分配給您,但不一定能指出是誰佔用了核心。

Steal 數值的來源

核心本身無法測量 steal,因為它看不到主機。這項資訊由 hypervisor 提供。在 KVM 上,主機會將每個 vCPU 的計數器寫入與 guest 共用的頁面;guest 會在核心以 CONFIG_PARAVIRT_TIME_ACCOUNTING 建置時累加該計數器,所有發行版核心都符合此條件。Xen 則透過 runstate area 回報相同資訊。總計值會在唯一一個位置傳遞至 userspace:

head -1 /proc/stat

cpu 這一行包含 10 個計數器,單位是開機後累積的 USER_HZ ticks,順序如下:user、nice、system、idle、iowait、irq、softirq、steal、guest、guest_nice。steal 是標籤後的第 8 個數值。以下所有工具,包括 vmstat、top、mpstat 及任何 Prometheus exporter,都會讀取同一個欄位,並將兩次取樣轉換為百分比。

其中一項影響比其他因素更重要。如果 hypervisor 從未匯出這個計數器,該欄位會永遠維持 0,所有以此為基礎的工具都會回報平靜的 0.0,即使主機已過載。KVM 和 Xen 會匯出此計數器。VMware 和 Hyper-V 上的 guest 通常會持續回報 0。信任 0 之前,先確認平台:

systemd-detect-virt

它會輸出平台名稱,例如 kvm、xen、vmware 或 microsoft;若是在 bare metal 上,則會輸出 none。在 container 內,它會改為回報 runtime,例如 lxc、docker 或 podman。這只能說明 container 的環境,不能說明底層機器。在 kvm 上,0 確實表示主機沒有對你造成資源競爭。在永遠不會填入此欄位的平台上,0 完全不能證明沒有資源競爭;此時必須透過計時實際工作來判斷。

如何在 VPS 上檢查 CPU steal time?

vmstat 來自 procps 套件。幾乎所有 Ubuntu 和 Debian VPS 映像檔都已包含此工具,但部分精簡容器映像檔可能沒有,因此在依賴此工具前先行安裝。

sudo apt-get update
sudo apt-get install -y procps
vmstat --version
vmstat 1 5

vmstat --version 會輸出類似 vmstat from procps-ng 4.0.4 的一行內容。若能輸出該內容,表示工具已安裝,且讀取的是核心提供的實際計數器。接著,vmstat 1 5 會每秒取樣一次,共取 5 次。

procs -----------memory---------- ---swap-- -----io---- -system-- -------cpu-------
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st gu
 1  0      0 3216484  98304 1284360    0    0     4    18   62  110  3  1 96  0  0  0
 2  0      0 3216232  98304 1284360    0    0     0     0  248  431  6  2 84  0  8  0

在右側的 cpu 區塊中尋找 st 欄位。目前的 procps-ng 建置版本會在其後輸出 gu 欄位,用於 KVM guest time,因此 st 是從右側數來第二欄,而不是最右欄。請依欄位標題讀取數值,因為該欄位位置在不同版本之間曾經變更。

以下兩個習慣能讓讀值保持準確。第一筆資料列是自開機以來的平均值,因此請忽略該列,改讀後面的資料列。單次取樣也不能代表實際狀況,因為 steal 可能以突發形式出現:執行 vmstat 1 60,並持續監看完整 1 分鐘後再下結論。

top 也會在其 %Cpu(s) 摘要列中回報相同數值,欄位標記為 st:

%Cpu(s):  6.2 us,  2.1 sy,  0.0 ni, 83.9 id,  0.0 wa,  0.0 hi,  0.3 si,  7.5 st

若要查看各 CPU 核心的詳細資料,加入 sysstat:

sudo apt-get install -y sysstat
mpstat -P ALL 1 5

mpstat 會為每個 CPU 輸出一列,並包含 %steal 欄位,用來顯示所有 vCPU 是否都受到影響,或只有其中一個受到影響。若要保留支援工單所需的歷史資料,請儲存取樣結果,不要只在螢幕上查看:

date -u | tee -a ~/steal.log
mpstat -P ALL 1 5 | tee -a ~/steal.log

在你懷疑發生問題的時段,透過 cron 執行該命令。如此一來,檔案就能讓你向供應商展示確切的 10 分鐘資料,而不是只說「昨晚感覺很慢」。

偷取值代表什麼?

  • 穩定的 0.0。 代表狀況正常,或平台完全不回報 steal。先用 systemd-detect-virt 確認,再下結論。
  • 持續數秒、幅度只有幾個百分點的尖峰。 任何共享節點都可能出現,屬於正常現象。可能是鄰近租戶開始建置,或主機正在執行備份。
  • 共享方案持續維持 1 到 5 percent。 這是預期狀況。價格反映的就是共享 CPU。
  • 持續維持 5 到 10 percent。 這已是可測量的效能下降。開始記錄證據,並比較數天內相同時段的數值。
  • 一次持續數小時、超過 10 percent。 代表該節點對你的工作負載而言超額配置。這種程度足以提出支援請求,或遷移到其他節點。

請將這些區間視為判讀指南,而不是規格,因為沒有任何供應商會為共享方案公布 steal 保證。應根據實際執行的工作負載評估。夜間批次工作即使承受 15 percent 的 steal,也可能不會被察覺。對延遲敏感的服務而言,p99 會比平均值更早顯示問題;因此,交易機器人等延遲敏感的工作負載應配置在專用核心上。

Steal time 的成本是多少?

計算很簡單。如果 CPU 時間中有 s 被占用,需要固定 CPU 時間的工作,在實際經過時間上會變成原本的 1 / (1 - s) 倍。以需要 60 秒 CPU 時間的工作為例:

ChartWall clock time for a job needing 60 seconds of CPU
The data behind this chart
[
  {
    "steal_percent": 0,
    "wall_clock_seconds": "60.0"
  },
  {
    "steal_percent": 3,
    "wall_clock_seconds": "61.9"
  },
  {
    "steal_percent": 8,
    "wall_clock_seconds": "65.2"
  },
  {
    "steal_percent": 15,
    "wall_clock_seconds": "70.6"
  },
  {
    "steal_percent": 25,
    "wall_clock_seconds": "80.0"
  },
  {
    "steal_percent": 40,
    "wall_clock_seconds": "100.0"
  }
]

在 3 percent 時,這是一般共享方案的讀值;該工作需要 61.9 秒,而不是 60.0 秒。這通常不至於讓人提出支援請求。在 8 percent 時,需要 65.2 秒。在 40 percent 時,同一項工作需要 100.0 秒,原本能逐漸清空的佇列也會開始累積。

這些是計算值,不是測量值。此模型假設只有一個可執行執行緒,且 steal time 平均分布在整個期間。實際服務通常會比曲線顯示的情況更差,因為被占用的時間片可能落在請求處理期間,而所有等待該請求的工作都必須再次承擔這段延遲。若要取得自己的數值,而不是套用公式,請在低負載時段和高負載時段各執行一次 VPS 效能基準測試,並記錄兩個時段的 st。

這是 steal,還是其他問題?

Steal 很容易與其他症狀混淆。請在同一行 vmstat 中一起查看這些計數器。

  • st 偏高,而 r 與 us 維持偏低:主機沒有把 CPU 核心時間分配給你。這就是 steal。
  • r 明顯高於你的 vCPU 數量,且 us 偏高、st 接近 0:你執行的工作量超過自有 CPU 的處理能力。將 r 與 nproc 的輸出比較。這是你自己的超額配置,不是鄰近租戶造成的。
  • wa 偏高,而 st 接近 0:工作正在等待儲存裝置。這是不同的問題,也需要不同的處理方式。
  • 負載平均值偏高,但 st 與 us 都偏低:負載數值也會計入不可中斷的工作,因此通常表示裝置卡住或網路掛載無回應,而不是 CPU 問題。

Burstable 方案需要另外說明。這類方案會提供 credit balance;閒置時累積,忙碌時消耗。額度用完後,供應商會將你的速率限制在基準值。有些平台會將這項節流回報為 steal。其他平台則不會從系統內部顯示,你只會發現每秒取得的 CPU cycles 變少。判斷是否由鄰近租戶造成問題前,請先閱讀方案說明。

為什麼容器顯示沒有 steal time

Steal 是虛擬機器的屬性,不是其中執行的容器屬性。自有 VPS 上的 Docker 容器會共用主機的 /proc,因此在容器內讀取的 st 值就是 VPS 的 steal,這正是你需要的值。以容器為基礎、以 VPS 形式提供的虛擬化則不同。啟用 lxcfs 後,容器內的 /proc/stat 會根據 cgroup accounting 合成,因此 steal 會按設計固定為 0。只從容器內擷取資料的監控堆疊,可能顯示平穩且沒有變化的 0,但底層實體機器其實正面臨資源不足。

在容器內,具有相同意義的計數器是 CPU quota throttling。在 cgroup v2 中:

cat /sys/fs/cgroup/cpu.stat

nr_throttled 計算該群組觸及 CPU quota 的 enforcement period 次數,throttled_usec 則累計其遭凍結的時間。nr_throttled 持續上升表示你的程序處於 runnable 狀態但未獲得執行時間,體驗上與 steal 相同,但原因是你自行設定的限制。先檢查自己的限制,再判斷是否應歸咎於主機;如果你在 compose 檔案中設定 CPU limits,尤其要確認這點,例如 在 VPS 上使用 Docker 執行服務。分層虛擬化會增加另一個時間耗損點,因為 VPS 內的 VM 必須承受 VPS 的 steal,以及自身的排程延遲。如果你 在 VPS 上執行巢狀虛擬化,請將這點納入考量。

持續發生 steal 時的處理方式

guest 內沒有任何設定可以修正 steal,因為做出排程決策的 scheduler 在 guest 外部執行。升級 kernel 也不會改變這點:Linux kernel 7.2 中加入的快取感知排程會在實際分配給你的 core 之間重新安排工作,無法取回鄰居已經占用的 CPU cycles。實際可行的處理方式有 4 種。

先蒐集證據。 記錄 UTC 時間戳記、每次事件的持續時間、重複發生的頻率,以及 mpstat 是否顯示只有 1 個 vCPU 受影響,或所有 vCPU 都受影響。持續記錄 1 週的樣本,比單張螢幕截圖更有價值。

附上資料提交 ticket。 直接詢問 2 個問題:這些時段該 node 是否超額配置,以及是否可以將我的 instance 搬遷。貼上 vmstat 的輸出與確切時間。Provider 會根據可重現的時段處理問題;只寫「server 很慢」的 ticket,通常會收到要求提供具體時段的回覆。你能將多少工作交給 provider 處理,是 受管理與未受管理 VPS 之間的實際差異之一。

要求搬遷。 Provider 將 guest 搬到負載較低的 node 是例行工作,通常只需要短暫重新開機。這是無須額外付費的修正方式,也能解決常見情況:某個 node 同時承載多個高負載鄰居。

購買不受 contention 影響的方案。 Dedicated vCPU 方案會為你的 instance 保留實體 core,因此計數器會保持在 0。每月費用較高,但對無法承受這種變動的 workload 而言,這是誠實的選擇。如果這樣仍不足,或你也希望獨占 memory bandwidth,下一步就是使用 dedicated server,而不是 VPS。

在等待上述處理方式生效期間,先降低 steal 的影響。執行的 worker threads 應少於 vCPU 數量,因為無法取得 core 的 threads 只會增加 context switches。將批次工作移到 node 較清閒的時段;現在你自己的 log 已能指出這些時段。接著使用相同的 command,在相同時段再次測量,這樣才能判斷變更是否有效,而不是靠猜測。

FAQ

VPS 上正常的 CPU steal time 是多少?

在共享方案中,短暫的尖峰以及持續低於約 5% 的數值都屬正常。這是因為共享 CPU 代表主機會在多個來賓系統之間分配實體核心。持續數小時維持兩位數百分比則不正常,值得提交支援工單。在 dedicated vCPU 方案中,預期讀值為 0.0,因此出現其他數值時應回報故障。請根據自身工作負載判斷數值:需要一整晚執行的批次工作可以承受 steal,但對延遲敏感的 API 則不行。

擴大方案能解決高 steal time 嗎?

不能單靠擴大方案解決。在同一個共享節點上增加 vCPU,代表更多虛擬 CPU 會爭用相同的受限實體核心,百分比可能完全不變。能消除 steal 的方法是配置 dedicated CPU,或移至負載較低的節點。從繁忙主機取得更大的資源份額,仍然只是繁忙主機上的資源份額。

為什麼 VPS 明顯變慢,卻顯示 0 steal time?

常見原因有兩個。Hypervisor 可能根本不提供此計數器。VMware 和 Hyper-V 平台通常會有這種情況,因此無論主機上的實際狀況如何,欄位都會維持為零。執行 systemd-detect-virt,確認目前使用的平台。否則瓶頸可能在其他地方:檢查 wa 以查看儲存裝置等待,將 r 與 nproc 比較以確認自身是否過載,並在容器內讀取 /sys/fs/cgroup/cpu.stat 以檢查 quota throttling。

可以從伺服器內部降低 steal time 嗎?

無法從來賓系統內部變更主機的排程方式。只能降低它造成的影響。執行的 worker thread 數量應少於 vCPU 數量,讓較少工作排在 run queue 中,等待尚未可用的核心。將批次工作移至節點較不繁忙的時段。快取結果,讓更少請求需要使用 CPU。真正能消除 steal 的變更,例如移至其他節點或使用 dedicated core,必須由供應商處理。