Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial
  • Lezione 40 di 58
  • livello intermedio
Indice lezioni

Replica in MySQL: limiti e possibili soluzioni

Una panoramica dei principali difetti della replica su MySQL, e di alcune delle soluzioni adottate per risolverli e gestirli correttamente.
Una panoramica dei principali difetti della replica su MySQL, e di alcune delle soluzioni adottate per risolverli e gestirli correttamente.
Link copiato negli appunti

Fino ad ora abbiamo analizzato soprattutto i vantaggi legati alle repliche in MySQL. Purtroppo, come spesso accade, anche questa architettura presenta qualche svantaggio. Trattandosi però di un pattern diffuso, la maggior parte dei problemi noti sono stati affrontati in innumerevoli situazioni, portando ad oggi una serie di soluzioni che permettono di considerare maturo l'intero quadro.

Proteggere la replica tra master e slave

La configurazione che abbiamo visto fino ad ora gestisce in maniera semplice un sistema complesso come quello di una replica di database, ma ha lo svantaggio di fornire accesso all'esterno al database e, ancora peggio, gestire le comunicazioni tra il master e lo slave in maniera non criptata (rendendo il tutto vulnerabile ad uno sniffing). Considerando la necessità di riservatezza nel trattamento di una notevole mole di dati (dai dati personali alle credenziali di accesso) è necessario pensare ad una soluzione.

MySQL supporta nativamente le connessioni sicure protette da certificati SSL, ma queste richiedono una configurazione specifica dei certificati tra il server master e il server slave, che può non essere immediata. Un'altra soluzione attuabile ci viene fornita dal software SSH (Secure Shell), che permette l'accesso remoto alla shell di comando di un server di cui possediamo le credenziali di accesso.

Tramite SSH è infatti possibile creare un tunnel criptato tra una porta presente sulla macchina locale e una porta sulla macchina remota; ad esempio è possibile mappare la porta 3307 locale alla porta 3306 (porta standard di MySQL) del server da raggiungere. In questo modo sulla macchina locale possiamo avviare una connessione con l'indirizzo 127.0.0.1:3307, ed essere collegati direttamente con il server MySQL con un doppio vantaggio:

  • tutte le comunicazioni avvengono in maniera criptata;
  • per la macchina remota le connessioni non arrivano dall'esterno ma dall'IP interno 127.0.0.1, permettendoci quindi di chiudere l'accesso esterno al server e aumentando la sicurezza complessiva del sistema.

Per applicare questo concetto alla replica, ci basterà creare un tunnel dalla porta 3307 sul server slave alla porta 3306 sul server master, ed impostare l'indirizzo IP del server master a 127.0.0.1:3307 nella configurazione del server slave che abbiamo visto nelle lezioni precedenti.

Avviare un tunnel SSH sembra complesso, ma in realtà si tratta di un'operazione abbastanza semplice dato che basta eseguire il seguente codice:

ssh -L 3307 127.0.0.1:3306 user@123.123.123.123

dove 3307 è la porta locale, 3306 è la porta remota, user è l'username dell'utente del server di destinazione di cui abbiamo le credenziali di accesso e 123.123.123.123 è l'indirizzo IP (o l'hostname) del server di destinazione. Al primo accesso ci verra chiesto se considerare sicuro il server remoto, e dovremo rispondere sì (ovviamente se si tratta realmente del nostro server); ci verrà inoltre richiesta la password dell'utente. Possiamo evitare che la password ci venga richiesta creando una coppia di chiavi SSH pubbliche e private, e consegnando quella pubblica al server remoto.

Questa procedura è perfetta per collegarsi dalla propria macchina di sviluppo al database senza dover aprire la porta di ascolto di MySQL all'esterno, e senza dover passare attraverso un client come PhpMyAdmin. Quando invece il collegamento avviene tra due server, che quindi necessitano di una connessione permanente, può non essere una buona idea limitarsi al tunnel qui descritto, poiché la connessione SSH potrebbe cadere per mancanza temporanea di linea. Questo causerebbe l'interruzione della connessione e di conseguenza la possibile chiusura della replica. Per evitarlo, possiamo creare uno script da mettere in cron, che controlla la disponibilità del tunnel e lo riavvia in caso di connessione interrotta. In alternativa, potremmo più semplicemente ricorrere ad un software pensato appositamente per questo motivo: autossh.

Limiti delle repliche master/slave in MySQL

