La replica di MySQL è interessata da un'interconnessione ad alta latenza?


11

Abbiamo una configurazione MySQL master e slave vanilla che risiede in diversi data center e un altro slave nello stesso datacenter del master.

La larghezza di banda tra il datacenter è piuttosto elevata (nei benchmark di rete che abbiamo fatto possiamo raggiungere i 15 MB / secondo), ma esiste la latenza, è di circa 28 ms. Non è elevato in alcun modo, ma è molto più elevato della latenza dei secondi secondari nello stesso centro dati.

Occasionalmente, si verificano gravi ritardi (2000 secondi e più) con lo slave di rimozione, mentre lo slave locale rimane aggiornato. Quando si osserva lo slave remoto in ritardo, il thread SQL di solito trascorre il tempo in attesa che il thread IO aggiorni il registro di inoltro. Il master mostra "in attesa di rete" o qualcosa del genere allo stesso tempo.

Quindi significa che è una rete, ma abbiamo ancora larghezza di banda libera nel momento in cui ciò accade.

La mia domanda è : la latenza tra i datacenter può influire sulle prestazioni della replica? Il thread io slave esegue semplicemente lo streaming degli eventi fino a quando il master non smette di inviarli o sta in qualche modo raggruppando il master tra gli eventi?


2000 secondi? Quindi, un ritardo di 33 minuti?
Richard,

Sì ... Va su e giù per tutto il giorno.
shlomoid,

2
+1 perché adoro questo tipo di domande in questo sito. Per favore, fai sapere agli altri di venire su questo sito con domande di questo tipo !!!
RolandoMySQLDBA il

Risposte:


7

La risposta diretta alla tua domanda è Sì, ma dipende dalla versione di MySQL che stai utilizzando. Prima di MySQL 5.5, la replica funzionava come segue:

  • Master esegue SQL
  • Master Records Evento SQL nei suoi registri binari
  • Lo slave legge l'evento SQL dai registri binari principali
  • Lo slave memorizza l'evento SQL nei registri di inoltro tramite thread I / O
  • Lo slave legge il prossimo evento SQL dal registro di inoltro tramite thread SQL
  • Lo slave esegue SQL
  • Lo slave riconosce il Master dell'esecuzione completa dell'evento SQL

A partire da MySQL 5.5, utilizzando la replica semisincrona , ora la replica funzionerebbe come segue:

  • Master esegue SQL
  • Master Records Evento SQL nei suoi registri binari
  • Lo slave legge l'evento SQL dai registri binari principali
  • Lo slave riconosce il master della ricevuta dell'evento SQL
  • Lo slave memorizza l'evento SQL nei registri di inoltro tramite thread I / O
  • Lo slave legge il prossimo evento SQL dal registro di inoltro tramite thread SQL
  • Lo slave esegue SQL
  • Lo slave riconosce il Master dell'esecuzione completa dell'evento SQL

Questo nuovo paradigma consentirà a uno Slave di essere più vicino al suo Maestro.

Ciononostante, la latenza all'interno della rete potrebbe ostacolare la replica semisincrona di MySQL al punto in cui ritorna alla replica asincrona di vecchio stile. Perché ? Se si verifica un timeout senza che uno slave abbia riconosciuto la transazione, il master torna alla replica asincrona. Quando almeno uno slave semisincrono raggiunge, il master torna alla replica semisincrona.

AGGIORNAMENTO 2011-08-08 14:22 EDT

La configurazione della replica semisincrona di MySQL 5.5 è semplice

Passaggio 1) Aggiungi queste quattro (4) righe a /etc/my.cnf

[mysqld]
plugin-dir=/usr/lib64/mysql/plugin
#rpl_semi_sync_master_enabled
#rpl_semi_sync_master_timeout=5000
#rpl_semi_sync_slave_enabled

Passaggio 2) Riavvia MySQL

service mysql restart

Passaggio 3) Eseguire questi comandi nel client MySQL

INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
INSTALL PLUGIN rpl_semi_sync_slave  SONAME 'semisync_slave.so';

Passaggio 4: decomprimere le tre opzioni rpm_semi_sync dopo l'opzione plugin-dir

