SSD Nodes Learn 🎉 VPS $4.99/月〜
ガイド Matt Connor著者 Matt Connor ・更新日 2026-08-08

VPSのCPU steal timeとnoisy neighbourの見分け方

VPSのCPU steal timeは、実行可能だったのに他のゲストへコアを奪われた時間です。vmstatのst列を読み、自身の過負荷かnoisy neighbourかを切り分けます。

CPU steal time が実際に測定するもの

CPU steal time は、仮想 CPU が実行可能な状態で待機するものがないにもかかわらず、ハイパーバイザーが物理コアを別のゲストに割り当てていた時間の割合です。処理はキューに入っていました。コアは別の場所で使用されていました。Linux はこのサイクルを別に数え、st として報告します。これにより、「サーバーがビジーである」のか、「実行順を待っている」のかを区別できます。

この違いが、このカウンターが存在する理由です。プロセス自身が CPU 上で消費した時間は、us(user)または sy(system)として報告されます。タスクがストレージ上でブロックされている時間は、wa(I/O wait)として報告されます。I/O 処理が保留されておらず、実行キューに入って実行可能な状態にあるにもかかわらず、まだ実行されていない vCPU(virtual CPU)は、st として報告されます。ホスト側でスケジューリングが決定されるため、サーバー内部の処理でこの状態を解消することはできません。

これは、VPS が 1 台の物理マシンを複数のゲストで共有する仕組みから直接導かれます。通常の原因は、同じノード上の別のゲストです。そのゲストの負荷が高いため、ホストがコアを複数のゲストに分配します。見落とされやすい別の原因もあります。多くのプロバイダーは、共有 vCPU に物理コアの一部に相当する上限を設定しています。また、複数のハイパーバイザーでは、その上限による制限がゲスト内で steal として計上されます。したがって、st の値が高い場合、コアが自分に割り当てられなかったことは分かります。ただし、誰がコアを使用したのかまでは、必ずしも分かりません。

steal 値の取得元

カーネルはホストを認識できないため、steal を単独で測定できません。ハイパーバイザーが値を通知します。KVM では、ホストがゲストと共有するページに vCPU ごとのカウンターを書き込みます。ゲストは、カーネルが CONFIG_PARAVIRT_TIME_ACCOUNTING でビルドされている場合に、その値を合計します。これはすべてのディストリビューションカーネルに含まれています。Xen も runstate 領域を通じて同じ値を報告します。合計値が userspace に渡される場所は、次の 1 か所だけです。

head -1 /proc/stat

この cpu 行には、ブート以降の USER_HZ ティック単位のカウンターが 10 個、次の順序で含まれます。user、nice、system、idle、iowait、irq、softirq、steal、guest、guest_nice です。steal はラベルの後にある 8 番目の値です。以下の各ツール、vmstattopmpstat、および Prometheus exporter は、すべて同じフィールドを読み取り、2 つのサンプルから割合を計算します。

最も重要な点は、ハイパーバイザーがこのカウンターをエクスポートしない場合、フィールドが永続的に 0 のままになることです。その場合、この値を使うすべてのツールは、ホストが過負荷でも穏やかな 0.0 を報告します。KVM と Xen はこの値をエクスポートします。VMware と Hyper-V のゲストでは、通常は 0 のままです。0 を信頼する前に、プラットフォームを確認してください。

systemd-detect-virt

このコマンドは、kvmxenvmwaremicrosoft などのプラットフォーム名を表示します。ベアメタルでは none と表示されます。コンテナ内では、lxcdockerpodman などのランタイムが表示されます。これはコンテナについての情報であり、その下にあるマシンについての情報ではありません。kvm では、0 はホストが適切にリソースを割り当てていることを示す実際の証拠です。フィールドに値を設定しないプラットフォームでは、0 には何の証拠もありません。その場合は、実際の処理にかかる時間を測定して競合を判断する必要があります。

VPS で CPU steal time を確認する方法

vmstatprocps パッケージに含まれています。ほとんどすべての 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 は、その後 1 秒間隔で 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 ビルドでは、その後ろに KVM ゲスト時間用の gu 列が表示されるため、st は右端ではなく右から 2 番目です。リリースによってこの位置が変わっているため、列の位置ではなくヘッダー名で読み取ってください。

読み取りを正確にするには、2 つの点に注意します。最初のデータ行は起動後の平均値なので無視し、その後の行を読みます。また、steal はバースト状に発生するため、1 回のサンプルでは測定になりません。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 ごとに 1 行を出力し、%steal 列を表示します。この列により、すべての vCPU が影響を受けているのか、それとも 1 つだけが影響を受けているのかを確認できます。サポートチケットに必要な履歴を残すには、画面から読み取るのではなく、サンプルを保存します。

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

