Una scrittura non si bilancia.
Nodi database identici sembrano capacità di scrittura moltiplicata. Distribuite le vostre scritture su tutti e il cluster fabbrica deadlock. Il design che funziona.
In questo articolo 2 sezioni
- La configurazione intuitiva del cluster: nodi identici, un load balancer, tutto in round-robin. Sembra capacità moltiplicata.
- Sotto un carico del tutto normale consegna errori di deadlock ai redattori a metà pubblicazione, senza alcun bug di locking nel codice. Due redattori, due nodi, una riga calda, e il controllo dei conflitti del cluster ne rimanda indietro uno.
- La soluzione controintuitiva: ogni scrittura va a un solo nodo eletto, e solo le letture si distribuiscono.
- Il colpo di scena che risponde a «ma distribuire non è più veloce?»: il volume di scritture è raramente il vincolo. La capacità di lettura è ciò che scala, e gli errori spariscono.
Avete comprato un cluster di database. Nessuno compra più esemplari di una cosa per usarne uno, quindi la configurazione del load balancer si scrive praticamente da sola: round-robin di tutto su ogni nodo. La convinzione sottostante è semplice: una singola query non sarà più veloce, ma molte lo saranno, divise tra le macchine. Suona ovviamente corretto. È anche il modo più comune in cui vediamo usare male questa classe di cluster.
Il bug che non è nel codice
Sotto un carico ordinario, i redattori a intermittenza premono salva e si vedono restituire un errore grezzo del database attraverso il CMS: deadlock found. È intermittente e difficile da riprodurre, e nessuna quantità di lettura del codice applicativo lo troverà, perché il bug non è nel codice.
Il carico che diventa l'arma è ordinario. Un CMS riscrive una manciata di righe di configurazione con nomi globali quasi a ogni azione. Un plugin SEO ricostruisce la sua sitemap a ogni salvataggio. Timestamp di login e contatori di visualizzazioni toccano tutti le stesse righe calde. Il round-robin sparge quelle scritture concorrenti su ogni nodo. Ogni nodo accetta la propria scrittura localmente, e poi il passo di certificazione del cluster coglie la collisione al momento del commit e la rimanda a un client che non ha fatto nulla di sbagliato. Due redattori, due nodi, la stessa riga: errore 1213.
Un deadlock sotto carico normale, su un cluster, senza alcuno schema di locking nell'applicazione, è un sintomo di instradamento. Il carico non è sbagliato. La topologia sì.
Un solo writer per la sicurezza, letture distribuite
Convogliare tutte le scritture su un nodo spreca gli altri? No. Le letture si bilanciano uniformemente sul cluster e ogni scrittura va al singolo writer eletto. L'istinto del round-robin ha ragione sulle letture e torto sulle scritture; l'instradamento a writer singolo tiene la metà giusta e cancella gli errori che l'altra metà genera. Se il vostro primo istinto su un cluster occupato è scalare verso l'alto, la lezione gemella è che la mossa giusta è spesso l'opposto (ridimensionate verso il basso, non verso l'alto).
1213
1
“Un cluster è capace di multi-primary e sicuro con un solo writer. Sono due frasi diverse.”
Se gestite un cluster con letture bilanciate, andate a scoprire dove atterrano davvero le vostre scritture. Se la risposta è «ovunque il balancer le mandi», siete a un pomeriggio intenso dal fabbricare deadlock con il vostro stesso successo. Il controllo costa la lettura di una configurazione. La soluzione è una regola di instradamento, non una riscrittura.
Risposte dirette
Perché ricevo errori di deadlock (1213) sul mio cluster Galera o PXC sotto carico normale?+
Se non c'è alcun bug di locking nel vostro codice, controllate l'instradamento delle scritture. Scritture sparse sui nodi collidono sulle righe calde al momento della certificazione, e il cluster riporta la collisione come deadlock a un client innocente. Instradate ogni scrittura a un solo nodo e l'intera classe di errore sparisce.
Mandare tutte le scritture a un solo nodo non spreca il mio cluster?+
Le scritture non sono quasi mai il collo di bottiglia; il volume sono le letture. Con l'instradamento a writer singolo, le letture continuano a bilanciarsi su ogni nodo e il throughput di scrittura non cambia, perché di fatto un solo nodo ha sempre fatto tutto il lavoro di scrittura.
Un cluster Galera può fare scritture multi-master?+
È capace di accettare scritture su ogni nodo, ed è sicuro quando non deve certificare scritture concorrenti sulle righe calde provenienti da più nodi insieme. Capace di multi-primary, sicuro con un solo writer. Usate la capacità per il failover, non per la distribuzione del carico.
Come scalo le scritture del database, allora?+
Prima dimostrate di averne bisogno: misurate il volume di scritture rispetto al margine del writer singolo, che di solito è un errore di arrotondamento accanto alle letture. Lo scaling autentico delle scritture è territorio di sharding o di riprogettazione del carico, non un'impostazione del load balancer.
Cosa instrada letture e scritture in modo diverso?+
Uno strato proxy che parla il protocollo del database può separarle: le letture si distribuiscono, le scritture si fissano sul writer eletto, e il failover rielegge un writer automaticamente. Gestiamo questo schema in produzione: ProxySQL davanti a Percona XtraDB Cluster.
Vedete deadlock che non trovate nel codice?
Mandateci solo l'errore e come è bilanciato il vostro cluster. Se è la topologia, ve lo mostreremo, e lo sistemeremo nell'instradamento, non nella vostra applicazione.
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
