CPU steal time su VPS: come riconoscere un vicino rumoroso
Scopri cosa indica davvero la colonna st di vmstat e come distinguere un vicino rumoroso dal sovraccarico della tua VPS, senza confondere attesa CPU e I/O.
Che cosa misura realmente lo steal time della CPU
Lo steal time della CPU è la quota di tempo in cui la CPU virtuale era pronta per l'esecuzione, senza dover attendere nulla, mentre l'hypervisor assegnava il core fisico a un altro guest. Il lavoro era accodato. Il core era assegnato altrove. Linux conta separatamente questi cicli e li riporta come st. Questo permette di distinguere tra «il server è occupato» e «il server sta aspettando il proprio turno».
Questa differenza è il motivo per cui esiste questo contatore. Il tempo che i processi utilizzano direttamente sulla CPU viene riportato come us (user) o sy (system). Il tempo durante il quale un task resta bloccato in attesa dello storage viene riportato come wa (I/O wait). Una vCPU (CPU virtuale) eseguibile, presente nella run queue, senza operazioni di I/O in sospeso e ancora non in esecuzione, viene riportata come st. Nulla all'interno del server può eliminare questo stato, perché la decisione di scheduling viene presa un livello più in basso, sull'host.
Questo deriva direttamente da come una VPS condivide una macchina fisica tra più guest. La causa abituale è un vicino: un altro guest sullo stesso nodo sta utilizzando intensamente la CPU, quindi l'host suddivide i core tra i vari guest. Esiste anche una seconda causa che viene spesso trascurata. Molti provider limitano una vCPU condivisa a una frazione di un core fisico e, con diversi hypervisor, questo limite viene contabilizzato come steal all'interno del guest. Un valore elevato di st indica quindi che il core non era stato assegnato al server. Non indica sempre chi lo stava utilizzando.
Da dove proviene il valore di steal
Il kernel non può misurare autonomamente lo steal, perché non può vedere l'host. È l'hypervisor a comunicarglielo. In KVM, l'host scrive un contatore per vCPU in una pagina condivisa con il guest, e il guest lo somma quando il kernel è compilato con CONFIG_PARAVIRT_TIME_ACCOUNTING, come avviene per tutti i kernel delle distribuzioni. Xen comunica lo stesso valore tramite la propria area runstate. Il totale arriva allo userspace in un solo punto:
head -1 /proc/statQuella riga cpu contiene dieci contatori, espressi in tick USER_HZ dall'avvio, nel seguente ordine: user, nice, system, idle, iowait, irq, softirq, steal, guest, guest_nice. Steal è l'ottavo valore dopo l'etichetta. Tutti gli strumenti riportati di seguito, vmstat, top, mpstat e qualsiasi exporter Prometheus, leggono lo stesso campo e trasformano due campioni in una percentuale.
Una conseguenza è più importante delle altre. Se l'hypervisor non esporta il contatore, il campo resta sempre a zero e tutti gli strumenti che lo utilizzano riportano uno 0.0 tranquillo mentre l'host è sovraccarico. KVM e Xen lo esportano. I guest su VMware e Hyper-V riportano comunemente un valore costante pari a zero. Verifica la piattaforma prima di interpretare uno zero:
systemd-detect-virtStampa il nome della piattaforma, ad esempio kvm, xen, vmware o microsoft, e none su bare metal. All'interno di un container riporta invece il runtime, ad esempio lxc, docker o podman, fornendo informazioni sul container ma non sulla macchina sottostante. Su kvm, uno zero è una prova concreta che l'host sta gestendo correttamente il carico assegnato. Su una piattaforma che non valorizza mai il campo, uno zero non fornisce alcuna informazione e la contesa deve essere valutata misurando i tempi di esecuzione di attività reali.
Come verificare il tempo CPU rubato su un VPS?
vmstat proviene dal pacchetto procps. È presente in quasi tutte le immagini VPS Ubuntu e Debian, ma può mancare in alcune immagini container minimali. Installalo prima di farci affidamento.
sudo apt-get update
sudo apt-get install -y procps
vmstat --version
vmstat 1 5vmstat --version stampa una riga simile a vmstat from procps-ng 4.0.4. Se la riga viene visualizzata, lo strumento è installato e stai leggendo contatori reali del kernel. vmstat 1 5 acquisisce quindi un campione al secondo, per cinque volte.
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 0Nel blocco cpu a destra, individua la colonna st. Le build correnti di procps-ng stampano dopo questa colonna anche una colonna gu per il tempo del guest KVM. Di conseguenza, st è la seconda colonna da destra, non l'ultima. Leggi la colonna dal nome dell'intestazione, perché questa posizione è cambiata tra le diverse release.
Due accorgimenti rendono affidabile la lettura. La prima riga di dati è la media dall'avvio, quindi ignorala e leggi le righe successive. Inoltre, un solo campione non costituisce una misurazione, perché il tempo rubato arriva a raffiche: esegui vmstat 1 60 e monitora un minuto intero prima di trarre conclusioni.
top riporta lo stesso valore nella relativa riga riepilogativa %Cpu(s), nel campo contrassegnato da 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 stPer i dettagli relativi a ciascun core, aggiungi sysstat:
sudo apt-get install -y sysstat
mpstat -P ALL 1 5mpstat stampa una riga per ogni CPU, con una colonna %steal che mostra se il problema interessa ogni vCPU o soltanto una. Per conservare lo storico necessario a un ticket di supporto, salva i campioni invece di leggerli direttamente dallo schermo:
date -u | tee -a ~/steal.log
mpstat -P ALL 1 5 | tee -a ~/steal.logEsegui il comando da cron nelle ore in cui sospetti il problema. Il file ti permetterà di mostrare al provider i dieci minuti esatti, invece di limitarti a dire che "ieri sera il server sembrava lento".
Che cosa significano i valori di steal?
- Un valore stabile di
0.0. È un dato nella norma oppure la piattaforma non restituisce affatto il valore di steal. Prima di trarre conclusioni, verifica consystemd-detect-virt. - Picchi di pochi punti percentuali della durata di alcuni secondi. Sono normali su qualsiasi nodo condiviso. Può avviarsi una compilazione sul sistema vicino oppure l'host può eseguire i backup.
- Dall'1 al 5 percento in modo costante su un piano condiviso. È un valore previsto. Il prezzo riflette l'uso di CPU condivisa.
- Dal 5 al 10 percento in modo costante. Indica un rallentamento misurabile. Inizia a raccogliere dati e confronta le stesse ore per diversi giorni.
- Oltre il 10 percento per diverse ore consecutive. Il nodo è sovraccarico rispetto al tuo carico di lavoro. Questo livello giustifica l'apertura di un ticket di supporto o il trasferimento a un altro nodo.
Considera questi intervalli come una guida interpretativa, non come una specifica, perché nessun provider garantisce un valore di steal per i piani condivisi. Valutali in base ai carichi che esegui. Un job batch notturno può assorbire un valore di steal del 15 percento senza che nessuno lo noti. Un servizio sensibile alla latenza lo mostra nel p99 molto prima che la media diventi preoccupante. Per questo i carichi di lavoro sensibili alla latenza, come i bot di trading devono essere eseguiti su core dedicati.
Quanto ti costa lo steal time?
Il calcolo è breve. Se una frazione s del tempo CPU viene sottratta, un job che richiede una quantità fissa di CPU impiega 1 / (1 - s) volte più tempo reale. Per un job che richiede 60 secondi di 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"
}
]Con 3 percento, un valore ordinario per un piano condiviso, il job impiega 61.9 secondi invece di 60.0. Questo non porta nessuno ad aprire un ticket. Con 8 percento servono 65.2 secondi. Con 40 percento lo stesso job richiede 100.0 secondi e una coda che prima si svuotava inizia invece a crescere.
Sono valori calcolati, non misurazioni. Il modello presuppone un singolo thread eseguibile e uno steal distribuito uniformemente nell'intervallo. I servizi reali spesso risentono di un impatto maggiore rispetto a quello indicato dalla curva, perché uno slice sottratto può interrompere una richiesta e il ritardo viene quindi subito di nuovo da tutto ciò che è in attesa di quella richiesta. Per ottenere un valore riferito al tuo caso anziché una formula, esegui un benchmark sulla VPS durante un'ora di bassa attività e ripetilo durante un'ora di intenso traffico, registrando st per entrambe le finestre.
È steal o si tratta di qualcos’altro?
Steal può essere facilmente confuso con altri sintomi. Leggi i contatori insieme, sulla stessa riga di vmstat.
stalto mentrereusrestano bassi: l’host non ti sta assegnando il core. Questo è steal.rmolto superiore al numero di vCPU, conusalto estvicino a zero: stai eseguendo più lavoro di quanto le tue CPU possano gestire. Confrontarcon l’output dinproc. Questa è una sovrascrizione delle tue risorse, non un problema causato da un vicino.waalto constvicino a zero: i task sono bloccati sullo storage. È un problema diverso, che richiede una correzione diversa.- Load average alto mentre
steussono entrambi bassi: il valore del carico include anche i task non interrompibili. Questo indica in genere un dispositivo bloccato o un mount di rete non responsivo, non un problema della CPU.
I piani burstable richiedono una nota specifica. Forniscono un saldo di crediti che aumenta quando il carico è inattivo e diminuisce quando il carico è elevato. Quando i crediti terminano, il provider limita l’istanza a una velocità di base. Su alcune piattaforme questa limitazione viene riportata come steal. Su altre non è visibile dall’interno dell’istanza e si ottengono semplicemente meno cicli al secondo. Leggi la descrizione del piano prima di attribuire il problema a un vicino.
Perché un container non mostra steal time
Lo steal è una proprietà della macchina virtuale, non di un container eseguito al suo interno. Un container Docker sul proprio VPS condivide il /proc dell'host, quindi un valore st letto al suo interno corrisponde allo steal del VPS, che è il dato necessario. La virtualizzazione basata su container venduta come VPS si comporta diversamente. Quando è presente lxcfs, il valore di /proc/stat all'interno del container viene calcolato a partire dai dati contabili del cgroup e lo steal è zero per costruzione. Uno stack di monitoraggio che raccoglie i dati soltanto dall'interno può mostrare uno zero costante e apparentemente normale, mentre la macchina fisica sottostante è priva di risorse.
All'interno di un container, il contatore con lo stesso significato operativo è il throttling imposto dalla quota CPU. Con cgroup v2:
cat /sys/fs/cgroup/cpu.statnr_throttled conta i periodi di applicazione della quota in cui il gruppo ha raggiunto il limite CPU, mentre throttled_usec somma il tempo durante il quale è rimasto sospeso. Un valore nr_throttled in aumento indica che il processo era eseguibile ma non era in esecuzione: l'esperienza è la stessa dello steal, ma la causa è un limite configurato dall'utente. Controllare i propri limiti prima di attribuire il problema all'host, soprattutto se si eseguono i servizi in Docker su un VPS con limiti CPU definiti nel file compose. La virtualizzazione a più livelli aggiunge un ulteriore punto in cui il tempo può andare perso, perché una VM eseguita all'interno del VPS subisce lo steal del VPS oltre al proprio ritardo di scheduling. Tenerne conto se si usa la virtualizzazione annidata su un VPS.
Cosa fare in caso di steal persistente
Nessuna impostazione all'interno del guest risolve lo steal, perché la decisione viene presa dallo scheduler che opera al di fuori del guest. Anche l'aggiornamento del kernel non cambia la situazione: il meccanismo di scheduling consapevole della cache aggiunto nel kernel Linux 7.2 ridistribuisce i task tra i core che ti sono stati effettivamente assegnati e non può recuperare i cicli già utilizzati da un vicino. Le opzioni concrete sono quattro.
Raccogli prima le evidenze. Registra i timestamp in UTC, la durata di ogni episodio, la frequenza con cui si ripete e se mpstat mostra un solo vCPU interessato oppure tutti. Una settimana di campioni registrati vale più di uno screenshot.
Apri un ticket con questi dati. Poni due domande dirette: il nodo è sovrallocato durante queste finestre temporali? È possibile spostare la mia istanza? Incolla l'output di vmstat e gli orari esatti. I provider intervengono quando il problema si verifica in una finestra riproducibile; un ticket che si limita a segnalare che il server è lento riceverà una richiesta di dettagli. La quantità di questo lavoro che puoi delegare è una delle differenze pratiche tra un VPS gestito e uno non gestito.
Chiedi una migrazione. Spostare un guest su un nodo meno carico è un'operazione ordinaria per un provider e di solito richiede un breve riavvio. È la soluzione che non comporta costi e risolve il caso comune, in cui un nodo ospita temporaneamente diversi vicini con carichi elevati.
Acquista un piano senza contesa. Un piano con vCPU dedicati riserva core fisici alla tua istanza, quindi il contatore resta a zero. Il costo mensile è maggiore, ma questa è la scelta corretta per un carico che non può tollerare variazioni nelle prestazioni. Se non è ancora sufficiente, oppure vuoi riservare anche la memoria, il passaggio successivo è un server dedicato invece di un VPS.
Nel frattempo, riduci l'impatto dello steal. Esegui meno thread worker rispetto al numero di vCPU disponibili, perché i thread che non riescono a ottenere un core aggiungono soltanto context switch. Sposta i job batch nelle ore in cui il nodo è meno carico, come indicato dal log che hai raccolto. Quindi esegui nuovamente la misurazione con lo stesso comando e nelle stesse ore, così puoi verificare se la modifica ha funzionato invece di procedere per supposizioni.
FAQ
Qual è un valore normale di CPU steal time su un VPS?
Su un piano condiviso, brevi picchi e un valore sostenuto inferiore a circa 5 percento sono normali, perché la CPU condivisa significa che l'host distribuisce i core fisici tra le macchine guest. Un valore a due cifre mantenuto per ore non è normale e giustifica l'apertura di un ticket. Su un piano con vCPU dedicata, il valore atteso è 0.0; qualsiasi altro valore indica un problema da segnalare. Valuta il numero in relazione al tuo carico di lavoro: un job batch notturno può tollerare uno steal time che invece è inaccettabile per un'API sensibile alla latenza.
Un piano più grande risolve lo steal time elevato?
Non da solo. Aggiungere vCPU sullo stesso nodo condiviso significa avere più CPU virtuali in competizione per gli stessi core fisici congestionati, quindi la percentuale può rimanere esattamente quella di prima. Per eliminare lo steal time servono un'allocazione CPU dedicata o lo spostamento su un nodo meno carico. Una quota maggiore di una macchina sovraccarica resta comunque una quota di una macchina sovraccarica.
Perché il mio VPS mostra 0 steal time anche se è chiaramente lento?
Le cause comuni sono due. L'hypervisor potrebbe non esportare affatto il contatore, cosa usuale sulle piattaforme VMware e Hyper-V; in questo caso il campo resta a zero indipendentemente da ciò che accade sull'host. Esegui systemd-detect-virt per verificare quale piattaforma stai utilizzando. In caso contrario, il collo di bottiglia è altrove: controlla wa per le attese di storage, confronta r con nproc per verificare un sovraccarico causato dal tuo carico e leggi /sys/fs/cgroup/cpu.stat all'interno dei container per rilevare il throttling imposto dalle quote.
Posso ridurre lo steal time dall'interno del server?
Non puoi modificare la pianificazione dell'host dall'interno della macchina guest. Puoi soltanto ridurre l'impatto del problema. Esegui meno thread worker rispetto al numero di vCPU disponibili, così meno attività resta nella run queue in attesa di un core che non si libera. Sposta i job batch nelle ore in cui il nodo è meno carico. Memorizza nella cache i risultati, così un numero inferiore di richieste richiede effettivamente tempo CPU. Le modifiche che eliminano davvero lo steal time, cioè la migrazione su un altro nodo o l'assegnazione di core dedicati, dipendono dal provider.