Per tutti coloro che non hanno familiarità con Vitess, si tratta di un sistema di database basato su MySQL che ha lo scopo di fornire un sistema di gestione di database relazionale, suddiviso in partizioni e di facile scalabilità. Non entreremo nei dettagli sulla progettazione ma, in breve, Vitess è costituito da nodi proxy che instradano le richieste, gateway che gestiscono i nodi del database e, infine, gli stessi nodi del database MySQL, che hanno lo scopo di archiviare i dati. Se stiamo parlando di MySQL, si potrebbe pensare se esiste un'opzione per, effettivamente, utilizzare strumenti esterni come, ad esempio, ClusterControl per gestire quei database sottostanti. La risposta breve è "sì". La risposta più lunga sarà questo post del blog.
MySQL in Vitess
Prima di tutto, vogliamo dedicare un po' di tempo a parlare di come Vitess utilizza MySQL. L'architettura di alto livello è descritta nella pagina della documentazione di Vitess. In breve, abbiamo VTGate che funge da proxy, abbiamo un Topology Service che è un archivio di metadati basato su Zookeeper, Consul o Etcd, dove si trovano tutte le informazioni sui nodi nel sistema, infine abbiamo VTTablets, che agiscono come intermediario tra VTGate e l'istanza MySQL. Le istanze MySQL possono essere autonome oppure possono essere configurate utilizzando la replica asincrona (o semisincrona) standard. MySQL viene utilizzato per memorizzare i dati. I dati possono essere suddivisi in frammenti, in tal caso un'istanza MySQL conterrà un sottoinsieme di dati.
Tutto questo funziona alla grande. Vitess è in grado di determinare quale nodo è il master, quali nodi sono slave, instradando le query di conseguenza. Ci sono diversi problemi, però. Non tutte le funzionalità di base sono fornite da Vitess. Rilevamento della topologia e instradamento delle query, sì. Backup:sì, anche Vitess può essere configurato per eseguire backup dei dati e consentire agli utenti di ripristinare tutto ciò di cui è stato eseguito il backup. Sfortunatamente, non esiste un supporto interno per il failover automatico. Non esiste un'interfaccia utente di tendenza adeguata che possa aiutare gli utenti a comprendere lo stato dei database e il loro carico di lavoro. Fortunatamente, poiché stiamo parlando di MySQL standard, possiamo facilmente utilizzare soluzioni esterne per ottenere questo risultato. Ad esempio, per il failover, Vitess può essere integrato con Orchestrator. Diamo un'occhiata a come ClusterControl può essere utilizzato insieme a Vitess per fornire gestione, monitoraggio e failover.
Distribuzione di un nuovo cluster di database utilizzando ClusterControl
Prima di tutto, distribuiamo un nuovo cluster. Come al solito con ClusterControl, devi effettuare il provisioning dell'hardware e assicurarti che ClusterControl possa accedere a quei nodi utilizzando SSH.
Per prima cosa, dobbiamo definire la connettività SSH.
Successivamente, sceglieremo il fornitore e la versione. Secondo la documentazione, Vitess supporta MySQL e Percona Server nelle versioni 5.7 e 8.0 (sebbene non supporti il metodo caching_sha2_password quindi bisogna fare attenzione durante la creazione degli utenti). Supporta anche MariaDB fino a 10.3.
Infine, definiamo la topologia. Dopo aver fatto clic su "Distribuisci", ClusterControl eseguirà la distribuzione del cluster.
Una volta pronto, dovresti vedere il cluster e dovresti essere in grado di gestirlo utilizzando ClusterControl. Se il ripristino automatico per cluster e nodi è abilitato, ClusterControl eseguirà failover automatici se necessario.
Trarrai vantaggio anche dal monitoraggio basato sugli agenti nella sezione "Dashboard" dell'interfaccia utente di ClusterControl.
Importazione del cluster in Vitess
Come passaggio successivo dovremmo avere Vitess schierato. Ciò che descriviamo qui non è affatto una configurazione di livello produttivo, quindi taglieremo alcuni angoli e implementeremo semplicemente la suite Vitess su un singolo nodo seguendo il tutorial dalla documentazione di Vitess. Per semplificare la gestione, andremo con la guida all'installazione locale, che distribuirà tutti i servizi, insieme a database di esempio su un singolo nodo. Rendilo abbastanza grande da accoglierli. A scopo di test dovrebbe essere sufficiente un nodo con un paio di core CPU e 4 GB di memoria.
Supponiamo che tutto sia andato bene e che tu abbia una distribuzione Vitess locale in esecuzione sul nodo. Il prossimo passo sarà importare il nostro cluster distribuito da ClusterControl in Vitess. Per questo dobbiamo eseguire altri due VTTablet. Per prima cosa, creeremo directory per quei tablet VTT:
[email protected]:~$ cd /home/vagrant/my-vitess-example/
[email protected]:~/my-vitess-example$ source env.sh
[email protected]:~/my-vitess-example$ mkdir $VTDATAROOT/vt_0000000401
[email protected]:~/my-vitess-example$ mkdir $VTDATAROOT/vt_0000000402
Quindi, sul database, creeremo un utente che verrà utilizzato da Vitess per connettersi e gestire il database.
mysql> CREATE USER [email protected]'%' IDENTIFIED BY 'pass';
Query OK, 0 rows affected (0.01 sec)
mysql> GRANT ALL ON *.* TO [email protected]'%' WITH GRANT OPTION;
Query OK, 0 rows affected (0.01 sec)
Se vogliamo, potremmo anche voler creare più utenti. Vitess ci consente di passare un paio di utenti con privilegi di accesso diversi:utente dell'applicazione, utente DBA, utente di replica, utente con privilegi completi e un paio di altri.
L'ultima cosa che dobbiamo fare è disabilitare super_read_only su tutti MySQL nodi poiché Vitess tenterà di creare metadati sulla replica, risultando in un tentativo fallito di avviare il servizio vttablet.
Una volta fatto, dovremmo avviare VTTablets. In entrambi i casi dobbiamo assicurarci che le porte siano univoche e di passare le credenziali corrette per accedere all'istanza del database:
vttablet $TOPOLOGY_FLAGS -logtostderr -log_queries_to_file $VTDATAROOT/tmp/vttablet_0000000401_querylog.txt -tablet-path "zone1-0000000401" -init_keyspace clustercontrol -init_shard 0 -init_tablet_type replica -port 15401 -grpc_port 16401 -service_map 'grpc-queryservice,grpc-tabletmanager,grpc-updatestream' -pid_file $VTDATAROOT/vt_0000000401/vttablet.pid -vtctld_addr http://localhost:15000/ -db_host 10.0.0.181 -db_port 3306 -db_app_user vtuser -db_app_password pass -db_dba_user vtuser -db_dba_password pass -db_repl_user vtuser -db_repl_password pass -db_filtered_user vtuser -db_filtered_password pass -db_allprivs_user vtuser -db_allprivs_password pass -init_db_name_override clustercontrol -init_populate_metadata &
vttablet $TOPOLOGY_FLAGS -logtostderr -log_queries_to_file $VTDATAROOT/tmp/vttablet_0000000402_querylog.txt -tablet-path "zone1-0000000402" -init_keyspace clustercontrol -init_shard 0 -init_tablet_type replica -port 15402 -grpc_port 16402 -service_map 'grpc-queryservice,grpc-tabletmanager,grpc-updatestream' -pid_file $VTDATAROOT/vt_0000000402/vttablet.pid -vtctld_addr http://localhost:15000/ -db_host 10.0.0.182 -db_port 3306 -db_app_user vtuser -db_app_password pass -db_dba_user vtuser -db_dba_password pass -db_repl_user vtuser -db_repl_password pass -db_filtered_user vtuser -db_filtered_password pass -db_allprivs_user vtuser -db_allprivs_password pass -init_db_name_override clustercontrol -init_populate_metadata &
Una volta pronto, possiamo controllare come Vitess vede i nuovi VTTablet:
[email protected]:~/my-vitess-example$ mysql
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 10
Server version: 5.7.9-vitess-10.0.2 Version: 10.0.2 (Git revision fc78470 branch 'HEAD') built on Thu May 27 08:45:22 UTC 2021 by [email protected] using go1.15.12 linux/amd64
Copyright (c) 2000, 2021, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> SHOW vitess_tablets;
+-------+----------------+-------+------------+---------+------------------+------------+----------------------+
| Cell | Keyspace | Shard | TabletType | State | Alias | Hostname | MasterTermStartTime |
+-------+----------------+-------+------------+---------+------------------+------------+----------------------+
| zone1 | clustercontrol | 0 | REPLICA | SERVING | zone1-0000000401 | vagrant.vm | |
| zone1 | clustercontrol | 0 | REPLICA | SERVING | zone1-0000000402 | vagrant.vm | |
| zone1 | commerce | 0 | MASTER | SERVING | zone1-0000000100 | vagrant.vm | 2021-07-08T13:12:21Z |
| zone1 | commerce | 0 | REPLICA | SERVING | zone1-0000000101 | vagrant.vm | |
| zone1 | commerce | 0 | RDONLY | SERVING | zone1-0000000102 | vagrant.vm | |
+-------+----------------+-------+------------+---------+------------------+------------+----------------------+
5 rows in set (0.00 sec)
I nodi sono presenti ma entrambi sono riportati come repliche da Vitess. Ora possiamo attivare Vitess per controllare la topologia per il nostro vero master (nodo che abbiamo importato con ID 401)
[email protected]:~/my-vitess-example$ vtctlclient TabletExternallyReparented zone1-401
Ora tutto sembra corretto:
mysql> SHOW vitess_tablets;
+-------+----------------+-------+------------+---------+------------------+------------+----------------------+
| Cell | Keyspace | Shard | TabletType | State | Alias | Hostname | MasterTermStartTime |
+-------+----------------+-------+------------+---------+------------------+------------+----------------------+
| zone1 | clustercontrol | 0 | MASTER | SERVING | zone1-0000000401 | vagrant.vm | 2021-07-08T13:27:34Z |
| zone1 | clustercontrol | 0 | REPLICA | SERVING | zone1-0000000402 | vagrant.vm | |
| zone1 | commerce | 0 | MASTER | SERVING | zone1-0000000100 | vagrant.vm | 2021-07-08T13:12:21Z |
| zone1 | commerce | 0 | REPLICA | SERVING | zone1-0000000101 | vagrant.vm | |
| zone1 | commerce | 0 | RDONLY | SERVING | zone1-0000000102 | vagrant.vm | |
+-------+----------------+-------+------------+---------+------------------+------------+----------------------+
5 rows in set (0.00 sec)
Integrazione del failover automatizzato di ClusterControl in Vitess
L'ultimo bit a cui vogliamo dare un'occhiata è la gestione automatizzata del failover con ClusterControl e vedere come integrarla con Vitess. Sarà abbastanza simile a quello che abbiamo appena visto. Il problema principale da affrontare è che il failover non cambia nulla nel Vitess. La soluzione è quella che abbiamo usato in precedenza, il comando TabletExternallyReparented. L'unica sfida è attivarlo quando si verifica il failover. Fortunatamente, ClusterControl viene fornito con hook che ci consentono di collegarci al processo di failover. Li useremo per eseguire vtctlclient. Tuttavia, deve essere prima installato sull'istanza ClusterControl. Il modo più semplice per farlo è semplicemente copiare il file binario dall'istanza di Vitess a ClusterControl.
Per prima cosa, creiamo la directory sul nodo ClusterControl:
mkdir -r /usr/local/vitess/bin
Quindi, copia il file:
scp /usr/local/vitess/bin/vtctlclient [email protected]:/usr/local/vitess/bin/
Come passaggio successivo, dobbiamo creare uno script che esegua il comando per riparentare gli shard. Useremo replication_post_failover_script e replication_post_switchover_script. Cmon eseguirà lo script con diversi argomenti. Siamo interessati al terzo di essi, conterrà il nome host del candidato master, il nodo che è stato scelto come nuovo master.
Lo script di esempio potrebbe assomigliare a questo.
#!/bin/bash
if [[ $3 == 10.0.0.181 ]] ; then tablet="zone1-401" ; fi
if [[ $3 == 10.0.0.182 ]] ; then tablet="zone1-402" ; fi
vitess="10.0.0.50"
/usr/local/vitess/bin/vtctlclient -server ${vitess}:15999 TabletExternallyReparented ${tablet}
Tieni presente che questo è solo un minimo indispensabile che funziona. Dovresti implementare uno script più dettagliato che eseguirà forse ulteriori controlli di integrità. Invece di codificare i nomi host e tablet, potresti effettivamente interrogare ClusterControl per ottenere l'elenco dei nodi nel cluster, quindi potresti volerlo confrontare con il contenuto del servizio di topologia per vedere quale alias tablet dovrebbe essere utilizzato.
Una volta che siamo pronti con lo script, dovremmo configurarlo per essere eseguito da ClusterControl:
Possiamo testarlo promuovendo manualmente la replica. Lo stato iniziale, visto da Vitess, era:
mysql> SHOW vitess_tablets;
+-------+----------------+-------+------------+---------+------------------+------------+----------------------+
| Cell | Keyspace | Shard | TabletType | State | Alias | Hostname | MasterTermStartTime |
+-------+----------------+-------+------------+---------+------------------+------------+----------------------+
| zone1 | clustercontrol | 0 | MASTER | SERVING | zone1-0000000401 | vagrant.vm | 2021-07-08T13:27:34Z |
| zone1 | clustercontrol | 0 | REPLICA | SERVING | zone1-0000000402 | vagrant.vm | |
| zone1 | commerce | 0 | MASTER | SERVING | zone1-0000000100 | vagrant.vm | 2021-07-08T13:12:21Z |
| zone1 | commerce | 0 | REPLICA | SERVING | zone1-0000000101 | vagrant.vm | |
| zone1 | commerce | 0 | RDONLY | SERVING | zone1-0000000102 | vagrant.vm | |
+-------+----------------+-------+------------+---------+------------------+------------+----------------------+
5 rows in set (0.00 sec)
Siamo interessati allo spazio delle chiavi "clustercontrol". 401 (10.0.0.181) era il master e 402 (10.0.0.182) era la replica.
Possiamo promuovere 10.0.0.182 per diventare un nuovo master. Il lavoro inizia e possiamo vedere che il nostro script è stato eseguito:
Finalmente, il lavoro è completato:
Tutto è andato bene in ClusterControl. Diamo un'occhiata a Vitess:
mysql> SHOW vitess_tablets;
+-------+----------------+-------+------------+---------+------------------+------------+----------------------+
| Cell | Keyspace | Shard | TabletType | State | Alias | Hostname | MasterTermStartTime |
+-------+----------------+-------+------------+---------+------------------+------------+----------------------+
| zone1 | clustercontrol | 0 | MASTER | SERVING | zone1-0000000402 | vagrant.vm | 2021-07-09T13:38:00Z |
| zone1 | clustercontrol | 0 | REPLICA | SERVING | zone1-0000000401 | vagrant.vm | |
| zone1 | commerce | 0 | MASTER | SERVING | zone1-0000000100 | vagrant.vm | 2021-07-08T13:12:21Z |
| zone1 | commerce | 0 | REPLICA | SERVING | zone1-0000000101 | vagrant.vm | |
| zone1 | commerce | 0 | RDONLY | SERVING | zone1-0000000102 | vagrant.vm | |
+-------+----------------+-------+------------+---------+------------------+------------+----------------------+
5 rows in set (0.00 sec)
Come puoi vedere, anche qui va tutto bene. 402 è il nuovo master e 401 è contrassegnato come replica.
Ovviamente, questo è solo un esempio di come puoi trarre vantaggio dalla capacità di ClusterControl di monitorare e gestire i tuoi database MySQL pur essendo in grado di sfruttare la capacità di Vitess di scalare e dividere i dati. Vitess è un ottimo strumento ma manca di un paio di elementi. Fortunatamente, ClusterControl può eseguire il backup in questi casi.