Sito lento, server scarico: scoprire dove finisce il tempo
Il database viene incolpato per primo perché è lì che l'attesa si sente; misurare ogni livello di una singola richiesta lenta mostra dove il tempo viene speso davvero.
In questo articolo 4 sezioni
- Una pagina lenta e un database occupato sembrano la stessa cosa guardando il numero di connessioni, perché il database è l'ultima fermata sincrona nella maggior parte delle richieste ed eredita ogni stallo che sta sopra di lui.
- Tracciate una singola URL lenta livello per livello: l'edge, la macchina, l'applicazione, poi il database. Il livello a cui appartiene il tempo è raramente quello nominato nel ticket.
- Una macchina più grande accorcia la parte della richiesta che era già breve. Misurate prima di comprare qualsiasi cosa.
Perché il database è il solito sospetto
Quando una pagina rallenta, il database è dove il sintomo diventa visibile per primo. Le connessioni si accumulano, la process list si riempie di query nello stato sending data, e lo slow query log comincia a crescere. Tutto questo è reale, e nulla di tutto questo dice dove sia finito il tempo. Il database sta alla fine della maggior parte dei percorsi di richiesta. Una pagina che lo chiama duecento volte invece di due, un worker che tiene aperta una connessione mentre aspetta un gateway di pagamento, una cache che viene aggirata a ogni hit: ciascuno di questi casi si manifesta come carico sul database, perché il database sta facendo esattamente ciò che gli viene chiesto, più spesso di quanto dovrebbe essergli chiesto.
Lo stesso vale per il server. Una macchina con un carico alto è una macchina a cui viene dato del lavoro. Se quel lavoro sia necessario è una domanda a cui il grafico del carico non può rispondere.
Tracciate una richiesta, non l'intero sito
Il metodo è scegliere una URL lenta e seguirla attraverso i livelli, misurando a ogni confine. Partite dall'esterno, da una macchina che non sta sulla stessa rete, e lasciate che curl riporti dove finisce il tempo prima che arrivi il primo byte.
$ curl -o /dev/null -s -w 'dns %{time_namelookup} connect %{time_connect} tls %{time_appconnect} ttfb %{time_starttransfer} total %{time_total}\n' https://www.example.com/slow-pageSe il tempo al primo byte è la maggior parte del totale, l'attesa sta sul lato server. Se il totale è molto più grande del tempo al primo byte, la pagina è pesante oppure la storia è il percorso tra il visitatore e l'edge, e il server non faceva parte dell'attesa.
Sulla macchina, campionate la CPU mentre la richiesta lenta è in corso, non un'ora di quiete più tardi.
$ mpstat -P ALL 1 5
$ vmstat 1 5Un server per lo più scarico durante una richiesta lenta, senza iowait e senza steal, si è scagionato da solo. Il tempo viene speso aspettando qualcosa, non calcolando.
Poi l'applicazione. La maggior parte dei framework può registrare, per richiesta, il numero di query emesse, il tempo totale speso in esse e il tempo speso in chiamate HTTP in uscita. Attivatelo per la URL lenta. Due numeri chiudono la discussione: quante query emette una singola pagina, e quanto del tempo totale è stato speso completamente fuori dall'applicazione.
Infine il database, con lo slow query log attivo e la soglia abbastanza bassa da catturare ciò che conta.
SET GLOBAL slow_query_log = ON;
SET GLOBAL long_query_time = 0.2;
SET GLOBAL log_queries_not_using_indexes = ON;Leggete il log nella finestra della richiesta lenta. Una manciata di query che impiegano secondi ciascuna è un problema di database. Migliaia di query che impiegano un millisecondo ciascuna è un problema dell'applicazione di cui il database viene incolpato.
Gli schemi che emergono dalle misure
Con i livelli separati, la causa tende a prendere una di poche forme.
Un endpoint chiamato in un ciclo. Un front end che richiede di nuovo la stessa risorsa a ogni cambio di stato, o una pagina che emette una query per riga invece di una query per pagina. Il database risponde a ogni chiamata in fretta; il problema è il numero.
Una chiamata sincrona a qualcun altro. Un fornitore di pagamenti, un ERP, un'API di spedizione, un tag manager, seduti sul percorso della richiesta dietro un timeout lungo. Il server è scarico per tutta l'attesa, e la pagina è lenta quanto la terza parte più lenta da cui dipende.
Una cache che viene vanificata. Header che vietano la cache su pagine che non cambiano, oppure nessuna cache all'edge davanti a traffico anonimo che non è mai stato dinamico.
Pool dimensionati a occhio. Pool di worker, di connessioni e di buffer impostati troppo grandi tanto spesso quanto troppo piccoli. Un pool molto più grande di ciò che la macchina può servire in parallelo trasforma una coda in un thrashing.
L'esaurimento reale è l'ultima forma, e quando compare è di solito a valle di una delle prime tre. La macchina che finisce qualcosa è la fine della storia, non l'inizio.
Cosa cambia un server più grande
Aggiungere core o memoria accorcia la parte della richiesta che stava calcolando. Se quella parte era già piccola, la pagina non diventa più veloce; l'attesa si sposta con essa. Il ciclo continua a ciclare, la terza parte continua a prendersi il suo tempo, la cache è ancora aggirata. L'upgrade nasconde inoltre la misura che avrebbe trovato la causa, perché il grafico che era rosso ora è ambra, e il ticket si chiude.
Per questo tracciamo prima di fare un preventivo. Una piattaforma sana resta noiosa, e il lavoro è trovare il livello a cui appartiene il tempo, anche quando quel livello sta sopra qualsiasi cosa gestiamo noi, e restituire la misura che indica la riga.
Risposte dirette
Perché il mio sito è lento se il server ha CPU e RAM in abbondanza?+
Perché il tempo viene speso aspettando, non calcolando: su un ciclo di chiamate, su un'API di terze parti nel percorso della richiesta, su una cache aggirata, su una query emessa migliaia di volte. Un server scarico durante una richiesta lenta è un forte indizio che l'attesa vive sopra l'hardware.
Un sito lento è di solito colpa del database?+
Il database è di solito dove l'attesa si vede, perché è l'ultima fermata sincrona della richiesta ed eredita ogni stallo che sta sopra di lui. Se sia la causa lo decide lo slow query log: poche query lente indicano il database, una marea di query veloci indica l'applicazione.
Devo comprare più RAM o un server più grande per sistemare un sito lento?+
Non prima della traccia. La capacità accorcia la parte di calcolo di una richiesta. Se la richiesta stava aspettando invece di calcolare, l'upgrade sposta l'attesa invece di eliminarla, e nasconde il grafico che avrebbe trovato la causa.
Come si distingue un problema dell'applicazione da un problema del database?+
Contate e cronometrate. Per richiesta: quante query, quanto tempo in totale, quanto tempo in chiamate in uscita. Per query: lo slow log. Se il tempo per query è basso e il numero è alto, l'applicazione chiede troppo spesso. Se il tempo per query è alto, il problema è la query, l'indice o lo schema.
Portateci la vostra URL più lenta e la tracceremo livello per livello fino alla riga a cui appartiene il tempo.
Parlate con un ingegnere.
Parla con un ingegnereSiete arrivati alla fine.
Mettete la lettura al lavoro
Cosa fate girare?
Raccontateci il carico di lavoro, il traffico e i requisiti di ripristino. Partite dal configuratore di server, oppure discutete i dettagli con un ingegnere.
Scritto dagli ingegneri che costruiscono e gestiscono l'infrastruttura che descrive.Parla con un ingegnere
