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

Sådan køres og konfigureres ProxySQL 2.0 til MySQL Galera Cluster på Docker

ProxySQL er en intelligent og højtydende SQL-proxy, som understøtter MySQL, MariaDB og ClickHouse. For nylig er ProxySQL 2.0 blevet GA, og det kommer med nye spændende funktioner såsom GTID-konsistente læsninger, frontend SSL, Galera og MySQL Group Replication native support.

Det er relativt nemt at køre ProxySQL som Docker-container. Vi har tidligere skrevet om hvordan man kører ProxySQL på Kubernetes som en hjælpecontainer eller som en Kubernetes service, som er baseret på ProxySQL 1.x. I dette blogindlæg vil vi bruge den nye version ProxySQL 2.x, som bruger en anden tilgang til Galera Cluster-konfiguration.

ProxySQL 2.x Docker-billede

Vi har frigivet en ny ProxySQL 2.0 Docker-billedbeholder, og den er tilgængelig i Docker Hub. README giver en række konfigurationseksempler, især for Galera og MySQL-replikering, før og efter v2.x. Konfigurationslinjerne kan defineres i en tekstfil og tilknyttes containerens sti på /etc/proxysql.cnf for at blive indlæst i ProxySQL-tjenesten.

Billedets "seneste" tag peger stadig på 1.x, indtil ProxySQL 2.0 officielt bliver GA (vi har endnu ikke set nogen officiel udgivelsesblog/artikel fra ProxySQL-teamet). Hvilket betyder, at når du installerer ProxySQL-image ved hjælp af det seneste tag fra Severalnines, vil du stadig få version 1.x med det. Bemærk, at de nye eksempelkonfigurationer også aktiverer ProxySQL-webstatistik (introduceret i 1.4.4, men stadig i beta) - et simpelt dashboard, der opsummerer den overordnede konfiguration og status for selve ProxySQL.

ProxySQL 2.x-understøttelse af Galera Cluster

Lad os tale om Galera Clusters native support mere detaljeret. Den nye mysql_galera_hostgroups-tabel består af følgende felter:

  • writer_hostgroup : ID for værtsgruppen, der vil indeholde alle de medlemmer, der er forfattere (read_only=0).
  • backup_writer_hostgroup : Hvis klyngen kører i multi-writer-tilstand (dvs. der er flere noder med read_only=0), og max_writers er indstillet til et mindre antal end det samlede antal noder, flyttes de yderligere noder til denne backup-writer-værtsgruppe.
  • læser_værtsgruppe : ID for værtsgruppen, der vil indeholde alle medlemmer, der er læsere (dvs. noder, der har read_only=1)
  • offline_hostgroup : Når ProxySQL-overvågning bestemmer, at en vært er OFFLINE, flyttes værten til offline_hostgroup.
  • aktiv : en boolsk værdi (0 eller 1) for at aktivere en værtsgruppe
  • max_writers : Styrer det maksimale antal tilladte noder i forfatterværtsgruppen, som tidligere nævnt vil yderligere noder blive flyttet til backup_writer_hostgroup.
  • forfatter_er_også_læser : Når 1, vil en node i writer_hostgroup også blive placeret i reader_hostgroup, så den vil blive brugt til læsninger. Når indstillet til 2, vil noderne fra backup_writer_hostgroup blive placeret i reader_hostgroup i stedet for noderne i writer_hostgroup.
  • max_transactions_behind : bestemmer det maksimale antal skrivesæt, som en node i klyngen kan have i kø, før noden SHUNNED for at forhindre forældede læsninger (dette bestemmes ved at forespørge wsrep_local_recv_queue Galera-variablen).
  • kommentar : Tekstfelt, der kan bruges til ethvert formål defineret af brugeren

Her er et eksempel på konfiguration for mysql_galera_hostgroups i tabelformat:

Admin> select * from mysql_galera_hostgroups\G
*************************** 1. row ***************************
       writer_hostgroup: 10
backup_writer_hostgroup: 20
       reader_hostgroup: 30
      offline_hostgroup: 9999
                 active: 1
            max_writers: 1
  writer_is_also_reader: 2
