SSD Nodes Learn 🎉 VPS ab $4.99/Monat
Anleitungen Matt ConnorVon Matt Connor

CPU-Steal-Time im VPS erkennen und richtig deuten

CPU-Steal-Time zeigt, wann Ihr VPS auf den Hypervisor wartet. Lesen Sie die Spalte st in vmstat und unterscheiden Sie Nachbarn vom eigenen CPU-Overload.

Was die CPU-Steal-Time tatsächlich misst

Die CPU-Steal-Time ist der Anteil der Zeit, in der Ihre virtuelle CPU ausführungsbereit war und auf nichts warten musste, während der Hypervisor den physischen Kern einem anderen Gast zugewiesen hatte. Die Arbeit war in der Warteschlange. Der Kern war anderweitig zugewiesen. Linux zählt diese Zyklen separat und meldet sie als st. So lässt sich erkennen, ob „mein Server ausgelastet ist“ oder „mein Server auf seine Ausführung wartet“.

Genau dafür gibt es diesen Zähler. Die Zeit, die Ihre eigenen Prozesse auf der CPU verbringen, wird als us (Benutzer) oder sy (System) gemeldet. Die Zeit, in der eine Aufgabe wegen des Speichers blockiert ist, wird als wa (I/O-Wait) gemeldet. Eine vCPU (virtuelle CPU), die ausführungsbereit in der Run-Queue wartet, keine ausstehende I/O hat und trotzdem nicht ausgeführt wird, wird als st gemeldet. Nichts innerhalb Ihres Servers kann diesen Zustand beenden, weil die Scheduling-Entscheidung eine Ebene unterhalb Ihres Servers auf dem Host getroffen wird.

Das ergibt sich direkt daraus, wie ein VPS einen physischen Rechner zwischen mehreren Gästen aufteilt. Die übliche Ursache ist ein benachbarter Gast: Ein anderer Gast auf demselben Node ist stark ausgelastet, sodass der Host die Kerne zwischen Ihnen aufteilt. Es gibt eine weitere Ursache, die häufig übersehen wird. Viele Provider begrenzen eine gemeinsam genutzte vCPU auf einen Anteil eines physischen Kerns. Bei mehreren Hypervisoren wird diese erzwungene Begrenzung innerhalb des Gasts als Steal erfasst. Ein hoher Wert für st zeigt daher, dass Ihnen der Kern nicht zugewiesen wurde. Er zeigt jedoch nicht immer, welcher Gast ihn erhalten hat.

Woher der Steal-Wert stammt

Ihr Kernel kann Steal-Zeit nicht selbst messen, weil er den Host nicht sehen kann. Der Hypervisor stellt den Wert bereit. Unter KVM schreibt der Host einen Zähler pro vCPU in eine gemeinsam mit dem Gast genutzte Speicherseite. Der Gast summiert diesen Zähler, wenn der Kernel mit CONFIG_PARAVIRT_TIME_ACCOUNTING gebaut wurde. Das ist bei jedem Distributionskernel der Fall. Xen meldet denselben Wert über seinen Runstate-Bereich. Die Gesamtsumme erreicht den Userspace genau an einer Stelle:

head -1 /proc/stat

Die Zeile cpu enthält zehn Zähler in USER_HZ-Ticks seit dem Bootvorgang, und zwar in dieser Reihenfolge: user, nice, system, idle, iowait, irq, softirq, steal, guest, guest_nice. Steal ist nach der Bezeichnung der achte Wert. Jedes der folgenden Werkzeuge, vmstat, top, mpstat und jeder Prometheus-Exporter, liest dasselbe Feld und berechnet aus zwei Messwerten einen Prozentsatz.

Eine Folge ist besonders wichtig. Wenn der Hypervisor den Zähler nicht exportiert, bleibt das Feld dauerhaft auf null. Jedes darauf basierende Werkzeug meldet dann einen unauffälligen 0.0, obwohl der Host überlastet ist. KVM und Xen exportieren den Wert. Gäste unter VMware und Hyper-V melden dagegen häufig dauerhaft null. Prüfen Sie die Plattform, bevor Sie einem Nullwert vertrauen:

systemd-detect-virt

Der Befehl gibt den Plattformnamen aus, zum Beispiel kvm, xen, vmware oder microsoft, und none auf Bare Metal. In einem Container meldet er stattdessen die Laufzeit, zum Beispiel lxc, docker oder podman. Das sagt etwas über den Container aus, nicht über die darunterliegende Maschine. Unter kvm ist ein Nullwert ein echter Hinweis darauf, dass der Host Sie nicht belastet. Auf einer Plattform, die das Feld nie befüllt, liefert ein Nullwert dagegen keinerlei Information. Die Konkurrenz um CPU-Ressourcen muss dort anhand der Laufzeit echter Arbeit beurteilt werden.

Wie prüfe ich CPU-Steal-Time auf einem VPS?

vmstat stammt aus dem Paket procps. Es ist in fast jedem Ubuntu- und Debian-VPS-Image enthalten, fehlt jedoch in einigen minimalen Container-Images. Installieren Sie es daher, bevor Sie sich darauf verlassen.

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

vmstat --version gibt eine Zeile wie vmstat from procps-ng 4.0.4 aus. Wenn diese Ausgabe erscheint, ist das Tool installiert, und Sie lesen echte Kernel-Zähler. vmstat 1 5 nimmt anschließend fünfmal im Abstand von einer Sekunde eine Stichprobe.

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

Suchen Sie im Block cpu rechts die Spalte st. Aktuelle procps-ng-Builds geben danach für die Zeit von KVM-Gastsystemen eine Spalte gu aus. Deshalb steht st an vorletzter statt an letzter Stelle. Lesen Sie die Spalte anhand ihres Kopfnamens aus, da sich diese Position zwischen Releases geändert hat.

Zwei Gewohnheiten sorgen für eine verlässliche Auswertung. Die erste Datenzeile ist der Durchschnitt seit dem Booten. Ignorieren Sie sie und lesen Sie die folgenden Zeilen. Eine einzelne Stichprobe ist außerdem keine Messung, da Steal-Time schubweise auftritt. Führen Sie vmstat 1 60 aus und beobachten Sie eine vollständige Minute, bevor Sie eine Schlussfolgerung ziehen.

top meldet denselben Wert in seiner Zusammenfassungszeile %Cpu(s), im mit st gekennzeichneten Feld:

%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

Für Details pro CPU ergänzen Sie sysstat:

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

mpstat gibt eine Zeile pro CPU mit einer Spalte %steal aus. Daraus ist ersichtlich, ob alle vCPUs betroffen sind oder nur eine. Für die Historie, die ein Support-Ticket benötigt, speichern Sie die Stichproben, statt sie vom Bildschirm abzulesen:

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

Führen Sie den Befehl während der vermuteten Zeiträume über cron aus. Die Datei ersetzt dann die Aussage gegenüber dem Provider, dass es „gestern Nacht langsam war“, durch einen Nachweis der genauen zehn Minuten.

Was bedeuten die Steal-Werte?

  • Ein konstanter Wert von 0.0. Das System ist gesund, oder die Plattform meldet Steal-Zeit überhaupt nicht. Prüfen Sie dies mit systemd-detect-virt, bevor Sie Entwarnung geben.
  • Spitzen von wenigen Prozent über mehrere Sekunden. Das ist auf jedem gemeinsam genutzten Node normal. Der Build eines Nachbarn startet, oder der Host führt seine Backups aus.
  • Dauerhaft 1 bis 5 Prozent bei einem Shared-Tarif. Das ist zu erwarten. Der Preis berücksichtigt die gemeinsam genutzte CPU.
  • Dauerhaft 5 bis 10 Prozent. Die Verlangsamung ist messbar. Beginnen Sie, Belege zu sammeln, und vergleichen Sie dieselben Uhrzeiten über mehrere Tage.
  • Über 10 Prozent über mehrere Stunden hinweg. Der Node ist für Ihre Auslastung überbucht. Ab diesem Wert ist ein Support-Ticket oder ein Umzug gerechtfertigt.

