Cluster Mysql

Una delle caratteristiche più interessanti di mysql è la possibilità di replicare le modifiche al database su di un altro nodo che verrà mantenuto quindi aggiornato e al tempo stesso sarà disponibile per effettuare query in lettura,  backup o altro.

Questa caratteristica da luogo alla possibilità di implementare cluster con configurazioni (topologie) più o meno articolate che, avendo caratteristiche differenti, potranno tornare utili in situazioni diverse.

Quello che si cerca di ottenere in genere con queste configurazioni è in genere ridondanza per gestire fault dei server minimizzando il disservizio, scalabilità orizzontale nelle prestazioni o entrambe. Per scalabilità orizzontale si intende la possibilità di aggiungere server al sistema per aumentarne le prestazioni e si contrappone alla scalabilità verticale in cui per far crescere le prestazioni bisogna sostituire l’hardware precedente con altro in genere molto più costoso.

Altre volte quello che si vuole è un nodo disponibile per attività non standard: la possibilità di effettuare dei backup fuori linea, un ambiente su cui generare reportistica senza impattare sulle prestazioni del sistema di produzione, un ambiente su cui fare debugging o altro.

La configurazione più semplice possibile è una configurazione master-slave. In questa configurazione un solo nodo del cluster riceve le chiamate che modificano i dati mentre l’altro è disponibile per altre attività come i backup, attività di reporting o anche l’esecuzione di query di sola lettura di dati.

Sono utili alcune precisazioni:

  • mysql implementa la replica ma nessun meccanismo di distribuzione delle query. E’ demandato all’applicativo l’onere di inviare le query al server giusto. Questo si può fare sia tramite logica interna al client, sia con strumenti che si interpongono tra client e server quali proxy, pooling o loadbalancing.
  • mysql implementa la replica ma non implementa nessun meccanismo di tackeover: se il master dovesse morire il cluster perderebbe il nodo su cui vengono eseguite le query le query in scrittura. Anche in questo caso è demandato a strumenti esterni quali script, load balancing o lo stesso applicativo client l’onere di implementare la ridondanza. C’è da dire poi che questa non è la tipologia di cluster migliore per implementare la ridondanza data la sua forte asimmetria.
  • Se si utilizza il nodo mysql slave per fare dei backup si può avere un dump coerente con strumenti standard anche solo interrompendo i processi di replica; in questo modo infatti si sono sospese tutte le scritture sul nodo in esame.
  • se si utilizza il nodo mysql slave per fare dei backup e si vuole poter sfruttare il point in time recovery, bisogna abilitare i binary log anche sul nodo slave dato che sono questi che dovranno essere associati al backup stesso. O, meglio, bisogna associare al backup l’informazione dello stato della replica rispetto ai binary log del master; informazioni disponibili sullo stato della replica.

Una topologia di replica secondo me molto più interessante e flessibile è quella master-master. In questa configurazione si ha una coppia di server mysql ognuno dei quali replica le modifiche dell’altro.

Questa configurazione è estremamente flessibile perché, data la sua simmetria, è molto facile realizzare un sistema in High Havailability in cui un nodo venga sostituito dall’altro. E’ possibile farlo con diversi struementi, ad esempio heartbeat o un bilanciatore. Inoltre si può sia sfruttare entrambi i nodi per le scritture, sia utilizzare il cluster master-master come se fosse un sistema master-slave sia sfrutatrlo solamente per la ridondanza accedendo in condizioni normali ad un solo nodo. In tutti i casi però la simmetria del sistema fa si che nell’automatizzare lo scambio dei ruoli dei server non sia necessario intervenire sulla configurazione del database.

Ovviamente questa semplicità ha un costo, o se si preferisce i problemi vengono spostati altrove. In questa configurazione ci sono molte sottigliezze legate alla replica di cui l’applicazione deve tenere conto per non dare risultati sbagliati; sottiglizze legate soprattutto agli autoincrement, agli ordinamenti e a considerazioni di ACID compliance.

Se i nodi sono più di due le possibilità sembrano moltiplicarsi ma le vie ragionevolmente percorribili non sono poi così tante.

La prima possibilità è quella di avere un master e molti slave: questa configurazione, molto utile per i siti web in quanto permette di far crescere quasi a piacere la capacità di gestire query in lettura, presenta il non piccolo problema di non essere ridondata sul nodo master. L’implementazione di script che promuovono uno dei nodi slave al ruolo di master nel caso di fault del master precedente presenta moltissimi problemi: si pensi solo alla difficoltà di determinare qual’è lo slave più avanti con la replica e quindi più adatto a prendere il ruolo di master, per non parlare dei problemi nel riattestare tutti gli slave sul nuovo master.

Più praticabile, ma ovviamente molto più costosa, è la possibilità di implementare un cluster classico active-passive con disco condiviso per il solo master. Anche in questo caso comunque alcune attività possono rendersi necessarie sui nodi slave in caso di takeover del master.

Si può poi pensare di estender il caso di configurazione master-master  in una topologia ad anello in cui ogni nodo è replica del precedente e il primo è replica dell’ultimo. Questa configurazione nella pratica non è una grande idea per due ragioni:

  • il sistema nel suo insieme è sempre meno affidabile al crescere del numero dei nodi perché la rottura di un elemento qualsiasi della catena interrompe la propagazione delle modifice e bisogna quindi implementare una logica tutt’altro che banale che automatizzi l’esclusione di nodi rotti. Nodi che soarà poi comunque difficile reinserire senza dare disservizi.
  • ci sono potenziali problemi insidiosi legati al meccanismo di replica di mysql; questo infatti legge tutte le query nel binary log che ha in ingresso e se trova che il primo esecutore di una query è stato un altro nodo la esegue e la scrive nel proprio binary log altrimenti, se cioè riconosce di essere stato il primo esecutore di una query, la scarta. Tutto funziona bene fino a che non muore un nodo. Si pensi a cosa succede se in un sistema di tre server mysql A, B e C configurati ad anello: A master di  B master di C master di A si verifica la seguente situazione. Il nodo A esegue una query di insert e poi muore ad esempio per la rottura di un disco ma solo dopo aver passato l’insert al nodo B. Gli script del sistema riconoscono il problema ed escludono il nodo A rendendo C master di B. B riconosce come non propria la query ricevuta da A, la esegue e la passa a C; C riconosce la query come non propria, la esegue e la passa a B etc in un loop infinito. Per la verità le versioni più recenti di mysql hanno introdotto funzionalità per controllare questo problema ma la situazione rimane delicata.

Un’ultima configurazione che si può pensare di implementare è master-master ( o anche un anello con n master) su cui attestare un gruppo di slave. Gli slave andranno ovviamente divisi tra i master. Il problema di questa configurazione è che se uno dei master viene meno, si perde la possibilità di utilizzare tutti gli slave che a lui fanno capo a meno di non aver implementato una logica che permetta di riattestare gli slave sul master residuo.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *