sql >> Database teknologi >  >> RDS >> Mysql

Databasebevidst belastningsbalancering:Sådan migreres fra HAProxy til ProxySQL

HAProxy og ProxySQL er begge meget populære load balancers i MySQL-verdenen, men der er en betydelig forskel mellem begge disse proxyer. Vi vil ikke gå i detaljer her, du kan læse mere om HAProxy i HAProxy Tutorial og ProxySQL i ProxySQL Tutorial. Den vigtigste forskel er, at ProxySQL er SQL-bevidst proxy, den analyserer trafikken og forstår MySQL-protokollen, og som sådan kan den bruges til avanceret trafikformning - du kan blokere forespørgsler, omskrive dem, dirigere dem til bestemte værter, cache dem og mange flere. HAProxy, på den anden side, er en meget enkel, men effektiv lag 4-proxy, og alt det gør er at sende pakker til backend. ProxySQL kan bruges til at udføre en læse-skrive-split - den forstår SQL'en, og den kan konfigureres til at detektere, om en forespørgsel er SELECT eller ej, og dirigere dem i overensstemmelse hermed:SELECTs til alle noder, andre forespørgsler kun at mastere. Denne funktion er ikke tilgængelig i HAProxy, som skal bruge to separate  porte og to separate backends til master og slaver - læse-skriveopdelingen skal udføres på applikationssiden.

Hvorfor migrere til ProxySQL?

Baseret på de forskelle, vi forklarede ovenfor, vil vi sige, at hovedårsagen til, at du måske ønsker at skifte fra HAProxy til ProxySQL, er på grund af manglen på læse-skrive-splitningen i HAProxy. Hvis du bruger en klynge af MySQL-databaser, og det er lige meget, om det er asynkron replikering eller Galera Cluster, vil du sandsynligvis gerne være i stand til at opdele læsninger fra skrivninger. For MySQL-replikering ville dette naturligvis være den eneste måde at bruge din databaseklynge på, da skrivninger altid skal sendes til masteren. Derfor kan du kun sende forespørgsler til masteren, hvis du ikke kan udføre læse-skriveopdelingen. For Galera er læse-skriveopdeling ikke et must-have, men bestemt et godt at have. Sikker på, du kan konfigurere alle Galera-noder som én backend i HAProxy og sende trafik til dem alle på round-robin-måde, men dette kan resultere i, at skrivninger fra flere noder kommer i konflikt med hinanden, hvilket fører til deadlocks og fald i ydeevnen. Vi har også set problemer og fejl i Galera-klyngen, hvor løsningen, indtil de er blevet rettet, var at dirigere alle skrivningerne til en enkelt node. Derfor er den bedste praksis at sende alle skrivningerne til én Galera-node, da dette fører til mere stabil adfærd og bedre ydeevne.

En anden meget god grund til migrering til ProxySQL er et behov for at have bedre kontrol over trafikken. Med HAProxy kan du ikke gøre noget - det sender bare trafikken til sine backends. Med ProxySQL kan du forme din trafik ved hjælp af forespørgselsregler (matchende trafik ved hjælp af regulære udtryk, bruger, skema, kildevært og mange flere). Du kan omdirigere OLAP SELECTs til analyseslave (det gælder både for replikering og Galera). Du kan aflaste din master ved at omdirigere nogle af SELECT'erne fra den. Du kan implementere SQL firewall. Du kan tilføje en forsinkelse til nogle af forespørgslerne, du kan afbryde forespørgsler, hvis de tager mere end en foruddefineret tid. Du kan omskrive forespørgsler for at tilføje optimeringstip. Alle disse er ikke mulige med HAProxy.

Hvordan migreres fra HAProxy til ProxySQL?

Lad os først overveje følgende topologi...

ClusterControl MySQL-topologi MySQL-replikeringsklynge i ClusterControl