Betrachten Sie diese Bereiche als Orientierung und nicht als Spezifikation, da kein Anbieter eine Garantie für Steal-Zeit bei einem Shared-Tarif veröffentlicht. Bewerten Sie die Werte im Zusammenhang mit Ihren Workloads. Ein nächtlicher Batch-Job kann 15 Prozent Steal-Zeit verkraften, ohne dass es jemand bemerkt. Ein latenzsensibler Dienst zeigt die Auswirkungen bereits im p99, lange bevor der Durchschnittswert alarmierend aussieht. Deshalb gehören latenzsensible Workloads wie Trading-Bots auf dedizierte Cores.

Wie viel kostet Sie Steal Time?

Die Berechnung ist kurz. Wenn ein Anteil s Ihrer CPU-Zeit entzogen wird, benötigt ein Prozess mit festem CPU-Bedarf auf der Uhr 1 / (1 - s)-mal so lange. Für einen Prozess mit 60 Sekunden CPU-Zeit:

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"
  }
]

Bei 3 Prozent, einem typischen Wert bei Shared-Tarifen, benötigt der Prozess 61.9 Sekunden statt 60.0. Dafür eröffnet niemand ein Ticket. Bei 8 Prozent sind es 65.2 Sekunden. Bei 40 Prozent benötigt derselbe Prozess 100.0 Sekunden, und eine Warteschlange, die zuvor abgebaut wurde, wächst stattdessen weiter.

Das sind berechnete Werte, keine Messwerte. Das Modell geht von einem einzelnen ausführbaren Thread aus und davon, dass Steal Time gleichmäßig über das Intervall verteilt ist. Reale Dienste wirken oft stärker beeinträchtigt als die Kurve vermuten lässt, weil ein entzogenes Zeitfenster mitten in eine Anfrage fällt. Die Verzögerung wird dann von allem erneut bezahlt, was auf diese Anfrage wartet. Um Ihren eigenen Wert statt einer Formel zu erhalten, benchmarken Sie die VPS während einer ruhigen Stunde und erneut während einer ausgelasteten Stunde. Erfassen Sie dabei st für beide Zeitfenster.

Handelt es sich um Steal oder um etwas anderes?

Steal lässt sich leicht mit anderen Symptomen verwechseln. Lesen Sie die Zähler gemeinsam in derselben vmstat-Zeile.

  • st ist hoch, während r und us niedrig bleiben: Der Host stellt Ihnen den CPU-Kern nicht zur Verfügung. Das ist Steal.
  • r liegt deutlich über der Anzahl Ihrer vCPUs, us ist hoch und st liegt nahe null: Sie führen mehr Arbeit aus, als Ihre eigenen CPUs bewältigen können. Vergleichen Sie r mit der Ausgabe von nproc. Das ist Ihre eigene Überbelegung und nicht die eines Nachbarn.
  • wa ist hoch und st liegt nahe null: Aufgaben warten auf den Speicher, also liegt ein anderes Problem mit einer anderen Behebung vor.
  • Der Load Average ist hoch, während st und us beide niedrig sind: Der Load-Wert berücksichtigt auch nicht unterbrechbare Aufgaben. Das weist in der Regel eher auf ein blockiertes Gerät oder einen nicht reagierenden Netzwerk-Mount als auf die CPU hin.

Burstable-Tarife verdienen eine eigene Erläuterung. Sie stellen ein Credit-Guthaben bereit, das sich bei geringer Auslastung aufbaut und bei hoher Auslastung abnimmt. Wenn es aufgebraucht ist, begrenzt der Anbieter Sie auf eine Baseline-Rate. Auf manchen Plattformen wird diese Drosselung als Steal gemeldet. Auf anderen ist sie innerhalb der Instanz nicht sichtbar, und Sie erhalten einfach weniger CPU-Zyklen pro Sekunde. Lesen Sie die Tarifbeschreibung, bevor Sie einen Nachbarn für die Ursache halten.