[mysqld]
plugin-dir=/usr/lib64/mysql/plugin
rpl_semi_sync_master_enabled
rpl_semi_sync_master_timeout=5000
rpl_semi_sync_slave_enabled

Passaggio 5) Riavvia MySQL

service mysql restart

Tutto fatto !!! Ora installa MySQL Replication come al solito.


Non sono sicuro dell'ultimo stadio della replica asincrona - non credo che il master sappia fino a che punto è arrivato ogni schiavo. Possono chiedere qualsiasi parte del registro binario che desiderano, per quanto ne so - hai qualche riferimento per questo?
shlomoid,

Inoltre, stiamo usando la replica asincrona predefinita in MySQL, non il tipo asincrono - che deve essere abilitato appositamente installando plugin e simili. Quello che sto cercando di capire è se gli eventi vengono convogliati nello stile net-cat nello slave dalla posizione iniziale nel registro o se vi è uno scambio avanti e indietro tra il master e lo slave per ciascun evento, che potrebbe soffrire di tale latenza.
shlomoid,

Consiglio vivamente l'utilizzo di MySQL 5.5 per sfruttare questa nuova forma di replica MySQL e i miglioramenti di InnoDB.
RolandoMySQLDBA il

1
Sì, ovviamente stiamo usando MySQL 5.5, ma questo non è il tipo di replica predefinito. È necessario passare attraverso un'intera procedura di configurazione, installare plugin e simili, per farlo funzionare in modo semi-sincrono.
shlomoid,

2

Mi piace molto il modo in cui Rolando ha descritto la sequenza di operazioni eseguite da una replica. Tuttavia, penso che sarebbe più chiaro se aggiungessimo un altro componente - client.

Con il client la sequenza di operazioni per la replica asincrona potrebbe essere la seguente:

  1. Il client invia al master la query SQL (ad esempio, inserisci) utilizzando le transazioni

  2. Il Master esegue la transazione. In caso di successo, il record viene archiviato sul disco, ma la transazione non è stata ancora impegnata.

  3. Il master registra l'evento di inserimento nel registro binario principale Se il master non è riuscito a memorizzarlo nel registro binario, la transazione viene ripristinata.

  4. Il client riceve la risposta dal master (esito positivo o rollback).

  5. In caso di esito positivo della transazione, il thread di dump sul master legge l'evento dal registro binario e lo invia al thread I / O slave.

  6. Il thread I / O slave riceve l'evento e lo scrive alla fine del file di registro di inoltro.

  7. Una volta che l'evento è entrato nel registro di inoltro, il thread SQL slave esegue
    l'evento per applicare le modifiche al database sullo slave.

In questo scenario, il master non si preoccupa dello slave e il client sa solo che c'è qualcosa di sbagliato nello slave eseguendo manualmente il comando "SHOW SLAVE STATUS".

Nel caso di una replica semi-sincrona la sequenza delle operazioni potrebbe essere la seguente:

  1. Il client invia al master la query SQL (ad esempio, inserisci) utilizzando le transazioni.

  2. Il Master esegue la transazione. In caso di successo, il record viene archiviato sul disco, ma la transazione non viene impegnata.

  3. Il master registra l'evento di inserimento nel registro binario principale Se il master non è in grado di memorizzarlo nel registro binario, la transazione viene ripristinata e il client riceve la risposta solo in caso di rollback.

  4. A causa del successo della transazione sul master, il thread di dump sul master legge l'evento dal registro binario e lo invia al thread I / O slave.

  5. Il thread I / O slave riceve l'evento e lo scrive alla fine del file di registro di inoltro.

  6. Lo slave riconosce il master della registrazione dell'evento nel file di registro di inoltro.

  7. Il master esegue la transazione di inserimento.

  8. Il client riceve la risposta dal master (esito positivo).

  9. Una volta che l'evento è entrato nel registro di inoltro, il thread SQL slave esegue
    l'evento. Master e client non sanno se l'esecuzione è andata a buon fine o meno.

La replica semi-sincrona risolse un caso importante quando lo slave o la rete morivano e il master continuava a procedere. Quindi il master muore e vuoi riavviare il vecchio slave come nuovo master solo perché hai corretto quel nodo.