Vi har her en replikeringsklynge bestående af en master og to slaver. Vi har to HAProxy-noder installeret, som hver bruger to backends - på port 3307 til master (skriver) og 3308 for alle noder (læser). Keepalived bruges til at give en virtuel IP på tværs af disse to HAProxy-instanser - hvis en af ​​dem mislykkes, vil en anden blive brugt. Vores applikation forbinder direkte til VIP'en, gennem den til en af ​​HAProxy-instanserne. Lad os antage, at vores applikation (vi vil bruge Sysbench) ikke kan læse-skrive-opdelingen, derfor er vi nødt til at oprette forbindelse til "skribent"-backend. Som et resultat er størstedelen af ​​belastningen på vores master (10.0.0.101).

Hvad ville være trinene for at migrere til ProxySQL? Lad os tænke over det et øjeblik. Først skal vi implementere og konfigurere ProxySQL. Vi bliver nødt til at tilføje servere til ProxySQL, oprette nødvendige overvågningsbrugere og oprette korrekte forespørgselsregler. Endelig bliver vi nødt til at implementere Keepalived oven på ProxySQL, oprette endnu en virtuel IP og derefter sikre en så sømløs switch som muligt for vores applikation fra HAProxy til ProxySQL.

Lad os tage et kig på, hvordan vi kan opnå det...

Sådan installeres ProxySQL

