MariaDB
 sql >> Database >  >> RDS >> MariaDB

Gestione di grandi transazioni con Streaming Replication e MariaDB 10.4

Gestire grandi transazioni è sempre stato un punto dolente in Galera Cluster. Il modo in cui funziona la certificazione del set di scrittura Galera causa problemi quando le transazioni sono lunghe o quando una singola riga viene modificata spesso su più nodi. Di conseguenza, le transazioni devono essere annullate e riprovate causando cali di prestazioni. Fortunatamente, questo problema è stato risolto in Galera 4, una nuova versione di Galera di Codership. Questa libreria è utilizzata in MariaDB 10.4, quindi l'installazione di MariaDB 10.4 è il modo più semplice per testare le funzionalità appena introdotte. In questo post del blog daremo un'occhiata a come la replica in streaming può essere utilizzata per mitigare i problemi che erano un problema standard nelle versioni precedenti di Galera.

Utilizzeremo tre nodi del cluster MariaDB Galera versione 10.4.6, che viene fornito con la versione Galera di 26.4.2.

MariaDB [(none)]> show global status like 'wsrep_provider%';
+-----------------------------+------------------------------------------------------------------------------------------------------------------------------------------------+
| Variable_name               | Value                                                                                                                                          |
+-----------------------------+------------------------------------------------------------------------------------------------------------------------------------------------+
| wsrep_provider_capabilities | :MULTI_MASTER:CERTIFICATION:PARALLEL_APPLYING:TRX_REPLAY:ISOLATION:PAUSE:CAUSAL_READS:INCREMENTAL_WRITESET:UNORDERED:PREORDERED:STREAMING:NBO: |
| wsrep_provider_name         | Galera                                                                                                                                         |
| wsrep_provider_vendor       | Codership Oy <[email protected]>                                                                                                              |
| wsrep_provider_version      | 26.4.2(r4498)                                                                                                                                  |
+-----------------------------+------------------------------------------------------------------------------------------------------------------------------------------------+
4 rows in set (0.001 sec)

Ci sono tre principali punti deboli che la replica in streaming deve affrontare:

  • Transazioni lunghe
  • Grandi transazioni
  • Punti caldi nelle tabelle

Esaminiamoli uno per uno e vediamo come la replica in streaming può aiutarci a gestirli, ma prima concentriamoci sulla certificazione del set di scrittura, la causa principale di questi problemi.

Certificazione Writeset nel Cluster Galera

Il cluster Galera è costituito da più nodi scrivibili. Ogni transazione eseguita sul cluster Galera forma un writeset. Ogni writeset deve essere inviato a tutti i nodi del cluster per la certificazione, un processo che garantisce che tutti i nodi possano applicare una determinata transazione. I set di scrittura devono essere eseguiti su tutti i nodi del cluster, quindi in caso di conflitto non è possibile eseguire il commit della transazione. Quali sono i motivi tipici per cui non è possibile eseguire il commit della transazione? Bene, i tre punti che abbiamo elencato prima:

  • Transazioni lunghe:più tempo impiega la transazione, è più probabile che nel frattempo un altro nodo esegua aggiornamenti che alla fine andranno in conflitto con il writeset e impediranno di superare la certificazione
  • Grandi transazioni:prima di tutto, le transazioni grandi sono anche più lunghe di quelle piccole, quindi questo fa scattare il primo problema. Il secondo problema, strettamente correlato alle grandi transazioni, è il volume delle modifiche. Verranno aggiornate più righe, è più probabile che alcune scritture su un altro nodo provochino un conflitto e sia necessario eseguire il rollback dell'intera transazione.
  • Punti caldi nelle tabelle:è più probabile che una determinata riga debba essere aggiornata, più probabilmente tale aggiornamento avverrà contemporaneamente su più nodi con conseguente rollback di alcune transazioni

Il problema principale qui è che Galera non introduce alcun blocco sui nodi diversi dal nodo iniziale, su cui è stata aperta la transazione. Il processo di certificazione si basa sulla speranza che se un nodo potrebbe eseguire una transazione, anche altri dovrebbero essere in grado di farlo. È vero, ma, come abbiamo visto, ci sono casi limite in cui la probabilità che ciò accada è notevolmente ridotta.

In Galera 4, con la replica in streaming, il comportamento è cambiato e tutti i blocchi vengono presi in tutti i nodi. Le transazioni saranno suddivise in parti e ciascuna parte sarà certificata su tutti i nodi. Una volta completata la certificazione, le righe verranno bloccate su tutti i nodi del cluster. Ci sono un paio di variabili che governano come esattamente questo viene fatto:wsrep_trx_fragment_size e wsrep_trx_fragment_unit definiscono quanto grande dovrebbe essere il frammento e come dovrebbe essere definito. È un controllo molto fine:puoi definire unità di frammento come byte, istruzioni o righe che rendono possibile eseguire la certificazione per ogni riga modificata nella transazione. Diamo un'occhiata a come puoi trarre vantaggio dalla replica in streaming nella vita reale.

Utilizzo della replica in streaming

Consideriamo il seguente scenario. Abbiamo una transazione da eseguire che richiede almeno 30 secondi:

BEGIN; UPDATE sbtest.sbtest1 SET k = k - 2 WHERE id < 2000 ; UPDATE sbtest.sbtest1 SET k = k + 1 WHERE id < 2000 ; UPDATE sbtest.sbtest1 SET k = k + 1 WHERE id < 2000 ; SELECT SLEEP(30); COMMIT;

Quindi, mentre è in esecuzione, eseguiremo SQL che tocca righe simili. Questo verrà eseguito su un altro nodo:

BEGIN; UPDATE sbtest.sbtest1 SET k = k - 1 WHERE id < 20 ; UPDATE sbtest.sbtest1 SET k = k + 1 WHERE id < 20 ; COMMIT;

Quale sarebbe il risultato?

La prima transazione viene annullata non appena viene eseguita la seconda:

MariaDB [sbtest]> BEGIN; UPDATE sbtest.sbtest1 SET k = k - 2 WHERE id < 2000 ; UPDATE sbtest.sbtest1 SET k = k + 1 WHERE id < 2000 ; UPDATE sbtest.sbtest1 SET k = k + 1 WHERE id < 2000 ; SELECT SLEEP(30); COMMIT;
Query OK, 0 rows affected (0.001 sec)

Query OK, 667 rows affected (0.020 sec)
Rows matched: 667  Changed: 667  Warnings: 0

Query OK, 667 rows affected (0.010 sec)
Rows matched: 667  Changed: 667  Warnings: 0

Query OK, 667 rows affected (0.009 sec)
Rows matched: 667  Changed: 667  Warnings: 0

ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction
Query OK, 0 rows affected (0.001 sec)

La transazione sul secondo nodo è riuscita:

MariaDB [(none)]> BEGIN; UPDATE sbtest.sbtest1 SET k = k - 1 WHERE id < 20 ; UPDATE sbtest.sbtest1 SET k = k + 1 WHERE id < 20 ; COMMIT;
Query OK, 0 rows affected (0.000 sec)

Query OK, 7 rows affected (0.002 sec)
Rows matched: 7  Changed: 7  Warnings: 0

Query OK, 7 rows affected (0.001 sec)
Rows matched: 7  Changed: 7  Warnings: 0

Query OK, 0 rows affected (0.004 sec)

Quello che possiamo fare per evitarlo è utilizzare la replica in streaming per la prima transazione. Chiederemo a Galera di certificare ogni cambio di riga:

MariaDB [sbtest]> BEGIN; SET SESSION wsrep_trx_fragment_size=1 ; SET SESSION wsrep_trx_fragment_unit='rows' ; UPDATE sbtest.sbtest1 SET k = k - 2 WHERE id < 2000 ; UPDATE sbtest.sbtest1 SET k = k + 1 WHERE id < 2000 ; UPDATE sbtest.sbtest1 SET k = k + 1 WHERE id < 2000 ; SELECT SLEEP(30); COMMIT; SET SESSION wsrep_trx_fragment_size=0;
Query OK, 0 rows affected (0.001 sec)

Query OK, 0 rows affected (0.000 sec)

Query OK, 0 rows affected (0.000 sec)

Query OK, 667 rows affected (1.757 sec)
Rows matched: 667  Changed: 667  Warnings: 0

Query OK, 667 rows affected (1.708 sec)
Rows matched: 667  Changed: 667  Warnings: 0

Query OK, 667 rows affected (1.685 sec)
Rows matched: 667  Changed: 667  Warnings: 0

Come puoi vedere, questa volta ha funzionato bene. Sul secondo nodo:

MariaDB [(none)]> BEGIN; UPDATE sbtest.sbtest1 SET k = k - 1 WHERE id < 20 ; UPDATE sbtest.sbtest1 SET k = k + 1 WHERE id < 20 ; COMMIT;
Query OK, 0 rows affected (0.000 sec)

Query OK, 7 rows affected (33.942 sec)
Rows matched: 7  Changed: 7  Warnings: 0

Query OK, 7 rows affected (0.001 sec)
Rows matched: 7  Changed: 7  Warnings: 0

Query OK, 0 rows affected (0.026 sec)

Ciò che è interessante, puoi vedere che l'UPDATE ha richiesto quasi 34 secondi per essere eseguito - ciò è stato causato dal fatto che la transazione iniziale, tramite la replica in streaming, ha bloccato tutte le righe modificate su tutti i nodi e la nostra seconda transazione ha dovuto attendere il primo a completare anche se entrambe le transazioni sono state eseguite su nodi diversi.

Questo è fondamentalmente quando si tratta della replica in streaming. A seconda dei requisiti e del traffico, puoi utilizzarlo in modo meno rigoroso:abbiamo certificato ogni riga ma puoi cambiarlo in ogni riga n-esima o in ogni istruzione. Puoi anche decidere il volume di dati da certificare. Questo dovrebbe essere sufficiente per soddisfare i requisiti del tuo ambiente.

Ci sono ancora un paio di cose che vorremmo che tu tenessi a mente e ricordassi. Innanzitutto, la replica in streaming non è affatto una soluzione da utilizzare per impostazione predefinita. Questo è il motivo per cui è, per impostazione predefinita, disabilitato. Il caso d'uso consigliato consiste nel decidere manualmente le transazioni che potrebbero trarre vantaggio dalla replica in streaming e abilitarla a livello di sessione. Questo è il motivo per cui i nostri esempi terminano con:

SET SESSION wsrep_trx_fragment_size=0;

Questa istruzione (impostando wsrep_trx_fragment_size su 0) disabilita la replica in streaming per la sessione corrente.

Un'altra cosa che vale la pena ricordare:se ti capita di utilizzare la replica in streaming, utilizzerà la tabella "wsrep_streaming_log" nello schema "mysql" per archiviare in modo persistente i dati in streaming. Utilizzando questa tabella puoi avere un'idea dei dati che vengono trasferiti attraverso il cluster utilizzando la replica in streaming.

Infine, la performance. Questo è anche uno dei motivi per cui non si desidera utilizzare sempre la replica in streaming. Il motivo principale è il blocco:con la replica in streaming è necessario acquisire blocchi di riga su tutti i nodi. Questo richiede tempo per ottenere i blocchi e, se devi eseguire il rollback della transazione, eserciterà anche la pressione su tutti i nodi per eseguire il rollback. Abbiamo eseguito un test molto rapido dell'impatto sulle prestazioni della replica in streaming. L'ambiente è strettamente di prova, quindi non dare per scontato che i risultati siano gli stessi sull'hardware di livello produttivo, sta a te vedere quale potrebbe essere l'impatto.

Abbiamo testato quattro scenari:

  1. Linea di base, imposta wsrep_trx_fragment_size=0 globale;
  2. imposta globale wsrep_trx_fragment_unit='righe'; imposta wsrep_trx_fragment_size=1 globale;
  3. imposta globale wsrep_trx_fragment_unit='dichiarazioni'; imposta wsrep_trx_fragment_size=1 globale;
  4. imposta globale wsrep_trx_fragment_unit='dichiarazioni'; imposta wsrep_trx_fragment_size=5 globale;

Abbiamo usato sysbench r/w test:

sysbench /root/sysbench/src/lua/oltp_read_write.lua --threads=4 --events=0 --time=300 --mysql-host=10.0.0.141 --mysql-user=sbtest --mysql-password=sbtest --mysql-port=3306 --tables=32 --report-interval=1 --skip-trx=off --table-size=100000 --db-ps-mode=disable run

I risultati sono:

  1. Transazioni:82,91 al secondo, query:1658,27 al secondo. (100%)
  2. Transazioni:54,72 al secondo, query:1094,43 al secondo. (66%)
  3. Transazioni:54,76 al secondo, query:1095,18 al secondo. (66%)
  4. Transazioni:70,93 al secondo, query:1418,55 al secondo. (86%)

Come puoi vedere, l'impatto è notevole, le prestazioni scendono addirittura del 33%.

Ci auguriamo che tu abbia trovato questo post del blog informativo e che ti abbia fornito alcune informazioni sulla replica in streaming fornita con Galera 4 e MariaDB 10.4. Abbiamo cercato di coprire casi d'uso e potenziali svantaggi legati a questa nuova tecnologia.