max_transactions_behind: 20
                comment: 

ProxySQL udfører Galera-sundhedstjek ved at overvåge følgende MySQL-status/variabel:

  • skrivebeskyttet - Hvis TIL, vil ProxySQL gruppere den definerede vært i reader_hostgroup, medmindre writer_is_also_reader er 1.
  • wsrep_desync - Hvis TIL, vil ProxySQL markere noden som utilgængelig og flytte den til offline_hostgroup.
  • wsrep_reject_queries - Hvis denne variabel er TIL, vil ProxySQL markere noden som utilgængelig og flytte den til offline_hostgroup (nyttigt i visse vedligeholdelsessituationer).
  • wsrep_sst_donor_rejects_queries - Hvis denne variabel er TIL, vil ProxySQL markere noden som utilgængelig, mens Galera-knuden fungerer som en SST-donor, flytte den til offline_hostgroup.
  • wsrep_local_state - Hvis denne status returnerer en anden end 4 (4 betyder Synkroniseret), vil ProxySQL markere noden som utilgængelig og flytte den til offline_hostgroup.
  • wsrep_local_recv_queue - Hvis denne status er højere end max_transactions_behind, vil noden blive undgået.
  • wsrep_cluster_status - Hvis denne status returnerer en anden end Primær, vil ProxySQL markere noden som utilgængelig og flytte den til offline_hostgroup.

Når det er sagt, ved at kombinere disse nye parametre i mysql_galera_hostgroups sammen med mysql_query_rules, har ProxySQL 2.x fleksibiliteten til at passe ind i meget flere Galera use cases. For eksempel kan man have en enkelt-skriver-, multi-writer og multi-reader-værtsgrupper defineret som destinationsværtsgruppen for en forespørgselsregel, med muligheden for at begrænse antallet af forfattere og bedre kontrol over den forældede læseadfærd.

Sammenlign dette med ProxySQL 1.x, hvor brugeren eksplicit skulle definere en planlægger for at kalde et eksternt script for at udføre backend-sundhedstjek og opdatere databaseserverens tilstand. Dette kræver en vis tilpasning af scriptet (brugeren skal opdatere ProxySQL admin bruger/adgangskode/port) plus det afhang af et ekstra værktøj (MySQL klient) for at oprette forbindelse til ProxySQL admin interface.

Her er et eksempel på konfiguration af Galera-sundhedstjek-scriptplanlægning i tabelformat til ProxySQL 1.x:

Admin> select * from scheduler\G
*************************** 1. row ***************************
         id: 1
     active: 1
interval_ms: 2000
   filename: /usr/share/proxysql/tools/proxysql_galera_checker.sh
       arg1: 10
       arg2: 20
       arg3: 1
       arg4: 1
       arg5: /var/lib/proxysql/proxysql_galera_checker.log
    comment:

Desuden, da ProxySQL-planlægningstråden udfører ethvert script uafhængigt, er der mange versioner af sundhedstjek-scripts tilgængelige derude. Alle ProxySQL-instanser implementeret af ClusterControl bruger standardscriptet fra ProxySQL-installationspakken.

I ProxySQL 2.x kan max_writers og writer_is_also_reader variabler bestemme, hvordan ProxySQL dynamisk grupperer backend MySQL-serverne og vil direkte påvirke forbindelsesfordelingen og forespørgselsrouting. Overvej f.eks. følgende MySQL-backend-servere:

Admin> select hostgroup_id, hostname, status, weight from mysql_servers;
+--------------+--------------+--------+--------+
| hostgroup_id | hostname     | status | weight |
+--------------+--------------+--------+--------+
| 10           | DB1          | ONLINE | 1      |
| 10           | DB2          | ONLINE | 1      |
| 10           | DB3          | ONLINE | 1      |
+--------------+--------------+--------+--------+

Sammen med følgende Galera-værtsgruppedefinition:

Admin> select * from mysql_galera_hostgroups\G
*************************** 1. row ***************************
       writer_hostgroup: 10
backup_writer_hostgroup: 20
       reader_hostgroup: 30
      offline_hostgroup: 9999
                 active: 1
            max_writers: 1
  writer_is_also_reader: 2