Man kan installere ProxySQL på mange måder. Du kan bruge repository, enten fra selve ProxySQL (https://repo.proxysql.com), eller hvis du tilfældigvis bruger Percona XtraDB Cluster, kan du også installere ProxySQL fra Percona repository, selvom det kan kræve noget yderligere konfiguration, da det er afhængigt af CLI admin værktøjer oprettet til PXC. Da vi taler om replikering, kan brugen af ​​dem bare gøre tingene mere komplekse. Endelig kan du lige så godt installere ProxySQL binære filer, efter du har downloadet dem fra ProxySQL GitHub. I øjeblikket er der to stabile versioner, 1.4.x og 2.0.x. Der er forskelle mellem ProxySQL 1.4 og ProxySQL 2.0 med hensyn til funktioner, til denne blog vil vi holde os til 1.4.x-grenen, da den er bedre testet og funktionssættet er nok for os.

Vi vil bruge ProxySQL repository, og vi vil implementere ProxySQL på to yderligere noder:10.0.0.103 og 10.0.0.104.

Først installerer vi ProxySQL ved hjælp af det officielle depot. Vi vil også sikre, at MySQL-klienten er installeret (vi bruger den til at konfigurere ProxySQL). Vær opmærksom på, at den proces, vi gennemgår, ikke er produktionskvalitet. Til produktion vil du i det mindste ønske at ændre standardoplysningerne for den administrative bruger. Du vil også gerne gennemgå konfigurationen og sikre dig, at den er i overensstemmelse med dine forventninger og krav.

apt-get install -y lsb-release
wget -O - 'https://repo.proxysql.com/ProxySQL/repo_pub_key' | apt-key add -
echo deb https://repo.proxysql.com/ProxySQL/proxysql-1.4.x/$(lsb_release -sc)/ ./ | tee /etc/apt/sources.list.d/proxysql.list
apt-get -y update
apt-get -y install proxysql
service proxysql start

Nu, da ProxySQL er startet, vil vi bruge CLI til at konfigurere ProxySQL.

mysql -uadmin -padmin -P6032 -h127.0.0.1

Først vil vi definere backend-servere og replikeringsværtsgrupper:

mysql> INSERT INTO mysql_servers (hostgroup_id, hostname) VALUES (10, '10.0.0.101'), (20, '10.0.0.102'), (20, '10.0.0.103');
Query OK, 3 rows affected (0.91 sec)
mysql> INSERT INTO mysql_replication_hostgroups (writer_hostgroup, reader_hostgroup) VALUES (10, 20);
Query OK, 1 row affected (0.00 sec)

Vi har tre servere, vi definerede også, at ProxySQL skulle bruge værtsgruppe 10 til master (node ​​med read_only=0) og værtsgruppe 20 til slaver (read_only=1).

Som næste trin skal vi tilføje en overvågningsbruger på MySQL-knuderne, så ProxySQL kan overvåge dem. Vi vil gå med standardindstillinger, ideelt set vil du ændre legitimationsoplysningerne i ProxySQL.

mysql> SHOW VARIABLES LIKE 'mysql-monitor_username';
+------------------------+---------+
| Variable_name          | Value   |
+------------------------+---------+
| mysql-monitor_username | monitor |
+------------------------+---------+
1 row in set (0.00 sec)
mysql> SHOW VARIABLES LIKE 'mysql-monitor_password';
+------------------------+---------+
| Variable_name          | Value   |
+------------------------+---------+
| mysql-monitor_password | monitor |
+------------------------+---------+
1 row in set (0.00 sec)

Så vi er nødt til at oprette bruger 'monitor' med adgangskode 'monitor'. For at gøre det bliver vi nødt til at udføre følgende bevilling på master MySQL-serveren:

mysql> create user [email protected]'%' identified by 'monitor';
Query OK, 0 rows affected (0.56 sec)

Tilbage til ProxySQL - vi skal konfigurere brugere, som vores applikation vil bruge til at få adgang til MySQL og forespørgselsregler, som har til formål at give os en læse-skrive-split.

mysql> INSERT INTO mysql_users (username, password, default_hostgroup) VALUES ('sbtest', 'sbtest', 10);
Query OK, 1 row affected (0.34 sec)
mysql> INSERT INTO mysql_query_rules (rule_id,active,match_digest,destination_hostgroup,apply) VALUES (100, 1, '^SELECT.*FOR UPDATE$',10,1), (200,1,'^SELECT',20,1), (300,1,'.*',10,1);
Query OK, 3 rows affected (0.01 sec)

Bemærk venligst, at vi brugte adgangskode i almindelig tekst, og vi vil stole på, at ProxySQL hash det. Af sikkerhedshensyn bør du udtrykkeligt sende MySQL-adgangskode-hashen her.

Til sidst skal vi anvende alle ændringerne.

mysql> LOAD MYSQL SERVERS TO RUNTIME;
Query OK, 0 rows affected (0.02 sec)
mysql> LOAD MYSQL USERS TO RUNTIME;
Query OK, 0 rows affected (0.01 sec)
mysql> LOAD MYSQL QUERY RULES TO RUNTIME;
Query OK, 0 rows affected (0.01 sec)
mysql> SAVE MYSQL SERVERS TO DISK;
Query OK, 0 rows affected (0.07 sec)
mysql> SAVE MYSQL QUERY RULES TO DISK;
Query OK, 0 rows affected (0.02 sec)

Vi ønsker også at indlæse de hash-kodede adgangskoder fra runtime:almindelige tekst-adgangskoder hash-krypteres, når de indlæses i runtime-konfigurationen, for at holde dem hashed på disken, skal vi indlæse dem fra runtime og derefter gemme dem på disken:

mysql> SAVE MYSQL USERS FROM RUNTIME;
Query OK, 0 rows affected (0.00 sec)
mysql> SAVE MYSQL USERS TO DISK;
Query OK, 0 rows affected (0.02 sec)

Dette er det, når det kommer til ProxySQL. Før du foretager yderligere trin, bør du kontrollere, om du kan oprette forbindelse til proxyer fra dine applikationsservere.

[email protected]:~# mysql -h 10.0.0.103 -usbtest -psbtest -P6033 -e "SELECT * FROM sbtest.sbtest4 LIMIT 1\G"
mysql: [Warning] Using a password on the command line interface can be insecure.
*************************** 1. row ***************************
 id: 1
  k: 50147
  c: 68487932199-96439406143-93774651418-41631865787-96406072701-20604855487-25459966574-28203206787-41238978918-19503783441
pad: 22195207048-70116052123-74140395089-76317954521-98694025897

I vores tilfælde ser alt godt ud. Nu er det tid til at installere Keepalived.

Beholdt installation

Installationen er ret enkel (i hvert fald på Ubuntu 16.04, som vi brugte):

apt install keepalived

Så skal du oprette konfigurationsfiler for begge servere:

Master keepalived node:

vrrp_script chk_haproxy {
   script "killall -0 haproxy"   # verify the pid existance
   interval 2                    # check every 2 seconds
   weight 2                      # add 2 points of prio if OK
}
vrrp_instance VI_HAPROXY {
   interface eth1                # interface to monitor
   state MASTER
   virtual_router_id 52          # Assign one ID for this route
   priority 101
   unicast_src_ip 10.0.0.103
   unicast_peer {
      10.0.0.104

   }
   virtual_ipaddress {
       10.0.0.112                        # the virtual IP
   }
   track_script {
       chk_haproxy
   }
#    notify /usr/local/bin/notify_keepalived.sh
}

Backup keepalive node:

vrrp_script chk_haproxy {
   script "killall -0 haproxy"   # verify the pid existance
   interval 2                    # check every 2 seconds
   weight 2                      # add 2 points of prio if OK
}
vrrp_instance VI_HAPROXY {
   interface eth1                # interface to monitor
   state MASTER
   virtual_router_id 52          # Assign one ID for this route
   priority 100
   unicast_src_ip 10.0.0.103
   unicast_peer {
      10.0.0.104

   }
   virtual_ipaddress {
       10.0.0.112                        # the virtual IP
   }
   track_script {
       chk_haproxy
   }
#    notify /usr/local/bin/notify_keepalived.sh

Dette er det, du kan starte keepalive på begge noder:

service keepalived start

Du bør se oplysninger i logfilerne om, at en af ​​noderne gik ind i MASTER-tilstand, og at VIP er blevet bragt op på den node.

May  7 09:52:11 vagrant systemd[1]: Starting Keepalive Daemon (LVS and VRRP)...
May  7 09:52:11 vagrant Keepalived[26686]: Starting Keepalived v1.2.24 (08/06,2018)
May  7 09:52:11 vagrant Keepalived[26686]: Opening file '/etc/keepalived/keepalived.conf'.
May  7 09:52:11 vagrant Keepalived[26696]: Starting Healthcheck child process, pid=26697
May  7 09:52:11 vagrant Keepalived[26696]: Starting VRRP child process, pid=26698
May  7 09:52:11 vagrant Keepalived_healthcheckers[26697]: Initializing ipvs
May  7 09:52:11 vagrant Keepalived_vrrp[26698]: Registering Kernel netlink reflector
May  7 09:52:11 vagrant Keepalived_vrrp[26698]: Registering Kernel netlink command channel
May  7 09:52:11 vagrant Keepalived_vrrp[26698]: Registering gratuitous ARP shared channel
May  7 09:52:11 vagrant systemd[1]: Started Keepalive Daemon (LVS and VRRP).
May  7 09:52:11 vagrant Keepalived_vrrp[26698]: Unable to load ipset library
May  7 09:52:11 vagrant Keepalived_vrrp[26698]: Unable to initialise ipsets
May  7 09:52:11 vagrant Keepalived_vrrp[26698]: Opening file '/etc/keepalived/keepalived.conf'.
May  7 09:52:11 vagrant Keepalived_vrrp[26698]: Using LinkWatch kernel netlink reflector...
May  7 09:52:11 vagrant Keepalived_healthcheckers[26697]: Registering Kernel netlink reflector
May  7 09:52:11 vagrant Keepalived_healthcheckers[26697]: Registering Kernel netlink command channel
May  7 09:52:11 vagrant Keepalived_healthcheckers[26697]: Opening file '/etc/keepalived/keepalived.conf'.
May  7 09:52:11 vagrant Keepalived_healthcheckers[26697]: Using LinkWatch kernel netlink reflector...
May  7 09:52:11 vagrant Keepalived_vrrp[26698]: pid 26701 exited with status 256
May  7 09:52:12 vagrant Keepalived_vrrp[26698]: VRRP_Instance(VI_HAPROXY) Transition to MASTER STATE
May  7 09:52:13 vagrant Keepalived_vrrp[26698]: pid 26763 exited with status 256
May  7 09:52:13 vagrant Keepalived_vrrp[26698]: VRRP_Instance(VI_HAPROXY) Entering MASTER STATE
May  7 09:52:15 vagrant Keepalived_vrrp[26698]: pid 26806 exited with status 256
[email protected]:~# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 08:00:27:ee:87:c4 brd ff:ff:ff:ff:ff:ff
    inet 10.0.2.15/24 brd 10.0.2.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::a00:27ff:feee:87c4/64 scope link
       valid_lft forever preferred_lft forever
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 08:00:27:fc:ac:21 brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.103/24 brd 10.0.0.255 scope global eth1
       valid_lft forever preferred_lft forever
    inet 10.0.0.112/32 scope global eth1
       valid_lft forever preferred_lft forever
    inet6 fe80::a00:27ff:fefc:ac21/64 scope link
       valid_lft forever preferred_lft forever

Som du kan se, er der rejst en VIP (10.0.0.112) på node 10.0.0.103. Vi kan nu afslutte med at flytte trafikken fra den gamle opsætning til den nye.

Skift af trafik til en ProxySQL-opsætning

Der er mange metoder til hvordan man gør det, det afhænger mest af dit særlige miljø. Hvis du tilfældigvis bruger DNS til at vedligeholde et domæne, der peger på din HAProxy VIP, , kan du bare foretage en ændring der, og gradvist vil alle forbindelser over tid pege på den nye VIP. Du kan også foretage en ændring i din applikation, især hvis forbindelsesdetaljerne er hårdkodede - når du udruller ændringen, vil noder begynde at oprette forbindelse til den nye opsætning. Uanset hvordan du gør det, ville det være fantastisk at teste den nye opsætning, før du foretager et globalt skifte. Du har helt sikkert testet det på dit iscenesættelsesmiljø, men det er ikke en dårlig idé at vælge en håndfuld app-servere og omdirigere dem til den nye proxy, og overvåge, hvordan de ser ud rent præstationsmæssigt. Nedenfor er et simpelt eksempel, der bruger iptables, som kan være nyttige til test.

På ProxySQL-værterne skal du omdirigere trafik fra vært 10.0.0.11 og port 3307 til vært 10.0.0.112 og port 6033:

iptables -t nat -A OUTPUT -p tcp -d 10.0.0.111 --dport 3307 -j DNAT --to-destination 10.0.0.112:6033

Afhængigt af din applikation skal du muligvis genstarte webserveren eller andre tjenester (hvis din app opretter en konstant pulje af forbindelser til databasen) eller bare vente, da nye forbindelser vil blive åbnet mod ProxySQL. Du kan bekræfte, at ProxySQL modtager trafikken:

mysql> show processlist;
+-----------+--------+--------+-----------+---------+---------+-----------------------------------------------------------------------------+
| SessionID | user   | db     | hostgroup | command | time_ms | info                                                                        |
+-----------+--------+--------+-----------+---------+---------+-----------------------------------------------------------------------------+
| 12        | sbtest | sbtest | 20        | Sleep   | 0       |                                                                             |
| 13        | sbtest | sbtest | 10        | Query   | 0       | DELETE FROM sbtest23 WHERE id=49957                                         |
| 14        | sbtest | sbtest | 10        | Query   | 59      | DELETE FROM sbtest11 WHERE id=50185                                         |
| 15        | sbtest | sbtest | 20        | Query   | 59      | SELECT c FROM sbtest8 WHERE id=46054                                        |
| 16        | sbtest | sbtest | 20        | Query   | 0       | SELECT DISTINCT c FROM sbtest27 WHERE id BETWEEN 50115 AND 50214 ORDER BY c |
| 17        | sbtest | sbtest | 10        | Query   | 0       | DELETE FROM sbtest32 WHERE id=50084                                         |
| 18        | sbtest | sbtest | 10        | Query   | 26      | DELETE FROM sbtest28 WHERE id=34611                                         |
| 19        | sbtest | sbtest | 10        | Query   | 16      | DELETE FROM sbtest4 WHERE id=50151                                          |
+-----------+--------+--------+-----------+---------+---------+-----------------------------------------------------------------------------+

Det var det, vi har flyttet trafikken fra HAProxy til ProxySQL-opsætningen. Det tog nogle skridt, men det er bestemt muligt med meget små forstyrrelser i tjenesten.

Hvordan migreres fra HAProxy til ProxySQL ved hjælp af ClusterControl?

I det foregående afsnit forklarede vi, hvordan man manuelt implementerer ProxySQL-opsætningen og derefter migrerer ind i den. I dette afsnit vil vi gerne forklare, hvordan man opnår det samme mål ved hjælp af ClusterControl. Den indledende opsætning er nøjagtig den samme, derfor er vi nødt til at fortsætte med implementeringen af ​​ProxySQL.

Implementering af ProxySQL ved hjælp af ClusterControl

Implementering af ProxySQL i ClusterControl er kun et spørgsmål om en håndfuld klik.

Implementer ProxySQL i ClusterControl

Vi var nødt til at vælge en nodes IP eller værtsnavn, sende legitimationsoplysninger til CLI-administrativ bruger og MySQL-overvågningsbruger. Vi besluttede at bruge eksisterende MySQL, og vi videregav adgangsoplysninger for 'sbtest'@'%' bruger, som vi bruger i applikationen. Vi valgte hvilke noder vi vil bruge i belastningsbalanceren, vi øgede også den maksimale replikeringsforsinkelse (hvis den tærskel overskrides, sender ProxySQL ikke trafikken til den pågældende slave) fra standard 10 sekunder til 100, da vi allerede lider af replikeringen forsinkelse. Efter et kort stykke tid vil ProxySQL-noder blive tilføjet til klyngen.

Implementering af Keepalived til ProxySQL ved hjælp af ClusterControl

Når ProxySQL-noder er blevet tilføjet, er det tid til at implementere Keepalived.

Opbevares med ProxySQL i ClusterControl

Alt, hvad vi skulle gøre, er at vælge, hvilke ProxySQL-noder, vi vil have Keepalved til at implementere på, virtuel IP og grænseflade, som VIP vil være bundet til. Når implementeringen er fuldført, skifter vi trafikken til den nye opsætning ved hjælp af en af ​​metoderne nævnt i afsnittet "Skift trafik til ProxySQL-opsætning" ovenfor.

Overvågning af ProxySQL-trafik i ClusterControl

Vi kan verificere, at trafikken er skiftet til ProxySQL ved at se på belastningsgrafen – som du kan se, er belastningen meget mere fordelt på tværs af noderne i klyngen. Du kan også se det på grafen nedenfor, som viser fordelingen af ​​forespørgsler på tværs af klyngen.

ProxySQL Dashboard i ClusterControl

Endelig viser ProxySQL dashboard også, at trafikken er fordelt på tværs af alle noderne i klyngen:

ProxySQL Dashboard i ClusterControl

Vi håber, du vil drage fordel af dette blogindlæg, som du kan se, med ClusterControl, at implementeringen af ​​den nye arkitektur kun tager et øjeblik og kræver blot en håndfuld klik for at få tingene til at køre. Fortæl os om din erfaring med sådanne migreringer.


  1. Sådan vises tabeller i MySQL og MariaDB

  2. Sådan returneres en liste over datatyper i SQL Server (T-SQL)

  3. Hvordan deaktiverer jeg midlertidigt triggere i PostgreSQL?

  4. hvis min tabel har 4 kolonner, og jeg vil hente den 3. kolonne, hvad gør jeg.