Et proxy-lag mellem applikationer og databaser vil typisk bestå af flere proxy-noder for høj tilgængelighed. Dette er ikke anderledes for ProxySQL. ProxySQL kan, ligesom andre moderne proxyer, bruges til at bygge kompleks logik til routing forespørgsler. Du kan tilføje forespørgselsregler for at sende forespørgsler til bestemte værter, du kan cache forespørgsler, du kan tilføje og fjerne backend-servere eller administrere brugere, der har tilladelse til at oprette forbindelse til ProxySQL og MySQL. Imidlertid introducerer talrige ProxySQL-noder i proxy-laget et andet problem - synkronisering på tværs af distribuerede forekomster. Alle regler eller anden logik skal synkroniseres på tværs af instanser for at sikre, at de opfører sig på samme måde. Selvom ikke alle proxyerne håndterer trafik, fungerer de stadig som standby. Hvis de skulle overtage arbejdet, ønsker du ikke nogen overraskelser, hvis den anvendte instans ikke har de seneste konfigurationsændringer.
Det er ret besværligt at sikre dette manuelt - at foretage ændringerne manuelt på alle noderne. Du kan bruge værktøjer som Ansible, Chef eller Puppet til at administrere konfigurationer, men synkroniseringsprocessen skal kodes og testes. ClusterControl kan her hjælpe dig gennem en mulighed for at synkronisere konfigurationer mellem ProxySQL-instanser, men den kan også opsætte og administrere de andre komponenter, der kræves for høj tilgængelighed, f.eks. Virtual IP. Men fra version 1.4.2 tilbyder ProxySQL en indbygget klynge- og konfigurationssynkroniseringsmekanisme. I dette blogindlæg vil vi diskutere, hvordan man sætter det op med en blanding af handlinger, der udføres i ClusterControl og ProxySQL kommandolinje admin interface.
Lad os først og fremmest tage et kig på et typisk replikeringsmiljø, der er implementeret af ClusterControl.
Som du kan se på skærmbilledet, er dette en MySQL-replikeringsopsætning med tre ProxySQL-instanser. ProxySQL høj tilgængelighed er implementeret gennem Keepalved og Virtual IP, der altid er tildelt en af ProxySQL noderne. Der er et par trin, vi skal tage for at konfigurere ProxySQL-klynger. Først skal vi definere, hvilken bruger ProxySQL skal bruge til at udveksle information mellem noderne. Lad os definere en ny oven på den eksisterende administrative bruger:
Dernæst skal vi definere denne bruger i indstillingerne admin-cluster_password og admin-cluster_username.
Dette er blevet gjort på kun én af noderne (10.0.0.126). Lad os synkronisere denne konfigurationsændring med de resterende ProxySQL-noder.
Som vi sagde, giver ClusterControl dig mulighed for at synkronisere konfigurationen mellem ProxySQL-noder med blot et par trin. Da jobbet sluttede med at synkronisere 10.0.0.127 med 10.0.0.126, er der kun den sidste node, vi skal synkronisere.
Herefter skal vi lave en lille ændring i ProxySQL administrative kommandolinjegrænseflade, som typisk er tilgængelig på port 6032. Vi skal oprette poster i 'proxysql_servers'-tabellen, som definerer noderne i vores ProxySQL-klynge.
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)
Efter indlæsning af ændringen til runtime, bør ProxySQL begynde at synkronisere noderne. Der er et par steder, hvor du kan spore klyngens tilstand.
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)
Tabellen stats_proxysql_servers_checksums indeholder blandt andet en liste over noder i klyngen, tabeller der er synkroniseret, versioner og checksum af tabellen. Hvis kontrolsummen ikke er på linje, vil ProxySQL forsøge at hente den seneste version fra en klynge-peer. Mere detaljerede oplysninger om indholdet af denne tabel kan findes i ProxySQL-dokumentationen.
En anden kilde til information om processen er ProxySQL's log (som standard er den placeret i /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
Som du kan se, har vi her information om, at en ny kontrolsum er blevet opdaget, og at synkroniseringsprocessen er på plads.
Lad os stoppe et øjeblik her og diskutere, hvordan ProxySQL håndterer konfigurationsopdateringer fra flere kilder. Først og fremmest sporer ProxySQL kontrolsummer for at registrere, når en konfiguration er ændret. Det gemmer også, hvornår det skete - disse data gemmes som et tidsstempel, så det har et sekunds opløsning. ProxySQL har to variabler, som også påvirker, hvordan ændringer synkroniseres.
Cluster_check_interval_ms - det bestemmer, hvor ofte ProxySQL skal tjekke for konfigurationsændringer. Som standard er det 1000ms.
Cluster_mysql_servers_diffs_before_sync - det fortæller os, hvor mange gange en kontrol skal registrere en konfigurationsændring, før den bliver synkroniseret. Standardindstillingen er 3.
Dette betyder, at selvom du vil foretage en konfigurationsændring på den samme vært, hvis du vil lave den mindre ofte end 4 sekunder, vil de resterende ProxySQL-noder muligvis ikke være i stand til at synkronisere den, fordi en ny ændring vil dukke op før den forrige blev synkroniseret. Det betyder også, at hvis du laver konfigurationsændringer på flere ProxySQL-instanser, skal du lave dem med mindst 4 sekunders pause mellem dem, da nogle af ændringerne ellers vil gå tabt, og som et resultat vil konfigurationerne divergere. For eksempel tilføjer du Server1 på Proxy1, og efter 2 sekunder tilføjer du Server2 på Proxy2. Alle andre proxyer vil afvise ændringen på Proxy1, fordi de vil opdage, at Proxy2 har en nyere konfiguration. 4 sekunder efter ændringen på Proxy2 vil alle proxyer (inklusive Proxy1) trække konfigurationen fra Proxy2.
Da intra-cluster-kommunikationen ikke er synkron, og hvis en ProxySQL-node, du har foretaget ændringerne til, mislykkedes, bliver ændringer muligvis ikke replikeret til tiden. Den bedste tilgang er at foretage den samme ændring på to ProxySQL-noder. På denne måde, medmindre begge fejler nøjagtigt på samme tid, vil en af dem være i stand til at udbrede ny konfiguration.
Det er også værd at bemærke, at ProxySQL-klyngetopologien kan være ret fleksibel. I vores tilfælde har vi tre noder, alle har tre indgange i proxysql_servers-tabellen. Sådanne noder danner den klynge, hvor du kan skrive til enhver node, og ændringerne vil blive udbredt. Oven i det er det muligt at tilføje eksterne noder, som ville fungere i en "skrivebeskyttet" tilstand, hvilket betyder, at de kun vil synkronisere ændringer foretaget i "kerne"-klyngen, men de vil ikke udbrede ændringer, der blev udført direkte på sig selv. Alt du behøver på den nye node er kun at have "kerne"-klyndeknuderne konfigureret i proxysql_servere, og som et resultat vil den oprette forbindelse til disse noder og få dataændringerne, men det vil ikke blive forespurgt af resten af klyngen for dens konfigurationsændringer. Denne opsætning kunne bruges til at skabe en kilde til sandhed med flere noder i klyngen og andre ProxySQL noder, som bare får konfigurationen fra hoved-"kerne"-klyngen.
Ud over alt dette understøtter ProxySQL-klyngen automatisk genforening af noderne - de vil synkronisere deres konfiguration, mens de starter. Det kan også nemt skaleres ud ved at tilføje flere noder.
Vi håber, at dette blogindlæg giver dig et indblik i, hvordan ProxySQL-klynge kan konfigureres. ProxySQL-klyngen vil være gennemsigtig for ClusterControl, og det vil ikke påvirke nogen af de operationer, du måtte ønske at udføre fra ClusterControl-brugergrænsefladen.