max_transactions_behind: 20
                comment: 

I betragtning af at alle værter er oppe og køre, vil ProxySQL højst sandsynligt gruppere værterne som nedenfor:

Lad os se på dem én efter én:

Konfiguration Beskrivelse
writer_is_also_reader=0
  • Grupper værterne i 2 værtsgrupper (writer og backup_writer).
  • Writer er en del af backup_writer.
  • Da forfatteren ikke er en læser, er der intet i værtsgruppe 30 (læser), fordi ingen af ​​værterne er indstillet med read_only=1. Det er ikke almindelig praksis i Galera at aktivere skrivebeskyttet flag.
writer_is_also_reader=1
  • Grupper værterne i 3 værtsgrupper (writer, backup_writer og reader).
  • Variabel read_only=0 i Galera har ingen indflydelse, så forfatteren er også i værtsgruppe 30 (læser)
  • Writer er ikke en del af backup_writer.
writer_is_also_reader=2
  • I lighed med writer_is_also_reader=1 er writer dog en del af backup_writer.

Med denne konfiguration kan man have forskellige valg for værtsgruppedestination for at tage højde for specifikke arbejdsbelastninger. "Hotspot"-skrivninger kan konfigureres til kun at gå til én server for at reducere multi-master-konflikter, ikke-modstridende skrivninger kan fordeles ligeligt på de andre mastere, de fleste læsninger kan fordeles jævnt på alle MySQL-servere eller ikke-skribenter, kritiske læsninger kan videresendes til de mest opdaterede servere, og analytiske læsninger kan videresendes til en slavereplika.

ProxySQL-implementering til Galera Cluster

Antag i dette eksempel, at vi allerede har en Galera Cluster med tre knudepunkter implementeret af ClusterControl som vist i følgende diagram:

Vores Wordpress-applikationer kører på Docker, mens Wordpress-databasen er hostet på vores Galera Cluster, der kører på bare-metal-servere. Vi besluttede at køre en ProxySQL-container sammen med vores Wordpress-containere for at have bedre kontrol over Wordpress-databaseforespørgselsrouting og fuldt ud udnytte vores databaseklyngeinfrastruktur. Da læse-skriveforholdet er omkring 80%-20%, ønsker vi at konfigurere ProxySQL til:

  • Videresend alle skrivninger til én Galera-node (mindre konflikt, fokus på skrivning)
  • Balancer alle læsninger til de to andre Galera-noder (bedre fordeling for størstedelen af ​​arbejdsbyrden)

For det første skal du oprette en ProxySQL-konfigurationsfil inde i Docker-værten, så vi kan kortlægge den i vores container:

$ mkdir /root/proxysql-docker
$ vim /root/proxysql-docker/proxysql.cnf

Kopier derefter følgende linjer (vi vil forklare konfigurationslinjerne længere nede):

datadir="/var/lib/proxysql"

admin_variables=
{
    admin_credentials="admin:admin"
    mysql_ifaces="0.0.0.0:6032"
    refresh_interval=2000
    web_enabled=true
    web_port=6080
    stats_credentials="stats:admin"
}

mysql_variables=
{
    threads=4
    max_connections=2048
    default_query_delay=0
    default_query_timeout=36000000
    have_compress=true
    poll_timeout=2000
    interfaces="0.0.0.0:6033;/tmp/proxysql.sock"
    default_schema="information_schema"
    stacksize=1048576
    server_version="5.1.30"
    connect_timeout_server=10000
    monitor_history=60000
    monitor_connect_interval=200000
    monitor_ping_interval=200000
    ping_interval_server_msec=10000
    ping_timeout_server=200
    commands_stats=true
    sessions_sort=true
    monitor_username="proxysql"
    monitor_password="proxysqlpassword"
    monitor_galera_healthcheck_interval=2000
    monitor_galera_healthcheck_timeout=800
}

mysql_galera_hostgroups =
(
    {
        writer_hostgroup=10
        backup_writer_hostgroup=20
        reader_hostgroup=30
        offline_hostgroup=9999
        max_writers=1
        writer_is_also_reader=1
        max_transactions_behind=30
        active=1
    }
)