疑わしい時間帯に cron からこれを実行してください。そうすれば、そのファイルによって、プロバイダーに「昨夜は遅く感じた」と伝えるだけでなく、正確な 10 分間の記録を提示できます。

steal の値は何を意味しますか?

  • 安定した 0.0 健全な状態です。または、プラットフォームが steal をまったく報告していません。判断する前に systemd-detect-virt で確認してください。
  • 数秒続く数パーセントの急上昇。 共有ノードでは正常です。隣の利用者がビルドを開始したか、ホストがバックアップを実行しています。
  • 共有プランで 1〜5 パーセントが継続。 想定内です。料金には共有 CPU の利用が反映されています。
  • 5〜10 パーセントが継続。 測定可能な速度低下です。証拠の記録を開始し、数日間にわたって同じ時間帯を比較してください。
  • 10 パーセントを超える状態が一度に数時間続く。 そのワークロードに対してノードのリソースが過剰に共有されています。この水準なら、サポートへの問い合わせや移行を検討する根拠になります。

これらの範囲は仕様ではなく、読み取りの目安として扱ってください。共有プランでは、steal の保証を公開しているプロバイダーがないためです。実行している処理に照らして判断してください。夜間のバッチ処理なら、steal が 15 パーセントあっても影響に気付かないことがあります。レイテンシーに敏感なサービスでは、平均値が問題に見える前に p99 に影響が現れます。そのため、トレーディングボットなどのレイテンシーに敏感なワークロードは専用コア上で運用してください。

steal time によるコスト

計算は簡単です。CPU 時間の s が奪われると、一定量の CPU を必要とするジョブは、実時間で 1 / (1 - s) 倍かかります。CPU 時間を 60 秒必要とするジョブでは、次のようになります。

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 パーセントという、一般的な共有プランで見られる値では、そのジョブの所要時間は 61.9 秒です。60.0 秒ではありません。この程度でチケットを起票する人はいません。8 パーセントになると、所要時間は 65.2 秒です。40 パーセントでは、同じジョブに 100.0 秒かかり、以前は処理できていたキューが増え始めます。

これは測定値ではなく、計算値です。このモデルでは、実行可能なスレッドが 1 つだけあり、期間全体で steal が均等に発生すると仮定しています。実際のサービスでは、曲線以上に遅く感じることがよくあります。steal された時間がリクエストの処理途中に発生すると、その遅延を、そのリクエストの完了を待つすべての処理が受けるためです。計算式ではなく実際の値を得るには、静かな時間帯と負荷の高い時間帯に VPS のベンチマークを実行し、両方の時間帯で st を記録してください。

これは steal ですか、それとも別の問題ですか?

steal は、ほかの症状と混同しやすい項目です。同じ vmstat 行にあるカウンターをまとめて確認してください。

  • st が高く、rus が低いままの場合、ホストが CPU コアを割り当てていません。これは steal です。
  • r が vCPU 数を大きく上回り、us が高く、st がほぼ 0 の場合、自分の CPU で処理できる量を超えるワークロードを実行しています。rnproc の出力を比較してください。これは隣接するテナントではなく、自分自身のオーバーサブスクリプションです。
  • wa が高く、st がほぼ 0 の場合、タスクがストレージ待ちでブロックされています。これは別の問題であり、対処方法も異なります。
  • ロードアベレージが高い一方で stus がともに低い場合、ロード値には割り込み不能なタスクも含まれます。そのため通常は、CPU ではなく、停止したデバイスや応答しないネットワークマウントが原因です。

バースト可能なプランについては、別途確認が必要です。アイドル中にクレジット残高が増え、負荷が高いときに減少します。残高がなくなると、プロバイダーはベースラインの速度に制限します。このスロットリングが steal として報告されるプラットフォームもあります。内部からは確認できず、単純に 1 秒あたりの CPU サイクル数が少なくなるプラットフォームもあります。隣接するテナントが原因だと判断する前に、プランの説明を確認してください。

コンテナで steal time が報告されない理由

steal は仮想マシンの特性であり、その内部で実行されるコンテナの特性ではありません。自身の VPS 上の Docker コンテナはホストの /proc を共有するため、コンテナ内で読み取った st の値は VPS の steal です。これは必要な値です。VPS として提供されるコンテナベースの仮想化では、動作が異なります。lxcfs が設定されている場合、コンテナ内の /proc/stat は cgroup のアカウンティングから合成されるため、steal は構造上 0 になります。コンテナ内部だけをスクレイピングする監視基盤では、物理マシンがリソース不足に陥っていても、変化のない 0 として表示されることがあります。

コンテナ内で同じ意味を持つカウンターは、CPU クォータによるスロットリングです。cgroup v2 では、次のように確認します。

cat /sys/fs/cgroup/cpu.stat

