Un livello proxy tra applicazioni e database è generalmente costituito da più nodi proxy per un'elevata disponibilità. Questo non è diverso per ProxySQL. ProxySQL, proprio come altri proxy moderni, può essere utilizzato per creare una logica complessa per l'instradamento delle query. È possibile aggiungere regole di query per inviare query a host particolari, memorizzare nella cache le query, aggiungere e rimuovere server back-end o gestire utenti a cui è consentito connettersi a ProxySQL e MySQL. Tuttavia, numerosi nodi ProxySQL nel livello proxy introducono un altro problema:la sincronizzazione tra istanze distribuite. Qualsiasi regola o altra logica deve essere sincronizzata tra le istanze, per garantire che si comportino allo stesso modo. Anche se non tutti i proxy gestiscono il traffico, funzionano comunque come standby. Nel caso in cui dovessero prendere in carico il lavoro, non vuoi sorprese se l'istanza utilizzata non ha le modifiche alla configurazione più recenti.
È piuttosto ingombrante garantire ciò manualmente, apportare le modifiche manualmente su tutti i nodi. Puoi utilizzare strumenti come Ansible, Chef o Puppet per gestire le configurazioni, ma il processo di sincronizzazione deve essere codificato e testato. ClusterControl può aiutarti qui attraverso un'opzione per sincronizzare le configurazioni tra istanze ProxySQL, ma può anche impostare e gestire gli altri componenti necessari per l'alta disponibilità, ad esempio, IP virtuale. Ma a partire dalla versione 1.4.2, ProxySQL offre un meccanismo nativo di clustering e sincronizzazione della configurazione. In questo post del blog, discuteremo come configurarlo con un mix di azioni intraprese nell'interfaccia di amministrazione della riga di comando di ClusterControl e ProxySQL.
Prima di tutto, diamo un'occhiata a un tipico ambiente di replica distribuito da ClusterControl.
Come puoi vedere dallo screenshot, questa è una configurazione di replica MySQL con tre istanze ProxySQL. L'elevata disponibilità di ProxySQL viene implementata tramite Keepalived e Virtual IP che viene sempre assegnato a uno dei nodi ProxySQL. Ci sono un paio di passaggi che dobbiamo eseguire per configurare il clustering ProxySQL. Innanzitutto, dobbiamo definire quale utente ProxySQL dovrebbe utilizzare per scambiare informazioni tra i nodi. Definiamone uno nuovo in aggiunta all'utente amministrativo esistente:
Successivamente, dobbiamo definire quell'utente nelle impostazioni admin-cluster_password e admin-cluster_username.
Questo è stato fatto su uno solo dei nodi (10.0.0.126). Sincronizziamo questa modifica di configurazione con i restanti nodi ProxySQL.
Come affermato, ClusterControl consente di sincronizzare la configurazione tra i nodi ProxySQL con solo un paio di passaggi. Quando il lavoro ha terminato la sincronizzazione 10.0.0.127 con 10.0.0.126, c'è solo l'ultimo nodo che dobbiamo sincronizzare.
Successivamente, dobbiamo apportare una piccola modifica all'interfaccia della riga di comando amministrativa di ProxySQL, che è generalmente raggiungibile sulla porta 6032. Dobbiamo creare voci nella tabella 'proxysql_servers' che definirebbe i nodi nel nostro cluster ProxySQL.
mysql> INSERT INTO proxysql_servers (hostname) VALUES ('10.0.0.126'), ('10.0.0.127'), ('10.0.0.128');
Query OK, 3 rows affected (0.00 sec)
mysql> LOAD PROXYSQL SERVERS TO RUNTIME;
Query OK, 0 rows affected (0.01 sec)
mysql> SAVE PROXYSQL SERVERS TO DISK;
Query OK, 0 rows affected (0.01 sec)
Dopo aver caricato la modifica in runtime, ProxySQL dovrebbe iniziare a sincronizzare i nodi. Ci sono un paio di posti in cui puoi monitorare lo stato del cluster.
mysql> SELECT * FROM stats_proxysql_servers_checksums;
+------------+------+-------------------+---------+------------+--------------------+------------+------------+------------+
| hostname | port | name | version | epoch | checksum | changed_at | updated_at | diff_check |
+------------+------+-------------------+---------+------------+--------------------+------------+------------+------------+
| 10.0.0.128 | 6032 | admin_variables | 0 | 0 | | 0 | 1539773916 | 0 |
| 10.0.0.128 | 6032 | mysql_query_rules | 2 | 1539772933 | 0x3FEC69A5C9D96848 | 1539773546 | 1539773916 | 0 |
| 10.0.0.128 | 6032 | mysql_servers | 4 | 1539772933 | 0x3659DCF3E53498A0 | 1539773546 | 1539773916 | 0 |
| 10.0.0.128 | 6032 | mysql_users | 2 | 1539772933 | 0xDD5F0BB01235E930 | 1539773546 | 1539773916 | 0 |
| 10.0.0.128 | 6032 | mysql_variables | 0 | 0 | | 0 | 1539773916 | 0 |
| 10.0.0.128 | 6032 | proxysql_servers | 2 | 1539773835 | 0x8EB13E2B48C3FDB0 | 1539773835 | 1539773916 | 0 |
| 10.0.0.127 | 6032 | admin_variables | 0 | 0 | | 0 | 1539773916 | 0 |
| 10.0.0.127 | 6032 | mysql_query_rules | 3 | 1539773719 | 0x3FEC69A5C9D96848 | 1539773546 | 1539773916 | 0 |
| 10.0.0.127 | 6032 | mysql_servers | 5 | 1539773719 | 0x3659DCF3E53498A0 | 1539773546 | 1539773916 | 0 |
| 10.0.0.127 | 6032 | mysql_users | 3 | 1539773719 | 0xDD5F0BB01235E930 | 1539773546 | 1539773916 | 0 |
| 10.0.0.127 | 6032 | mysql_variables | 0 | 0 | | 0 | 1539773916 | 0 |
| 10.0.0.127 | 6032 | proxysql_servers | 2 | 1539773812 | 0x8EB13E2B48C3FDB0 | 1539773813 | 1539773916 | 0 |
| 10.0.0.126 | 6032 | admin_variables | 0 | 0 | | 0 | 1539773916 | 0 |
| 10.0.0.126 | 6032 | mysql_query_rules | 1 | 1539770578 | 0x3FEC69A5C9D96848 | 1539773546 | 1539773916 | 0 |
| 10.0.0.126 | 6032 | mysql_servers | 3 | 1539771053 | 0x3659DCF3E53498A0 | 1539773546 | 1539773916 | 0 |
| 10.0.0.126 | 6032 | mysql_users | 1 | 1539770578 | 0xDD5F0BB01235E930 | 1539773546 | 1539773916 | 0 |
| 10.0.0.126 | 6032 | mysql_variables | 0 | 0 | | 0 | 1539773916 | 0 |
| 10.0.0.126 | 6032 | proxysql_servers | 2 | 1539773546 | 0x8EB13E2B48C3FDB0 | 1539773546 | 1539773916 | 0 |
+------------+------+-------------------+---------+------------+--------------------+------------+------------+------------+
18 rows in set (0.00 sec)
La tabella stats_proxysql_servers_checksums contiene, tra gli altri, un elenco di nodi nel cluster, tabelle sincronizzate, versioni e checksum della tabella. Se il checksum non è in linea, ProxySQL tenterà di ottenere l'ultima versione da un peer del cluster. Informazioni più dettagliate sui contenuti di questa tabella sono disponibili nella documentazione di ProxySQL.
Un'altra fonte di informazioni sul processo è il log di ProxySQL (per impostazione predefinita si trova in /var/lib/proxysql/proxysql.log).
2018-10-17 11:00:25 [INFO] Cluster: detected a new checksum for mysql_query_rules from peer 10.0.0.126:6032, version 2, epoch 1539774025, checksum 0xD615D5416F61AA72 . Not syncing yet …
2018-10-17 11:00:27 [INFO] Cluster: detected a peer 10.0.0.126:6032 with mysql_query_rules version 2, epoch 1539774025, diff_check 3. Own version: 2, epoch: 1539772933. Proceeding with remote sync
2018-10-17 11:00:28 [INFO] Cluster: detected a peer 10.0.0.126:6032 with mysql_query_rules version 2, epoch 1539774025, diff_check 4. Own version: 2, epoch: 1539772933. Proceeding with remote sync
2018-10-17 11:00:28 [INFO] Cluster: detected peer 10.0.0.126:6032 with mysql_query_rules version 2, epoch 1539774025
2018-10-17 11:00:28 [INFO] Cluster: Fetching MySQL Query Rules from peer 10.0.0.126:6032 started
2018-10-17 11:00:28 [INFO] Cluster: Fetching MySQL Query Rules from peer 10.0.0.126:6032 completed
2018-10-17 11:00:28 [INFO] Cluster: Loading to runtime MySQL Query Rules from peer 10.0.0.126:6032
2018-10-17 11:00:28 [INFO] Cluster: Saving to disk MySQL Query Rules from peer 10.0.0.126:6032
Come puoi vedere, qui abbiamo informazioni sul rilevamento di un nuovo checksum e sul processo di sincronizzazione.
Fermiamoci un momento qui e discutiamo di come ProxySQL gestisce gli aggiornamenti di configurazione da più origini. Prima di tutto, ProxySQL tiene traccia dei checksum per rilevare quando una configurazione è stata modificata. Memorizza anche quando è successo:questi dati vengono archiviati come timestamp, quindi hanno una risoluzione di un secondo. ProxySQL ha due variabili che influiscono anche sulla modalità di sincronizzazione delle modifiche.
Cluster_check_interval_ms:determina la frequenza con cui ProxySQL deve verificare le modifiche alla configurazione. Per impostazione predefinita è 1000 ms.
Cluster_mysql_servers_diffs_before_sync - ci dice quante volte un controllo dovrebbe rilevare una modifica alla configurazione prima che venga sincronizzata. L'impostazione predefinita è 3.
Ciò significa che, anche se farai una modifica alla configurazione sullo stesso host, se la farai meno spesso di 4 secondi, i restanti nodi ProxySQL potrebbero non essere in grado di sincronizzarla perché una nuova modifica apparirà prima della precedente era sincronizzato. Significa anche che se apporti modifiche alla configurazione su più istanze ProxySQL, dovresti eseguirle con un'interruzione di almeno 4 secondi tra di loro, altrimenti alcune modifiche andranno perse e, di conseguenza, le configurazioni divergeranno. Ad esempio, aggiungi Server1 su Proxy1 e dopo 2 secondi aggiungi Server2 su Proxy2 . Tutti gli altri proxy rifiuteranno la modifica su Proxy1 perché rileveranno che Proxy2 ha una configurazione più recente. 4 secondi dopo la modifica su Proxy2, tutti i proxy (incluso Proxy1) estrarranno la configurazione da Proxy2.
Poiché la comunicazione all'interno del cluster non è sincrona e se un nodo ProxySQL su cui hai apportato le modifiche non è riuscito, le modifiche potrebbero non essere replicate in tempo. L'approccio migliore consiste nell'apportare la stessa modifica su due nodi ProxySQL. In questo modo, a meno che entrambi non falliscano esattamente nello stesso momento, uno di loro sarà in grado di propagare la nuova configurazione.
Vale anche la pena notare che la topologia del cluster ProxySQL può essere abbastanza flessibile. Nel nostro caso abbiamo tre nodi, tutti hanno tre voci nella tabella proxysql_servers. Tali nodi formano il cluster in cui è possibile scrivere su qualsiasi nodo e le modifiche verranno propagate. Inoltre, è possibile aggiungere nodi esterni che funzionerebbero in modalità "sola lettura", il che significa che sincronizzerebbero solo le modifiche apportate al cluster "core" ma non propagherebbero le modifiche eseguite direttamente su se stessi. Tutto ciò che serve sul nuovo nodo è avere solo i nodi del cluster "core" configurati in proxysql_servers e, di conseguenza, si connetterà a quei nodi e otterrà le modifiche ai dati, ma non verrà interrogato dal resto del cluster per le sue modifiche di configurazione. Questa configurazione potrebbe essere utilizzata per creare una fonte di verità con diversi nodi nel cluster e altri nodi ProxySQL, che ottengono semplicemente la configurazione dal cluster "core" principale.
Oltre a tutto ciò, il cluster ProxySQL supporta il ricongiungimento automatico dei nodi:sincronizzeranno la loro configurazione all'avvio. Può anche essere facilmente ridimensionato aggiungendo più nodi.
Ci auguriamo che questo post del blog ti dia un'idea di come è possibile configurare il cluster ProxySQL. Il cluster ProxySQL sarà trasparente per ClusterControl e non influirà su nessuna delle operazioni che potresti voler eseguire dall'interfaccia utente di ClusterControl.