Come abbiamo visto, l'utilizzo di Galera per la creazione di un cluster MySQL si avvale delle API wsrep, che rappresentano il vero livello operativo per la gestione della sincronizzazione dei nodi partecipanti. L'aggiunta di questo layer ha lo svantaggio di ridurre le prestazioni della singola macchina ed aumentare la quantità di RAM richiesta per il server. Ciò va sempre tenuto in considerazione nell'analisi complessiva dei vantaggi/svantaggi di questa soluzione, soprattutto se abbiamo intenzione di utilizzare VPS.
Le API wsrep mettono comunque a disposizione una serie di opzioni di configurazione per personalizzarne il funzionamento. Analizziamo quelle con cui più probabilmente ci troveremo ad interagire.
Trasferimento dei dati
Mentre per le repliche master/master (o master/slave) dobbiamo provvedere manualmente alla sincronizzazione dei server implicati, trasferendo un dump dei database e un codice numerico che rappresenta lo stato di scrittura, per i cluster Galera non abbiamo questa necessità. In questo caso, infatti, è il server stesso ad occuparsi di gestire la sincronizzazione attraverso due diversi tipi di trasferimenti:
- SST (State Snapshot Transfer): sono i trasferimenti totali per portare una macchina che si collega al cluster al livello delle altre (l'equivalente del trasferimento manuale dei dump);
- IST (Incremental State Transfer): sono i trasferimenti parziali che aggiornano un macchina che già faceva parte del cluster, e ne è uscita per qualche ragione.
Nella maggioranza dei casi, il metodo utilizzato sarà SST, ma l'esistenza di IST permette di ottimizzare il rejoin di una macchina al cluster senza la necessità di trasferire gli interi database replicati (che possono raggiungere dimensioni rilevanti). In ogni caso, la scelta del tipo di trasferimento non è selezionabile, e dipende unicamente dagli algoritmi interni di wsrep. Quello che invece possiamo modificare è il metodo utilizzato per effettuare concretamente il trasferimento, tramite le opzioni wsrep_sst_*
.
Nella configurazione base di un cluster Galera abbiamo usato l'opzione wsrep_sst_method
impostandola a rsync
, ma avremmo potuto usare anche un altro dei valori validi come rsync_wan
, xtrabackup
e mysqldump
. Mentre quest'ultimo è un metodo di trasferimento "logico", in cui essenzialmente vengono trasferite delle query SQL da applicare, gli altri sono metodi "fisici", che implicano il trasferimento dei file binari che rappresentano le tabelle.
La differenza principale tra trasferimenti "logici" e "fisici" è rappresentata dalla compatibilità necessaria tra i server coinvolti: visto che nel trasferimento fisico vengono trasferiti dei file binari, tutti i server partecipanti al cluster dovranno avere la stessa configurazione relativamente ai formati di file binari, cosa che è invece non necessità per i trasferimenti logici (sebbene questi ultimi risultano più lenti). Nella quasi totalità dei casi le macchine che partecipano ad un cluster hanno gli stessi file di configurazione personalizzati esclusivamente per le caratteristiche che identificano il singolo nodo, ragion per cui in concreto questa distinzione ha poca rilevanza.
Se il nostro cluster è composto da macchine distribuite geograficamente, è preferibile utilizzare l'opzione rsync_wan
, poiché essa ottimizza il trasferimento riducendo la dimensione dei file da inviare e ricevere. Il valore xtrabackup
utilizza il software Percona XtraBackup per effettuare un trasferimento di file in maniera non bloccante, permettendo quindi al nodo donatore, cioè quello da cui parte il trasferimento, di continuare ad essere raggiungibile e operativo. Questa caratteristica può essere molto utile in un cluster di piccole dimensioni (il numero minimo consigliato è 3 per evitare lo split brain).
Questi valori, in realtà, corrispondono a script eseguibili lato server che si occupano del trasferimento reale dei dati, per cui è possibile in teoria aggiungere script personalizzati anche se questa possibilità sarà utilizzata raramente. L'unica limitazione è data dal fatto che, a livello di cluster, deve essere utilizzato un unico metodo di trasferimento; di conseguenza, eventuali script personalizzati devono essere presenti su ogni macchina partecipante.
Alcuni script di trasferimento, come mysqldump
e xtrabackup
, richiesto l'impostazione delle credenziali di un utente abilitato ad accedere al database. A tale scopo di utilizza l'opzione wsrep_sst_auth
. Il valore di questo parametro è una stringa composta da username e password, separati da due punti (ad esempio username:password
).
Normalmente, il nodo donatore viene stabilito dal cluster tramite un algoritmo che non tiene conto, ad esempio, della potenza di calcolo delle varie macchine o della distanza geografica rispetto al nodo ricevente. Possiamo ovviare a questo specificando un nodo o una lista di nodi da utilizzare in maniera preferenziale nell'ordine in cui sono indicati, tramite l'opzione wsrep_sst_donor
. Il valore di questo parametro è una stringa composta dai nomi dei nodi specificati con le opzioni wsrep_node_name
, separati da una virgola (attenzione quindi a non inserire l'hostname o l'indirizzo IP dei nodi).
Gestire il comportamento fuori dalla sincronia
Il concetto stesso di cluster è basato sul fatto che i dati di ogni nodo partecipante devono essere sincronizzati con quelli presenti sugli altri nodi. A tale scopo, tutte le query di modifica dei dati (INSERT
, UPDATE
, REPLACE
) che vengono richieste da un client ad un nodo server ricevente, devono essere inoltrate agli altri nodi, che devono quindi eseguirle. Questo è il motivo principale per cui le prestazioni del cluster dipendono da quelle del nodo più lento, oltre ad essere ridotte anche a causa dei tempi di latenza.
A livello teorico, un cluster avviato è composto da nodi sempre sincronizzati tra di loro. Nella pratica, però, ciò non è sempre vero: ad esempio, è possibile che ci sia un'interruzione nella comunicazione tra nodi che potrebbe causare un'uscita temporanea dalla sincronia, oppure può succedere che su una macchina vengano eseguite operazioni talmente intensive da ritardare l'esecuzione degli aggiornamenti. Anche eseguire il dump di un database può mettere in difficoltà il nodo del cluster, poichè esso richiede che tutte le tabelle vengano poste temporaneamente in stato di lock.
Per questa ragione, ogni server del cluster ha a disposizione una coda di lavorazione delle modifiche, in modo da gestire contrattempi temporanei. Se invece il nodo non riesce a stare dietro alle modifiche da applicare, esso può decidere di uscire temporaneamente dallo stato di sincronia per completare la propria coda di lavorazione, e quindi riunirsi al cluster tramite il Flow Control. Tramite l'opzione wsrep_desync
(i cui valori consentiti sono OFF
e ON
) è possibile disabilitare questo comportamento, mantenendo il nodo sempre operativo. Il vantaggio consiste nell'avere una macchina in più su cui scalare le operazioni, ma le query in lettura avranno accesso a dati fuori sincronia, e quindi senza la garanzia della consistenza dei dati.
Dalla versione 5.6.29 di MySQL è possibile utilizzare l'opzione wsrep_dirty_reads
per gestire il comportamento dei nodi che escono dalla sincronia e entrano in uno stato non operativo. In condizioni normali, un server in queste condizioni rifiuta qualsiasi tipo di query (modifica della struttura, scrittura, lettura) e deve quindi essere escluso da un eventuale livello di load balancing per tutte le operazioni. Impostando l'opzione su ON è invece possibile permettere le sole query in lettura con i vantaggi e svantaggi precedentemente esposti.
Nel momento in cui un nuovo nodo si unisce al cluster (o un vecchio nodo esegue un re-join), esso diventa il ricevente dei dati forniti da un nodo donatore. Quest'ultimo, a sua volta, esce dallo stato di sincronia in maniera temporanea e controllata per poter eseguire il trasferimento di dati. Di base, un nodo donatore continua a rispondere alle query che riceve anche durante il trasferimento di dati verso il ricevente. Visto che alcuni metodi di trasferimento sono bloccanti, come abbiamo visto in precedenza, è possibile che si crei un conflitto con delle query bloccanti. Per questa ragione, è possibile configurare le macchine donatrici perché rifiutino qualsiasi query e vengano di fatto considerate come non raggiungibili tramite l'opzione wsrep_sst_donor_rejects_queries
impostata su ON
.
Questo comportamento può sembrare il più idoneo, ma a seconda della dimensione del cluster si potrebbero creare situazioni rischiose. Ad esempio, con un cluster di tre nodi la macchina che si sta aggiungendo sarebbe considerata fuori dalla sincronia per definizione, e quindi non risponderebbe alle query presentate lasciando due soli server operativi: togliendo l'operatività anche al server donatore, ci troveremmo nella situazione di avere un'unica macchina raggiungibile, vulnerabile a possibili sovraccarichi.