Quindi hai iniziato quel nodo come nuovo master, hai riparato il vecchio master e ora vuoi usarlo come slave. Quel nodo ha ancora i dati, ma se il nuovo slave inizia dalla posizione in cui è stato avviato il nuovo master ci saranno record duplicati.

Se il periodo di attesa è infinito, la posizione del registro binario principale sarà sempre sincronizzata con la posizione del registro del relè slave presupponendo che tutte le query sullo slave abbiano avuto esito positivo. Quanto è realistico questo assunto?

Penso che sia molto realistico. Uno dei casi più comuni di errore della query slave è "record duplicato". Dove il record duplicato è arrivato allo slave se il master non lo aveva? Veniva da una posizione errata data allo slave per iniziare a replicare. La posizione di replica iniziale includeva il record che era già stato replicato. In caso di replica semi-sincrona questa situazione non si verificherà.

Jacob Nikom


1

Qualificatore : non sono un utente MySQL, quindi principalmente, questa è solo la mia ricerca su Internet.

Come sicuramente saprai, la più grande limitazione della replica di MySQL è che è a thread singolo. Pertanto, mentre il thread è impegnato a inviare dati allo slave interno, non sarà in grado di inviare dati allo slave remoto. Questo è per qui .


Per qui :

Una cosa che devi assicurarti di fare è ridurre i tempi di transazione. Ciò consente al thread di replica di avere l'opportunità di recuperare il ritardo con ciò che accade nel database. Vuoi che le tue transazioni siano le più brevi possibili.

Un modo per farlo è attraverso l'interruzione di query; limitare le righe modificate da UPDATE o DELETE mediante l'uso delle clausole WHERE. Se lo inserisci in un ciclo, puoi scorrere l'elenco, avviando e eseguendo ogni volta la transazione. (AGGIORNA / ELIMINA il primo terzo, il secondo terzo, quindi l'ultimo terzo ciascuno nella propria transazione.) Personalmente sconsiglio fortemente di farlo perché ti apri alla possibilità che i dati nella tabella cambino tra le transazioni. Tuttavia, è possibile migliorare queste prestazioni se si è sicuri che nessun altro stia scherzando con la tabella (e non lo farà mai) .

Un'altra possibilità è non replicare quelle transazioni a lungo termine, ma piuttosto eseguirle su entrambi i master (che si replicano sullo slave locale) e quindi eseguirle sullo slave remoto separatamente. Ciò libererebbe il thread di replica in modo che non si impantanasse fino al segno di oltre 30 minuti.


Per qui :

Un'ultima possibilità sarebbe quella di ottimizzare le dimensioni dei buffer TCP. L'obiettivo è ridurre il numero di comunicazioni che stai effettuando tra master e slave. Questo potrebbe aiutare a ridurre la latenza.

Personalmente, proverei questo se tutto il resto fallisce. Sospetto che il problema sia più causato dal sistema di replica a thread singolo anziché da una latenza di rete. Le reti normalmente scaderebbero molto prima dei 30 minuti. (30 minuti?!)


I segnalibri Delicious di JHammerb hanno diversi collegamenti per la replica mysql che potresti voler controllare anche.

Spero che aiuti.


1
Ottieni un +1 per menzionare come MySQL Replication è a thread singolo, ma devo qualificare la tua dichiarazione come segue: MySQL Replication è a doppio thread utilizzando un thread I / O per il download di eventi SQL da master a slave e un thread SQL per l'elaborazione gli eventi SQL localmente sullo slave. Tuttavia, la trasmissione degli eventi SQL è a thread singolo, che è contestualmente corretta per questa domanda.
RolandoMySQLDBA il

2
BTW Non utilizzare LIMIT con le istruzioni UPDATE e DELETE perché l'ordine delle righe da aggiornare o eliminare potrebbe non essere lo stesso sullo Slave come sul Master. In effetti, i messaggi di avvertimento in proposito appaiono come "Dichiarazione non sicura per BinLog" nel registro degli errori.
RolandoMySQLDBA il

Ooh, buon punto per non usare LIMIT con UPDATE e DELETE. Modificherò la mia risposta per rimuoverla.
Richard,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.