...

Interpretare correttamente il load average: malintesi nell'hosting

Media di carico indica quanti processi sono attualmente in esecuzione o in attesa di tempo CPU, non la percentuale di utilizzo della CPU. Chi legge il valore senza contesto spesso reagisce con panico o aggiornamenti errati; spiego come classificarlo correttamente e come ricavarne decisioni di hosting sensate.

Punti centrali

  • Nessuna CPU%: Load conta i processi nella coda di esecuzione.
  • Per nucleo pensare: dividere il carico per il numero di nuclei.
  • Attesa I/O spesso il carico è maggiore rispetto alla CPU.
  • 1/5/15-Media dei minuti appiana i picchi.
  • Contesto prima delle azioni: ora, lavori, traffico.

Cosa misura realmente il load average

Leggo il valore come numero medio di Processi, che sono attivi da 1, 5 e 15 minuti o in attesa nella coda di esecuzione. Molti lo confondono con il carico della CPU in percentuale, ma il contatore conosce solo le code, non il tempo di calcolo. Un carico di 1,0 su un sistema single-core significa un utilizzo costante al massimo, mentre lo stesso valore su quattro core rimane rilassato. Per questo motivo confronto sempre il carico in relazione al numero chiave e solo allora valuto se si tratta di un sovraccarico reale. La media di 15 minuti mostra le tendenze e mi aiuta a distinguere i picchi di breve durata dal carico prolungato.

Perché valori elevati spesso indicano problemi di I/O

Può verificarsi un carico elevato anche se la CPU lavora poco: in tal caso le code I/O bloccano il sistema. Discussioni. Controllo con top o htop la percentuale di %wa (I/O-Wait) e con iotop verifico quali processi rallentano lo storage. Spesso la causa è da ricercarsi in database lenti, operazioni di backup o unità di rete sovraccariche. Se %wa aumenta, un upgrade della CPU serve a poco; uno storage più veloce, il caching e un minor numero di sync flush hanno un effetto maggiore. L'articolo fornisce un approfondimento interessante. Comprendere l'I/O Wait, che consulto quando i tempi di attesa sono particolarmente lunghi.

Malinteso: il carico equivale all'utilizzo della CPU

Faccio una netta distinzione tra i valori percentuali della CPU e il Load Average come metrica di coda. Un carico di 8 su un server a 8 core può essere normale se tutti i core funzionano e non c'è nulla in attesa. La situazione diventa critica quando il carico è significativamente superiore al numero di core e contemporaneamente la curva dei 15 minuti aumenta. Per vedere le correlazioni, affianco CPU%, I/O-Wait, tempi di scheduler ed elenchi di processi. Solo l'interazione di questi segnali mi spiega se la macchina sta calcolando, bloccando o semplicemente elaborando molti lavori di breve durata.

Classificare correttamente i picchi invece di allarmarsi

Brevi picchi di carico causati da Cron, rotazione dei log o backup fanno parte della routine quotidiana e non significano automaticamente Malfunzionamento. Valuto sempre l'ora del giorno, la durata e la linea dei 15 minuti prima di attivare gli allarmi o aumentare la capacità. Scalo le soglie con il numero di core, ad esempio attivo l'allarme solo quando il carico è > 2× core per diversi minuti. Controllo inoltre i picchi irregolari nei sistemi di gestione dei contenuti per verificare la presenza di attività in background; per WordPress è utile il suggerimento WP-Cronjobs e carico. In questo modo evito reazioni avventate e do priorità alle misure utili.

Leggere il Load Average nell'hosting quotidiano

Avvio uptime per dare una rapida occhiata, quindi apro htop, per visualizzare i processi, la distribuzione della CPU, la RAM e l'I/O. Se il carico di 15 minuti rimane elevato, cerco i responsabili con iotop o pidstat. In caso di carichi di lavoro pesanti sul database, controllo le latenze delle query, gli indici e i cache hit. Sui server web controllo se ci sono troppi worker PHP simultanei in attesa o se, se necessario, interviene OpCache. Questa routine separa i sintomi dalle cause e mi evita costosi e inefficaci aggiornamenti hardware.