mysql_servers =
(
    { address="db1.cluster.local" , port=3306 , hostgroup=10, max_connections=100 },
    { address="db2.cluster.local" , port=3306 , hostgroup=10, max_connections=100 },
    { address="db3.cluster.local" , port=3306 , hostgroup=10, max_connections=100 }
)

mysql_query_rules =
(
    {
        rule_id=100
        active=1
        match_pattern="^SELECT .* FOR UPDATE"
        destination_hostgroup=10
        apply=1
    },
    {
        rule_id=200
        active=1
        match_pattern="^SELECT .*"
        destination_hostgroup=30
        apply=1
    },
    {
        rule_id=300
        active=1
        match_pattern=".*"
        destination_hostgroup=10
        apply=1
    }
)

mysql_users =
(
    { username = "wordpress", password = "passw0rd", default_hostgroup = 10, transaction_persistent = 0, active = 1 },
    { username = "sbtest", password = "passw0rd", default_hostgroup = 10, transaction_persistent = 0, active = 1 }
)

Lad os nu besøge nogle af de mest konfigurerede sektioner. For det første definerer vi Galera værtsgruppers konfiguration som nedenfor:

mysql_galera_hostgroups =
(
    {
        writer_hostgroup=10
        backup_writer_hostgroup=20
        reader_hostgroup=30
        offline_hostgroup=9999
        max_writers=1
        writer_is_also_reader=1
        max_transactions_behind=30
        active=1
    }
)

Hostgroup 10 vil være writer_hostgroup, hostgroup 20 for backup_writer og hostgroup 30 for reader. Vi sætter max_writers til 1, så vi kan have en single-writer værtsgruppe til værtsgruppe 10, hvor alle skrivere skal sendes til. Derefter definerer vi writer_is_also_reader til 1, hvilket vil gøre alle Galera-noder som læser også velegnede til forespørgsler, der kan fordeles ligeligt til alle noder. Hostgroup 9999 er reserveret til offline_hostgroup, hvis ProxySQL registrerer uoperative Galera-noder.

Derefter konfigurerer vi vores MySQL-servere med standard til værtsgruppe 10:

mysql_servers =
(
    { address="db1.cluster.local" , port=3306 , hostgroup=10, max_connections=100 },
    { address="db2.cluster.local" , port=3306 , hostgroup=10, max_connections=100 },
    { address="db3.cluster.local" , port=3306 , hostgroup=10, max_connections=100 }
)

Med ovenstående konfigurationer vil ProxySQL "se" vores værtsgrupper som nedenfor:

Derefter definerer vi forespørgselsdirigeringen gennem forespørgselsregler. Baseret på vores krav skal alle læsninger sendes til alle Galera noder undtagen forfatteren (værtsgruppe 20), og alt andet sendes til værtsgruppe 10 for enkelt forfatter:

mysql_query_rules =
(
    {
        rule_id=100
        active=1
        match_pattern="^SELECT .* FOR UPDATE"
        destination_hostgroup=10
        apply=1
    },
    {
        rule_id=200
        active=1
        match_pattern="^SELECT .*"
        destination_hostgroup=20
        apply=1
    },
    {
        rule_id=300
        active=1
        match_pattern=".*"
        destination_hostgroup=10
        apply=1
    }
)

Til sidst definerer vi de MySQL-brugere, der vil blive sendt gennem ProxySQL:

mysql_users =
(
    { username = "wordpress", password = "passw0rd", default_hostgroup = 10, transaction_persistent = 0, active = 1 },
    { username = "sbtest", password = "passw0rd", default_hostgroup = 10, transaction_persistent = 0, active = 1 }
)

Vi indstiller transaktion_persistent til 0, så alle forbindelser, der kommer fra disse brugere, vil respektere forespørgselsreglerne for læse- og skriveruting. Ellers ville forbindelserne ende med at ramme én værtsgruppe, hvilket besejrer formålet med belastningsbalancering. Glem ikke at oprette disse brugere først på alle MySQL-servere. For ClusterControl-brugere kan du bruge funktionen Administrer -> Skemaer og brugere til at oprette disse brugere.

Vi er nu klar til at starte vores container. Vi vil kortlægge ProxySQL-konfigurationsfilen som bind mount, når vi starter ProxySQL-containeren. Kør kommandoen vil således være:

$ docker run -d \
--name proxysql2 \
--hostname proxysql2 \
--publish 6033:6033 \
--publish 6032:6032 \
--publish 6080:6080 \
--restart=unless-stopped \
-v /root/proxysql/proxysql.cnf:/etc/proxysql.cnf \
severalnines/proxysql:2.0

Til sidst skal du ændre Wordpress-databasen, der peger på ProxySQL containerport 6033, for eksempel:

$ docker run -d \
--name wordpress \
--publish 80:80 \
--restart=unless-stopped \
-e WORDPRESS_DB_HOST=proxysql2:6033 \
-e WORDPRESS_DB_USER=wordpress \
-e WORDPRESS_DB_HOST=passw0rd \
wordpress

På dette tidspunkt ser vores arkitektur nogenlunde sådan her ud:

Hvis du ønsker, at ProxySQL-beholderen skal være persistent, skal du tilknytte /var/lib/proxysql/ til en Docker-volumen eller bind mount, for eksempel:

$ docker run -d \
--name proxysql2 \
--hostname proxysql2 \
--publish 6033:6033 \
--publish 6032:6032 \
--publish 6080:6080 \
--restart=unless-stopped \
-v /root/proxysql/proxysql.cnf:/etc/proxysql.cnf \
-v proxysql-volume:/var/lib/proxysql \
severalnines/proxysql:2.0

Husk, at kørsel med vedvarende lagring som ovenstående vil gøre vores /root/proxysql/proxysql.cnf forældet ved anden genstart. Dette skyldes ProxySQL flerlagskonfiguration, hvorved hvis /var/lib/proxysql/proxysql.db eksisterer, vil ProxySQL springe over indlæsningsmuligheder fra konfigurationsfilen og indlæse hvad der er i SQLite-databasen i stedet (medmindre du starter proxysql-tjenesten med --initial flag). Når det er sagt, skal den næste ProxySQL-konfigurationsadministration udføres via ProxySQL-administrationskonsollen på port 6032, i stedet for at bruge konfigurationsfilen.

Overvågning

ProxySQL-proceslog logger som standard til syslog, og du kan se dem ved at bruge standard docker-kommando:

$ docker ps
$ docker logs proxysql2

For at bekræfte den aktuelle værtsgruppe skal du forespørge tabellen runtime_mysql_servers:

$ docker exec -it proxysql2 mysql -uadmin -padmin -h127.0.0.1 -P6032 --prompt='Admin> '
Admin> select hostgroup_id,hostname,status from runtime_mysql_servers;
+--------------+--------------+--------+
| hostgroup_id | hostname     | status |
+--------------+--------------+--------+
| 10           | 192.168.0.21 | ONLINE |
| 30           | 192.168.0.21 | ONLINE |
| 30           | 192.168.0.22 | ONLINE |
| 30           | 192.168.0.23 | ONLINE |
| 20           | 192.168.0.22 | ONLINE |
| 20           | 192.168.0.23 | ONLINE |
+--------------+--------------+--------+

Hvis den valgte forfatter går ned, vil den blive overført til offline_hostgroup (HID 9999):

Admin> select hostgroup_id,hostname,status from runtime_mysql_servers;
+--------------+--------------+--------+
| hostgroup_id | hostname     | status |
+--------------+--------------+--------+
| 10           | 192.168.0.22 | ONLINE |
| 9999         | 192.168.0.21 | ONLINE |
| 30           | 192.168.0.22 | ONLINE |
| 30           | 192.168.0.23 | ONLINE |
| 20           | 192.168.0.23 | ONLINE |
+--------------+--------------+--------+

Ovenstående topologiændringer kan illustreres i følgende diagram:

Vi har også aktiveret webstatistik UI med admin-web_enabled=true. For at få adgang til web UI skal du blot gå til Docker-værten i port 6080, for eksempel:http://192.168.0.200:8060 og du vil blive bedt om med brugernavn/adgangskode pop op. Indtast legitimationsoplysningerne som defineret under admin-stats_credentials, og du bør se følgende side:

Ved at overvåge MySQL-forbindelsespooltabellen kan vi få et overblik over forbindelsesfordelingen for alle værtsgrupper:

Admin> select hostgroup, srv_host, status, ConnUsed, MaxConnUsed, Queries from stats.stats_mysql_connection_pool order by srv_host;
+-----------+--------------+--------+----------+-------------+---------+
| hostgroup | srv_host     | status | ConnUsed | MaxConnUsed | Queries |
+-----------+--------------+--------+----------+-------------+---------+
| 20        | 192.168.0.23 | ONLINE | 5        | 24          | 11458   |
| 30        | 192.168.0.23 | ONLINE | 0        | 0           | 0       |
| 20        | 192.168.0.22 | ONLINE | 2        | 24          | 11485   |
| 30        | 192.168.0.22 | ONLINE | 0        | 0           | 0       |
| 10        | 192.168.0.21 | ONLINE | 32       | 32          | 9746    |
| 30        | 192.168.0.21 | ONLINE | 0        | 0           | 0       |
+-----------+--------------+--------+----------+-------------+---------+

Outputtet ovenfor viser, at værtsgruppe 30 ikke behandler noget, fordi vores forespørgselsregler ikke har denne værtsgruppe konfigureret som destinationsværtsgruppe.

Statistikken relateret til Galera-noderne kan ses i mysql_server_galera_log-tabellen:

Admin>  select * from mysql_server_galera_log order by time_start_us desc limit 3\G
*************************** 1. row ***************************
                       hostname: 192.168.0.23
                           port: 3306
                  time_start_us: 1552992553332489
                success_time_us: 2045
              primary_partition: YES
                      read_only: NO
         wsrep_local_recv_queue: 0
              wsrep_local_state: 4
                   wsrep_desync: NO
           wsrep_reject_queries: NO
wsrep_sst_donor_rejects_queries: NO
                          error: NULL
*************************** 2. row ***************************
                       hostname: 192.168.0.22
                           port: 3306
                  time_start_us: 1552992553329653
                success_time_us: 2799
              primary_partition: YES
                      read_only: NO
         wsrep_local_recv_queue: 0
              wsrep_local_state: 4
                   wsrep_desync: NO
           wsrep_reject_queries: NO
wsrep_sst_donor_rejects_queries: NO
                          error: NULL
*************************** 3. row ***************************
                       hostname: 192.168.0.21
                           port: 3306
                  time_start_us: 1552992553329013
                success_time_us: 2715
              primary_partition: YES
                      read_only: NO
         wsrep_local_recv_queue: 0
              wsrep_local_state: 4
                   wsrep_desync: NO
           wsrep_reject_queries: NO
wsrep_sst_donor_rejects_queries: NO
                          error: NULL

Resultatsættet returnerer den relaterede MySQL-variabel/statustilstand for hver Galera-node for et bestemt tidsstempel. I denne konfiguration konfigurerede vi Galera-sundhedstjekket til at køre hvert andet sekund (monitor_galera_healthcheck_interval=2000). Derfor vil den maksimale failover-tid være omkring 2 sekunder, hvis der sker en topologiændring i klyngen.

Referencer

  • ProxySQL Native Galera Support
  • HA- og klyngeløsning:ProxySQL som en intelligent router til Galera- og gruppereplikering
  • ProxySQL Docker-billede af Severalnines
  • Sådan overvåger du ProxySQL med Prometheus og ClusterControl

  1. Sådan ændres Datetime-formater i MySQL

  2. Kan ikke oprette forbindelse til Oracle-databasen ved hjælp af JDBC, hvis adgangskoden har specialtegn

  3. Forespørgsel, der returnerer en hierarkisk liste over triggerhændelsestyper i SQL Server

  4. Trin for trin opgraderingsproces for R12.2 Upgrade Part -4 (anvender 12.2.x Release Update Pack)