Warum ein Container keine Steal-Zeit meldet

Steal ist eine Eigenschaft der virtuellen Maschine, nicht eines darin ausgeführten Containers. Ein Docker-Container auf Ihrem eigenen VPS verwendet den /proc des Hosts. Ein darin gelesener Wert für st entspricht daher der Steal-Zeit des VPS. Das ist der gewünschte Wert. Eine als VPS angebotene containerbasierte Virtualisierung verhält sich anders. Wenn lxcfs verwendet wird, wird /proc/stat innerhalb des Containers aus der cgroup-Abrechnung erzeugt. Die Steal-Zeit ist dadurch konstruktionsbedingt null. Ein Monitoring-Stack, der nur innerhalb des Containers Daten erfasst, kann eine konstante, unauffällige Null anzeigen, während die darunterliegende physische Maschine überlastet ist.

Innerhalb eines Containers ist CPU-Quota-Throttling der Zähler mit derselben Bedeutung. Unter cgroup v2:

cat /sys/fs/cgroup/cpu.stat

nr_throttled zählt die Durchsetzungsintervalle, in denen die Gruppe ihr CPU-Limit erreicht hat. throttled_usec summiert die Zeit, in der sie eingefroren war. Ein steigender Wert für nr_throttled bedeutet, dass Ihr Prozess ausführbar war, aber nicht ausgeführt wurde. Das entspricht der Erfahrung mit Steal, wird jedoch durch ein von Ihnen selbst gesetztes Limit verursacht. Prüfen Sie Ihre eigenen Limits, bevor Sie den Host verantwortlich machen. Das gilt besonders, wenn Sie Ihre Dienste in Docker auf einem VPS ausführen und die CPU-Limits in der Compose-Datei festgelegt sind. Verschachtelte Virtualisierung fügt eine weitere Stelle hinzu, an der Zeit verloren gehen kann. Eine VM innerhalb Ihres VPS unterliegt sowohl dessen Steal-Zeit als auch ihrer eigenen Verzögerung bei der CPU-Zuteilung. Berücksichtigen Sie das, wenn Sie verschachtelte Virtualisierung auf einem VPS ausführen.

Was Sie gegen anhaltenden Steal tun können

Keine Einstellung innerhalb des Gasts behebt Steal, weil der Scheduler, der diese Entscheidung trifft, außerhalb des Gasts läuft. Es gibt vier sinnvolle Maßnahmen.

Sammeln Sie zuerst Belege. Erfassen Sie die Zeitstempel in UTC, die Dauer jeder Episode, ihre Wiederholungshäufigkeit und ob mpstat eine vCPU oder alle vCPUs als betroffen ausweist. Eine Woche protokollierter Messwerte ist aussagekräftiger als ein Screenshot.

Eröffnen Sie mit diesen Daten ein Ticket. Stellen Sie zwei direkte Fragen: Ist dieser Node in diesen Zeitfenstern überbucht, und kann meine Instanz verschoben werden? Fügen Sie die Ausgabe von vmstat und die genauen Zeitpunkte ein. Provider können mit einem reproduzierbaren Zeitfenster arbeiten. Auf ein Ticket, in dem nur steht, dass der Server langsam ist, fragen sie nach genau diesen Angaben. Wie viel dieser Arbeit Sie abgeben können, ist einer der praktischen Unterschiede zwischen einem verwalteten und einem nicht verwalteten VPS.

Bitten Sie um eine Migration. Das Verschieben eines Gasts auf einen weniger ausgelasteten Node gehört für einen Provider zum Routinebetrieb und erfordert normalerweise nur einen kurzen Reboot. Diese Lösung kostet nichts. Sie behebt den häufigen Fall, dass sich zufällig mehrere stark ausgelastete Nachbarn auf einem Node befinden.