Metriche Vita quotidiana Segnale di avvertimento (4 nuclei) Passo successivo
Carica 1 min <4 >8 oltre 3–5 min Verifica dei processi principali
Carica 15 min <3 >6 in aumento Pianificare la capacità/architettura
CPU% <80% >95% permanente Ottimizzare codice/lavoratori
Attesa I/O <10% >20% Punte Controllare lo storage/caching

Strumenti per un monitoraggio pulito dell'hosting

Combino Metriche da agenti con log e tracce, per individuare più rapidamente le cause. Per le serie temporali utilizzo Prometheus o raccoglitori alternativi, visualizzati in Grafana. A livello infrastrutturale mi aiutano Zabbix per i controlli e le regole di allarme flessibili, nonché i servizi SaaS per dashboard veloci. È importante avere una visione uniforme di carico, CPU%, RAM, swap, latenze del disco e rete. Senza una timeline comune, l'interpretazione dei valori di carico rimane frammentaria.

Categoria Esempio Punti di forza
Fonte aperta Zabbix Controlli, agente, logica di allarme
Serie temporali Prometeo Modello pull, PromQL
visualizzazione Grafana Dashboard, avvisi
SaaS Datadog Integrazioni, APM

Ottimizzazione con carico elevato costante

Comincio dal dolore più grande: lento Domande, percorsi I/O bloccati o troppi worker simultanei. Gli indici dei database, i pool di connessioni e le cache di query come Redis o Memcached riducono notevolmente i tempi di attesa. A livello di applicazione, alleggerisco l'origine: caching di pagine, frammenti e oggetti, nonché elaborazione pulita delle code. Sul sistema imposto vm.swappiness in modo adeguato, controllo le pagine enormi e imposto limiti ragionevoli per i servizi. Solo quando il software è esaurito, eseguo il ridimensionamento verticale (più RAM/CPU) o orizzontale (più istanze con bilanciatore di carico).

Load Average su sistemi multi-core

Calcolo sempre il carico in relazione a Nuclei: Load 16 può andare bene su 16 core fisici. L'Hyper-Threading raddoppia le CPU logiche, ma le prestazioni reali non seguono sempre un andamento lineare; per questo motivo valuto anche le latenze. Nei container o nelle VM entrano in gioco CPU share, quote CFS e limiti, che falsano i valori apparentemente „normali“. Uno sguardo al throttling della CPU e ai tempi di attesa dello scheduler separa i limiti rigidi dai reali problemi di capacità. Per prendere decisioni chiare, la curva di 15 minuti mi aiuta come punto di riferimento per le tendenze.

Hosting condiviso, vicini e colli di bottiglia nascosti

In ambienti condivisi, l'influenza di vicini spesso più potente della propria app. Per questo motivo osservo anche CPU-Steal, tempi di pronto e contenziosi di archiviazione, al fine di individuare carichi esterni. Se i core vengono „rubati“, il carico continua ad aumentare nonostante le proprie ottimizzazioni. Come base decisionale utilizzo la guida su Tempo di appropriazione della CPU e, se necessario, pianifico risorse dedicate. In questo modo garantisco prestazioni pianificabili invece di rimanere bloccato in una situazione di stallo.

Impostare correttamente tendenze, soglie e allarmi

Calibro le soglie per Nucleo e imposto l'isteresi in modo che gli allarmi non scattino ad ogni picco. Per 4 core, avvio gli allarmi a partire da un carico > 8 per diversi minuti e confermo con un trend di 15 minuti. Escludo dalla valutazione le finestre di manutenzione e i tempi di batch, in modo che i grafici non raccontino storie false. Inoltre, utilizzo il rilevamento delle anomalie rispetto alla propria mediana storica, invece di perpetuare valori fissi rigidi. In questo modo reagisco tempestivamente ai cambiamenti reali, senza affaticare il team con falsi allarmi.

Come Linux conta realmente il carico

Se necessario, controllo sotto il cofano: il kernel calcola la lunghezza media della coda di esecuzione e conta non solo i thread attivi (stato „R“), ma anche quelli in sonno ininterrotto („D“, solitamente stato di attesa I/O). Questo spiega proprio i valori di carico elevati con un basso utilizzo della CPU: molti thread bloccano il kernel su dischi lenti, accessi di rete o NFS. In /proc/loadavg vedo le tre medie e in aggiunta i thread „in esecuzione/totali“ e l'ultimo PID. Gli zombie non hanno alcuna rilevanza, mentre i thread del kernel e quelli dell'utente vengono considerati allo stesso modo. Sui sistemi con molte attività di breve durata (build, worker), il valore di 1 minuto varia naturalmente di più, mentre il valore di 15 minuti rimane il mio punto di riferimento per la stabilità.