nr_throttled は、グループが CPU クォータに達した強制適用期間の回数を示します。throttled_usec は、実行が停止していた時間の合計です。nr_throttled が増加している場合、プロセスは実行可能な状態でしたが実行されていませんでした。これは steal と同じ状態ですが、自分で設定した制限が原因です。ホストを疑う前に、自身の制限を確認してください。特に compose ファイルで CPU 制限を指定して VPS 上の Docker でサービスを実行している場合は重要です。階層化された仮想化では、時間が失われる場所がさらに増えます。VPS 内の VM は、VPS 自体の steal に加えて、独自のスケジューリング遅延も受けるためです。VPS 上でネストされた仮想化を実行している場合は、この点を考慮してください。

継続的な steal への対処

ゲスト内の設定では steal を解消できません。判断を行う scheduler はゲストの外部で動作しているためです。実際に取れる対策は4つです。

まず証拠を収集します。 UTC で timestamp を記録し、各発生時間の長さ、発生頻度、mpstat で影響を受けている vCPU が1つだけか、すべてかを確認します。1週間分の記録済みサンプルは、スクリーンショットより有用です。

そのデータを添えて ticket を作成します。 次の2点を直接確認してください。これらの時間帯に node の oversubscription が発生しているか。自分の instance を移動できるか。vmstat の出力と正確な時刻を貼り付けます。provider は再現可能な時間帯に基づいて対応します。「server が遅い」とだけ伝える ticket には、通常、その時間帯を求める返信が来ます。こうした作業をどこまで任せられるかは、managed VPS と unmanaged VPS の違いの実務的なポイントの1つです。

migration を依頼します。 ゲストを負荷の低い node へ移動することは provider にとって通常の作業で、通常は短時間の reboot で完了します。費用のかからない対策であり、1つの node に複数の負荷の高い neighbor が同時に配置されているという、よくあるケースを解消できます。

contention を避けるためにプランを変更します。 dedicated vCPU plan では、物理 core が instance 用に予約されるため、counter は0になり、その状態が維持されます。月額費用は高くなりますが、変動を許容できない workload には適切な選択です。それでも不十分な場合、または memory bandwidth も専有したい場合は、次の選択肢として VPS ではなく dedicated serverを検討します。

これらの対策を待つ間も、steal による影響を減らしてください。vCPU 数より少ない worker thread を実行します。core を取得できない thread は context switch を増やすだけだからです。batch work は node が静かな時間帯に移します。現在は自分の log から、その時間帯を判断できます。その後、同じ command を同じ時間帯に実行して再度測定します。推測ではなく、変更の効果を確認できます。

FAQ

VPS で正常な CPU steal time はどの程度ですか?

共有プランでは、短時間の急上昇や、約 5 パーセント未満で推移する値は通常の範囲です。共有 CPU では、ホストが物理コアをゲスト間で分配するためです。数時間にわたって 2 桁の値が続く場合は通常ではないため、問い合わせる価値があります。専用 vCPU プランで期待される値は 0.0 です。そのため、それ以外の値であれば報告すべき障害です。数値は自身のワークロードと照らして判断してください。夜間バッチジョブなら許容できる steal time でも、遅延に敏感な API では許容できない場合があります。

大きいプランに変更すれば、高い steal time は解消しますか?

それだけでは解消しません。同じ共有ノード上で vCPU を増やしても、競合している同じ物理コアをより多くの仮想 CPU が奪い合うため、割合はまったく変わらないことがあります。steal time をなくすには、専用 CPU の割り当てを受けるか、負荷の低いノードへ移行する必要があります。負荷の高いマシンで割り当てが増えても、負荷の高いマシンの共有であることに変わりはありません。

明らかに遅いのに、VPS の steal time が 0 になるのはなぜですか?

主な理由は 2 つあります。ハイパーバイザーがカウンター自体を提供していない可能性があります。VMware と Hyper-V のプラットフォームでは一般的であり、ホストの状態に関係なくフィールドが 0 のままになります。systemd-detect-virt を実行して、使用しているプラットフォームを確認してください。それ以外の場合は、ボトルネックが別の場所にあります。ストレージ待ちについては wa を確認し、自身の過負荷については rnproc を比較してください。コンテナ内の quota throttling については /sys/fs/cgroup/cpu.stat を確認します。

サーバー内から steal time を減らせますか?

ゲスト内からホストのスケジューリングを変更することはできません。影響を小さくすることだけが可能です。vCPU 数より少ない worker thread 数で実行してください。そうすれば、割り当てられないコアを待つ処理が run queue に滞留しにくくなります。バッチジョブは、ノードの負荷が低い時間帯に移動してください。結果をキャッシュすれば、CPU を必要とするリクエスト自体を減らせます。steal time を実際に解消できる変更、つまり別のノードへの移行や専用コアの割り当ては、プロバイダー側で行う必要があります。