Beseitigen Sie die Konkurrenz durch ein Upgrade. Ein Tarif mit dedizierter vCPU reserviert physische Kerne für Ihre Instanz. Dadurch bleibt der Zähler bei null. Das kostet monatlich mehr. Für eine Arbeitslast, die diese Schwankungen nicht tolerieren kann, ist dies die sachgerechte Lösung. Reicht das weiterhin nicht aus oder benötigen Sie zusätzlich die Speicherbandbreite exklusiv, ist der nächste Schritt ein dedizierter Server statt eines VPS.

Während Sie auf eine dieser Maßnahmen warten, können Sie die Auswirkungen von Steal begrenzen. Verwenden Sie weniger Worker-Threads als vCPUs vorhanden sind. Threads, die keinen Kern erhalten, verursachen sonst lediglich zusätzliche Kontextwechsel. Verschieben Sie Batch-Arbeiten in die Stunden, in denen der Node ruhig ist. Das zeigt Ihnen jetzt Ihr eigenes Log. Messen Sie anschließend mit demselben Befehl über dieselben Stunden erneut. So können Sie feststellen, ob die Änderung geholfen hat, statt zu raten.

FAQ

Wie hoch ist eine normale CPU-Steal-Time auf einem VPS?

Bei einem Shared-Tarif sind kurze Spitzen und ein dauerhaft unter etwa 5 Prozent liegender Wert normal, weil sich bei gemeinsam genutzten CPUs mehrere Gäste die physischen Kerne des Hosts teilen. Dauerhafte zweistellige Werte über mehrere Stunden sind nicht normal und sollten per Support-Ticket gemeldet werden. Bei einem Tarif mit dedizierter vCPU sollte der erwartete Wert 0.0 sein. Jeder andere Wert ist dort ein Fehler und sollte gemeldet werden. Bewerten Sie den Wert im Verhältnis zu Ihrer eigenen Arbeitslast: Ein nächtlicher Batch-Auftrag kann Steal-Time verkraften, eine latenzempfindliche API jedoch nicht.

Behebt ein größerer Tarif eine hohe Steal-Time?

Nicht von selbst. Mehr vCPUs auf demselben gemeinsam genutzten Node bedeuten, dass mehr virtuelle CPUs um dieselben ausgelasteten physischen Kerne konkurrieren. Der Prozentsatz kann daher unverändert bleiben. Steal-Time lässt sich durch eine dedizierte CPU-Zuweisung oder durch den Umzug auf einen weniger ausgelasteten Node beseitigen. Ein größerer Anteil an einer ausgelasteten Maschine bleibt ein Anteil an einer ausgelasteten Maschine.

Warum zeigt mein VPS 0 Steal-Time an, obwohl er offensichtlich langsam ist?

Dafür gibt es zwei häufige Gründe. Der Hypervisor exportiert den Zähler möglicherweise überhaupt nicht. Das ist auf VMware- und Hyper-V-Plattformen üblich. Das Feld bleibt dann unabhängig von der Auslastung des Hosts auf null. Führen Sie systemd-detect-virt aus, um die verwendete Plattform zu ermitteln. Andernfalls liegt der Engpass an anderer Stelle: Prüfen Sie wa auf Wartezeiten beim Speicherzugriff, vergleichen Sie r mit nproc auf eine Überlastung durch Ihre eigene Arbeitslast und prüfen Sie innerhalb von Containern /sys/fs/cgroup/cpu.stat auf eine Drosselung durch Quotas.

Kann ich die Steal-Time innerhalb meines Servers reduzieren?

Sie können die Scheduling-Entscheidungen des Hosts nicht innerhalb des Gasts ändern. Sie können nur die Auswirkungen reduzieren. Verwenden Sie weniger Worker-Threads, als vCPUs vorhanden sind. Dadurch warten weniger Aufgaben in der Run Queue auf einen verfügbaren Kern. Verschieben Sie Batch-Aufträge auf Zeiten, in denen der Node weniger ausgelastet ist. Cachen Sie Ergebnisse, damit weniger Anfragen überhaupt CPU-Zeit benötigen. Die Maßnahmen, die Steal-Time tatsächlich beseitigen, liegen auf der Seite des Providers: die Migration auf einen anderen Node oder die Zuweisung dedizierter Kerne.