Per me è importante tradurre „carico“ con „tempo di attesa“: se il carico è nettamente superiore al valore centrale, si formano code. Ciò non deve necessariamente essere negativo se si tratta di lavori di breve durata, ma se contemporaneamente aumenta la latenza delle richieste, il sistema va in sovraccarico. Per questo motivo considero sempre il carico insieme a Tempo di esecuzioneMetriche (Req-Latency, ttfb) per valutare le code non solo in termini numerici, ma anche in termini di efficacia.

Pressione di memoria, swap e blocchi nascosti

Spesso vedo valori di carico costantemente elevati in pressione di accumulo. Quando la cache della pagina si riduce o kswapd sposta le pagine, i processi entrano in stato di attesa. Lo swapping genera I/O e rallenta tutto. Controllo vmstat (si/so), errori di pagina maggiori, /proc/meminfo (Cached, Dirty, Writeback) e osservo se le latenze I/O aumentano contemporaneamente. Un carico elevato con CPU% moderato e un aumento dell'attesa del disco è per me un chiaro segnale: manca RAM o il set di dati non entra nella cache.

Reagisco in più fasi: prima identifico gli hotspot della RAM (ad es. grandi sort, query non memorizzate nella cache, array PHP enormi), poi rafforzo le cache e vm.swappiness in modo tale che la memoria di lavoro non venga sostituita troppo presto. Disattivare completamente lo swap è raramente una scelta saggia: uno swap piccolo e veloce (NVMe) con un utilizzo disciplinato previene i picchi di OOM killer. Se i writeback diventano un collo di bottiglia, attenuo le ondate di sincronizzazione (batching, opzioni di journaling, flush asincroni) e riduco i writer simultanei.

Container, cgroup e throttling della CPU

In Containern interpreto Load con riferimento a cgroups. Le quote CFS limitano il tempo di CPU per periodo; una volta raggiunto il limite, il contenitore continua a mostrare valori di carico elevati, anche se semplicemente ridotto verrà. Controllo cpu.max (cgroup v2) o. cfs_quota_us/cfs_period_us (v1) e il contatore dell'acceleratore (cpu.stat). Se „throttled_time“ aumenta, la causa non è la mancanza di potenza di calcolo, ma limiti rigidi. In Kubernetes distinguo rigorosamente tra „richieste“ (scheduling) e „limiti“ (throttling): limiti impostati in modo errato generano code artificiali.

Anche l'affinità della CPU e NUMA influenzano il quadro: se i thread vengono fissati su pochi core o parcheggiati su un nodo NUMA, il carico può accumularsi localmente, mentre globalmente CPU% sembra a posto. Distribuisco i thread caldi in modo mirato, controllo il bilanciamento IRQ e mi assicuro che i container non vengano tutti compressi sugli stessi core fisici. In questo modo riduco i tempi di attesa senza dover aggiornare l'hardware.

Lista di controllo per decisioni rapide

  • Carico relativo a Nuclei valutare (carico/nuclei ≈ 1 buono, ≫1 critico).
  • CPU% e Attesa I/O Contrastare: la cassa calcola o aspetta?
  • 15 minuti-Verificare la tendenza: sovraccarico prolungato vs. picco breve.
  • Processi principali e Stati (R/D/S/Z); molti Stati D = collo di bottiglia I/O.
  • Latenze del disco, misurare la profondità della coda e %util; controllare anche i percorsi NFS/rete.
  • RAM: Errori di pagina, attività di swap, kswapd – Ridurre la pressione sulla memoria.
  • Limiti Controllare nei container/VM: quote, condivisioni, furti, limitazioni.
  • Concorrenza limitare: worker/thread, code, contropressione.
  • Picchi temporali Trasferire: Cron, backup, indici, ETL.
  • Ricalibrare, quindi misurare nuovamente – Effetto prima dell'hardware.