La replica master/slave presenta alcune limitazioni intrinseche, come l'impossibilità di scrivere sui server slave. In questo caso non si tratta di un impedimento insormontabile: il server slave accetta query di modifica dati (INSERT, UPDATE, DELETE, REPLACE, TRUNCATE) o struttura (DROP, ALTER, CREATE) senza restituire errori durante l'esecuzione della stessa.

In questo caso in realtà il problema nasce in seguito: se si apportano modifiche su un server slave, infatti, questo entrerà in una fase di conflitto con il server master, portandoci nel migliore dei casi ad un problema di inconsistenza dei dati (la versione master e slave non saranno più copie identiche) e nel peggiore dei casi all'interruzione della replica che richiederà un riavvio manuale. Questo perché la replica dei dati, come illustrato nelle lezioni precedenti, è un processo di semplice interrogazione del server master e di esecuzione pedissequa delle query sullo slave. Sul server slave, infatti, non sono previsti meccanismi di controllo per assicurare la congruità dei dati.

La soluzione in questo caso è semplice: usare il server slave esclusivamente per operazioni in lettura ed eseguire tutte quelle in scrittura sul server master. Applicare questo concetto può sembrare semplice, ma nella realtà finisce spesso per risultare più complicato del previsto, ad esempio perché non abbiamo accesso diretto al codice dell'applicazione in esecuzione.

Per tutelarci come DBA (amministratori di database) ed evitare che un client possa creare problemi al nostro sistema, è necessario come minimo utilizzare i privilegi di accesso in maniera diversificata: sullo slave possiamo fornire un utente con soli privilegi di lettura, creando invece sul master un utente con pieni poteri di modifica. Questa soluzione però tutela esclusivamente la figura del DBA, non semplificando la vita degli sviluppatori che con quel database si devono interfacciare, e che saranno costretti a gestire un collegamento con due server differenti avendo cura di eseguire ogni query sull'apposito server.

Server proxy per MySQL

Per semplificare l'utilizzo da parte di un applicativo autorizzato è possibile ricorrere ad una soluzione lato server installando un server proxy specifico. Si tratta in questo caso di un applicativo che si interpone tra un client e un server, agendo in maniera trasparente per entrambi (cioè utilizzando lo stesso protocollo di comunicazione client/server). Il server proxy potrà quindi modificare le query o i risultati restituiti, tenere un log delle richieste o anche decidere arbitrariamente su quale server reindirizzare le richieste. Ad esempio, possiamo configurare il nostro proxy server per inviare le query di modifica dei dati al server master, e quelle in lettura ad un server slave. Concettualmente, si può associare questo comportamento a quello di un decorator nell'ambito della programmazione ad oggetti.

In questo caso non stiamo parlando quindi di un server proxy generico che possa gestire, ad esempio, il load balancing, bensì di un server specifico che comprende il protocollo e le comunicazioni tra client e server, e che sia in grado per questo di modificarle o eseguire specifiche azioni sulla base del loro contenuto.

In questo modo possiamo fornire alla nostra applicazione finale un unico punto di accesso alla nostra struttura dati, indipendentemente da quanto questa sia estesa, complessa o articolata. Sarà il proxy a gestire questa complessità liberando il client da tale incombenza e il DBA dal possibile utilizzo scorretto da parte dell'utilizzatore. Tutto ciò ha, ovviamente, un costo (seppur spesso tollerabile) in termini di performance, se confrontato con le connessioni dirette. In termini tecnici, questa funzione si definisce query routing.

Attualmente sono disponibili diversi progetti che rispondono a queste esigenze, in ragione del fatto che questa soluzione porta notevoli vantaggi:

  • MySQL Proxy: sviluppato inizialmente da MySQL AB nel 2007 e gestito in maniera non entusiastica da parte di Oracle, che ne ha interrotto lo sviluppo nel 2013;
  • MySQL Router: sviluppato da Oracle e attivamente supportato;
  • MaxScale: sviluppato dal progetto MariaDB e attivamente supportato;
  • ProxySQL: definito dagli sviluppatori come il proxy server per DBA prodotto da DBA;
  • Kingshard: un server proxy per MySQL sviluppato in GO;
  • Mixer: un altro server proxy per MySQL sviluppato in GO.

Ognuno dei software sopra elencati ha pregi e difetti da considerare, quali il supporto attivo, la dimensione del team di sviluppo, le caratteristiche aggiuntive supportate o la documentazione disponibile. Dal nostro punto di vista sono equivalenti, nel senso che tutti hanno la funzione di query routing. Di conseguenza, la scelta del sistema da utilizzare è personale e dovrebbe tenere conto, tra le altre cose, anche della semplicità di configurazione.

Ti consigliamo anche