Esempi concreti di ottimizzazione dall'hosting

Su stack Web/PHP è Concorrenza il massimo effetto leva. Per PHP‑FPM imposto valori realistici pm.max_children, in modo che le richieste non sovraccarichino il database. In nginx o Apache limito le connessioni upstream simultanee, attivo Keep‑Alive in modo sensato e lascio che le risorse statiche vengano memorizzate nella cache in modo aggressivo. OpCache impedisce i picchi di riscaldamento, mentre una cache di oggetti (Redis/Memcached) riduce notevolmente il carico delle query.

Per quanto riguarda i database, inizio con Indicizzazione e piani. Invece di aumentare ciecamente le connessioni, utilizzo pool di connessioni e limito le costose query simultanee. Osservo i tassi di hit del buffer pool, i tempi di attesa dei lock e gli spill delle tabelle temporanee. I report di grandi dimensioni o i lavori di migrazione vengono eseguiti in modo asincrono e in batch: preferisco un carico costante di 60% piuttosto che 5 minuti di 200% seguiti da un arresto.

Per i runner che richiedono molta memoria (ad es. elaborazione di immagini/video), definisco un limite massimo di lavori simultanei per ogni host. Impost bello e ionice, affinché i processi batch non compromettano le latenze interattive. Su dischi NVMe veloci mantengo snella la configurazione dello scheduler, garantisco una profondità della coda sufficiente ed evito le sincronizzazioni chatty. In questo modo scompaiono le valanghe di D-State e il carico diminuisce senza che CPU% aumenti: la macchina semplicemente aspetta meno.

Eseguire in modo pianificato i carichi di lavoro di compilazione e batch

Durante la compilazione o il rendering, il carico è fortemente correlato alla Parallelismo dei lavori. Io voto -j Consapevole: Kerne × (0,8–1,2) è un buon inizio, ma io mi riferisco RAM Meglio avere pochi lavori paralleli stabili piuttosto che tempeste di swap con picchi di carico. Le cache degli artefatti, le build incrementali e i volumi I/O dedicati impediscono che i D-state ingombrino la coda con tanti piccoli file.

Pianifico le finestre batch in modo da ridurre il carico. Rotazioni, backup, ETL e reindicizzazione vengono eseguiti in modo scaglionato, non tutti allo scoccare dell'ora. Le code di lavoro ricevono una contropressione: solo nuovi lavori se gli slot sono liberi, invece che un semplice „fire-and-forget“. In questo modo il carico e le latenze rimangono controllabili e i picchi diventano prevedibili.

PSI: Pressure Stall Information come sistema di allerta precoce

Oltre al classico Load, utilizzo anche il Informazioni sullo stallo di pressione (PSI) di Linux in /proc/pressure/cpu, .../io e .../memoria. PSI mostra la durata delle attività collettivo dovevano aspettare – ideale per sovraccarichi presto Se la pressione della CPU aumenta per diversi minuti, nonostante CPU% sia moderata, so che la coda di esecuzione è congestionata. Con la pressione I/O posso vedere se le latenze di archiviazione hanno un effetto a livello di sistema, anche se i singoli valori iotop sembrano innocui.

Combino PSI con il carico di 15 minuti: se entrambi aumentano, significa che c'è una saturazione reale. Se aumenta solo il carico, ma PSI rimane stabile, è possibile che siano in esecuzione molti lavori brevi che gli utenti non percepiscono. Ciò si traduce in allarmi più chiari e decisioni migliori: aumentare i limiti, distribuire i lavori o potenziare l'hardware in modo mirato laddove sono misurabili dei colli di bottiglia.

Breve panoramica da portare con sé

Leggo il Carico Mai isolati, ma nel contesto di core, I/O-Wait, CPU% e della curva dei 15 minuti. Interpreto i valori elevati solo dopo aver esaminato le latenze di archiviazione e di rete, poiché spesso è lì che si trova il vero freno. Per le misure da adottare, do la priorità ai fattori visibili: query, caching, worker, limiti e solo dopo l'hardware. In ambienti condivisi, controllo gli effetti parassitari come lo steal e, se necessario, pianifico risorse dedicate. Con queste regole prendo decisioni tranquille e solide e mantengo le configurazioni di hosting affidabili e veloci.

Articoli attuali