MariaDB MaxScale är en avancerad, plug-in databasproxy för MariaDB databasservrar. Den sitter mellan klientapplikationer och databasservrarna och dirigerar klientfrågor och serversvar. MaxScale övervakar också servrarna, så det kommer snabbt att märka eventuella förändringar i serverstatus eller replikeringstopologi. Detta gör MaxScale till ett naturligt val för att kontrollera failover och liknande funktioner.
I denna tvådelade bloggserie kommer vi att ge en komplett genomgång av hur man kör MariaDB MaxScale på Docker. Den här delen täcker distributionen som en fristående Docker-behållare och MaxScale-klustring via Docker Swarm för hög tillgänglighet.
MariaDB MaxScale på Docker
Det finns ett antal MariaDB Docker-bilder tillgängliga i Docker Hub. I den här bloggen kommer vi att använda den officiella bilden som underhålls och publiceras av MariaDB som heter "mariadb/maxscale" (tagg:senaste). Bilden är cirka 71MB stor. I skrivande stund är bilden förinstallerad med MaxScale 2.3.4 som en del av de nödvändiga paketen.
I allmänhet krävs följande steg för att köra en MaxScale med den här bilden i containermiljö:
- En körande MariaDB (master-slave eller master-master) replikering/Galera Cluster eller NDB Cluster
- Skapa och bevilja en databasanvändare dedikerad för MaxScale-övervakning
- Förbered MaxScale-konfigurationsfilen
- Mappa konfigurationsfilen till behållare eller ladda in i Kubernetes ConfigMap eller Docker Swarm Configs
- Starta behållaren/podden/service/replikuppsättningen
Observera att MaxScale är en produkt från MariaDB, vilket betyder att den är skräddarsydd för MariaDB-servern. De flesta funktionerna är fortfarande kompatibla med MySQL förutom vissa delar som till exempel GTID-hantering, Galera Cluster-konfiguration och interna datafiler. Den version som vi kommer att använda är 2.3.4, som släpps under Business Source License (BSL). Det tillåter att all kod är öppen och användning under TRE servrar är gratis. När användningen går över tre backend-servrar måste företaget som använder det betala för ett kommersiellt abonnemang. Efter en viss tidsperiod (2 år för MaxScale) flyttas versionen till GPL och all användning är gratis.
Bara för att vara tydlig, eftersom detta är en testmiljö, är vi okej att ha fler än 2 noder. Som anges på MariaDB BSL FAQ-sidan:
F:Kan jag använda MariaDB-produkter licensierade under BSL i test- och utvecklingsmiljö?
S:Ja, i icke-produktionstest- och utvecklingsmiljöer kan du använda produkter licensierade under BSL utan att behöva en prenumeration från MariaDB
I den här genomgången har vi redan en MariaDB-replikering med tre noder distribuerad med ClusterControl. Följande diagram illustrerar installationen som vi kommer att distribuera:
Vår systemarkitektur består av:
- mariadb1 - 192.168.0.91 (master)
- mariadb2 - 192.168.0.92 (slav)
- mariadb3 - 192.168.0.93 (slav)
- docker1 - 192.168.0.200 (Docker-värd för behållare - maxscale, app)
Förbereder MaxScale-användaren
Skapa först en MySQL-databasanvändare för MaxScale och tillåt alla värdar i nätverket 192.168.0.0/24:
MariaDB> CREATE USER 'maxscale'@'192.168.0.%' IDENTIFIED BY 'my_s3cret';
Ge sedan de nödvändiga rättigheterna. Om du bara vill övervaka backend-servrarna med lastbalansering räcker följande bidrag:
MariaDB> GRANT SHOW DATABASES ON *.* TO 'maxscale'@'192.168.0.%';
MariaDB> GRANT SELECT ON `mysql`.* TO 'maxscale'@'192.168.0.%';
MaxScale kan dock göra mycket mer än att dirigera frågor. Den har förmågan att utföra failover och switchover för att till exempel befordra en slav till en ny master. Detta kräver SUPER- och REPLICATION CLIENT-privilegier. Om du vill använda den här funktionen, tilldela ALLA PRIVILEGIER till användaren istället:
mysql> GRANT ALL PRIVILEGES ON *.* TO [email protected]'192.168.0.%';
Det är det för användarens del.
Förbereder MaxScale-konfigurationsfil
Bilden kräver att en fungerande konfigurationsfil mappas till behållaren innan den startas. Den minimala konfigurationsfilen som finns i behållaren kommer inte att hjälpa oss att bygga den omvända proxy som vi vill ha. Därför måste konfigurationsfilen förberedas i förväg.
Följande lista kan hjälpa oss att samla in nödvändig grundläggande information för att konstruera vår konfigurationsfil:
- Klustertyp - MaxScale stöder MariaDB-replikering (master-slave, master-master), Galera Cluster, Amazon Aurora, MariaDB ColumnStore och NDB Cluster (aka MySQL Cluster).
- Backend IP-adress och/eller värdnamn - IP-adress eller värdnamn som kan nås för alla backend-servrar.
- Routningsalgoritm - MaxScale stöder två typer av frågedirigering - läs-skriv-delning och lastbalansering i round-robin.
- Port att lyssna av MaxScale - Som standard använder MaxScale port 4006 för round-robin-anslutningar och 4008 för läs-skriv-delade anslutningar. Du kan använda UNIX-socket om du vill.
Skapa en textfil som heter maxscale.cnf i den aktuella katalogen så att vi kan mappa den till behållaren vid start. Klistra in följande rader i filen:
########################
## Server list
########################
[mariadb1]
type = server
address = 192.168.0.91
port = 3306
protocol = MariaDBBackend
serv_weight = 1
[mariadb2]
type = server
address = 192.168.0.92
port = 3306
protocol = MariaDBBackend
serv_weight = 1
[mariadb3]
type = server
address = 192.168.0.93
port = 3306
protocol = MariaDBBackend
serv_weight = 1
#########################
## MaxScale configuration
#########################
[maxscale]
threads = auto
log_augmentation = 1
ms_timestamp = 1
syslog = 1
#########################
# Monitor for the servers
#########################
[monitor]
type = monitor
module = mariadbmon
servers = mariadb1,mariadb2,mariadb3
user = maxscale
password = my_s3cret
auto_failover = true
auto_rejoin = true
enforce_read_only_slaves = 1
#########################
## Service definitions for read/write splitting and read-only services.
#########################
[rw-service]
type = service
router = readwritesplit
servers = mariadb1,mariadb2,mariadb3
user = maxscale
password = my_s3cret
max_slave_connections = 100%
max_sescmd_history = 1500
causal_reads = true
causal_reads_timeout = 10
transaction_replay = true
transaction_replay_max_size = 1Mi
delayed_retry = true
master_reconnection = true
master_failure_mode = fail_on_write
max_slave_replication_lag = 3
[rr-service]
type = service
router = readconnroute
servers = mariadb1,mariadb2,mariadb3
router_options = slave
user = maxscale
password = my_s3cret
##########################
## Listener definitions for the service
## Listeners represent the ports the service will listen on.
##########################
[rw-listener]
type = listener
service = rw-service
protocol = MariaDBClient
port = 4008
[ro-listener]
type = listener
service = rr-service
protocol = MariaDBClient
port = 4006
Lite förklaringar till varje avsnitt:
- Serverlista - Backend-servrarna. Definiera varje MariaDB-server i detta kluster i sin egen strof. Strofens namn kommer att användas när vi specificerar tjänstdefinitionen längre ner. Komponenttypen måste vara "server".
- MaxScale Configuration - Definiera alla MaxScale-relaterade konfigurationer där.
- Övervakningsmodul - Hur MaxScale ska övervaka backend-servrarna. Komponenttypen måste vara "monitor" följt av någon av övervakningsmodulerna. För listan över skärmar som stöds, se MaxScale 2.3-bildskärmar.
- Tjänst – Vart ska frågan dirigeras. Komponenttypen måste vara "service". För en lista över routrar som stöds, se MaxScale 2.3-routrar.
- Lyssnare – Hur MaxScale ska lyssna på inkommande anslutningar. Det kan vara port- eller socket-fil. Komponenttypen måste vara "lyssnare". Vanligtvis är lyssnare bundna till tjänster.
Så i grunden skulle vi vilja att MaxScale lyssnar på två portar, 4006 och 4008. Port 4006 är specifikt för round-robin-anslutning, lämplig för skrivskyddade arbetsbelastningar för vår MariaDB-replikering medan port 4008 är specifikt för kritiska läs- och skrivbelastningar. Vi vill också använda MaxScale för att utföra åtgärder för vår replikering i händelse av en failover, switchover eller slavåterförening, därför använder vi monitormodulen för kallad "mariadbmon".
Köra behållaren
Vi är nu redo att köra vår fristående MaxScale-behållare. Mappa konfigurationsfilen med -v och se till att publicera båda lyssnarportarna 4006 och 4008. Alternativt kan du aktivera MaxScale REST API-gränssnitt vid port 8989:
$ docker run -d \
--name maxscale \
--restart always \
-p 4006:4006 \
-p 4008:4008 \
-p 8989:8989 \
-v $PWD/maxscale.cnf:/etc/maxscale.cnf \
mariadb/maxscale
Verifiera med:
$ docker logs -f maxscale
...
2019-06-14 07:15:41.060 notice : (main): Started REST API on [127.0.0.1]:8989
2019-06-14 07:15:41.060 notice : (main): MaxScale started with 8 worker threads, each with a stack size of 8388608 bytes.
Se till att du inte ser något fel när du tittar på loggarna ovan. Kontrollera om docker-proxy-processerna lyssnar på de publicerade portarna - 4006, 4008 och 8989:
$ netstat -tulpn | grep docker-proxy
tcp6 0 0 :::8989 :::* LISTEN 4064/docker-proxy
tcp6 0 0 :::4006 :::* LISTEN 4092/docker-proxy
tcp6 0 0 :::4008 :::* LISTEN 4078/docker-proxy
Vid det här laget är vår MaxScale igång och kan bearbeta frågor.
MaxCtrl
MaxCtrl är en kommandoradsadministrativ klient för MaxScale som använder MaxScale REST API för kommunikation. Det är avsett att vara ersättningsprogramvaran för den äldre MaxAdmin-kommandoradsklienten.
För att komma in i MaxCtrl-konsolen, kör kommandot "maxctrl" inuti behållaren:
$ docker exec -it maxscale maxctrl
maxctrl: list servers
┌──────────┬──────────────┬──────┬─────────────┬─────────────────┬─────────────┐
│ Server │ Address │ Port │ Connections │ State │ GTID │
├──────────┼──────────────┼──────┼─────────────┼─────────────────┼─────────────┤
│ mariadb1 │ 192.168.0.91 │ 3306 │ 0 │ Master, Running │ 0-5001-1012 │
├──────────┼──────────────┼──────┼─────────────┼─────────────────┼─────────────┤
│ mariadb2 │ 192.168.0.92 │ 3306 │ 0 │ Slave, Running │ 0-5001-1012 │
├──────────┼──────────────┼──────┼─────────────┼─────────────────┼─────────────┤
│ mariadb3 │ 192.168.0.93 │ 3306 │ 0 │ Slave, Running │ 0-5001-1012 │
└──────────┴──────────────┴──────┴─────────────┴─────────────────┴─────────────┘
För att kontrollera om allt är okej, kör bara följande kommandon:
maxctrl: list servers
maxctrl: list services
maxctrl: list filters
maxctrl: list sessions
För att få mer information om varje komponent, prefix med kommandot "show" istället, till exempel:
maxctrl: show servers
┌──────────────────┬──────────────────────────────────────────┐
│ Server │ mariadb3 │
├──────────────────┼──────────────────────────────────────────┤
│ Address │ 192.168.0.93 │
├──────────────────┼──────────────────────────────────────────┤
│ Port │ 3306 │
├──────────────────┼──────────────────────────────────────────┤
│ State │ Slave, Running │
├──────────────────┼──────────────────────────────────────────┤
│ Last Event │ new_slave │
├──────────────────┼──────────────────────────────────────────┤
│ Triggered At │ Mon, 17 Jun 2019 08:57:59 GMT │
├──────────────────┼──────────────────────────────────────────┤
│ Services │ rw-service │
│ │ rr-service │
├──────────────────┼──────────────────────────────────────────┤
│ Monitors │ monitor │
├──────────────────┼──────────────────────────────────────────┤
│ Master ID │ 5001 │
├──────────────────┼──────────────────────────────────────────┤
│ Node ID │ 5003 │
├──────────────────┼──────────────────────────────────────────┤
│ Slave Server IDs │ │
├──────────────────┼──────────────────────────────────────────┤
│ Statistics │ { │
│ │ "connections": 0, │
│ │ "total_connections": 0, │
│ │ "persistent_connections": 0, │
│ │ "active_operations": 0, │
│ │ "routed_packets": 0, │
│ │ "adaptive_avg_select_time": "0ns" │
│ │ } │
├──────────────────┼──────────────────────────────────────────┤
│ Parameters │ { │
│ │ "address": "192.168.0.93", │
│ │ "protocol": "MariaDBBackend", │
│ │ "port": 3306, │
│ │ "extra_port": 0, │
│ │ "authenticator": null, │
│ │ "monitoruser": null, │
│ │ "monitorpw": null, │
│ │ "persistpoolmax": 0, │
│ │ "persistmaxtime": 0, │
│ │ "proxy_protocol": false, │
│ │ "ssl": "false", │
│ │ "ssl_cert": null, │
│ │ "ssl_key": null, │
│ │ "ssl_ca_cert": null, │
│ │ "ssl_version": "MAX", │
│ │ "ssl_cert_verify_depth": 9, │
│ │ "ssl_verify_peer_certificate": true, │
│ │ "disk_space_threshold": null, │
│ │ "type": "server", │
│ │ "serv_weight": "1" │
│ │ } │
└──────────────────┴──────────────────────────────────────────┘
Ansluter till databasen
Applikationens databasanvändare måste tilldelas MaxScale-värden eftersom den från MariaDB-serverns synvinkel endast kan se MaxScale-värden. Tänk på följande exempel utan MaxScale i bilden:
- Databasnamn:minapp
- Användare:myapp_user
- Värd:192.168.0.133 (applikationsserver)
För att tillåta användaren att komma åt databasen inuti MariaDB-servern måste man köra följande sats:
MariaDB> CREATE USER 'myapp_user'@'192.168.0.133' IDENTIFIED BY 'mypassword';
MariaDB> GRANT ALL PRIVILEGES ON myapp.* to 'myapp_user'@'192.168.0.133';
Med MaxScale i bilden måste man köra följande sats istället (ersätt applikationsserverns IP-adress med MaxScale IP-adressen, 192.168.0.200):
MariaDB> CREATE USER 'myapp_user'@'192.168.0.200' IDENTIFIED BY 'mypassword';
MariaDB> GRANT ALL PRIVILEGES ON myapp.* to 'myapp_user'@'192.168.0.200';
Från applikationen finns det två portar som du kan använda för att ansluta till databasen:
- 4006 – Round-robin lyssnare, lämplig för skrivskyddade arbetsbelastningar.
- 4008 - Läs-skriv-delad lyssnare, lämplig för skrivarbetsbelastningar.
Om din applikation endast tillåts ange en MySQL-port (t.ex. Wordpress, Joomla, etc), välj RW-port 4008 istället. Detta är den säkraste slutpunktsanslutningen oavsett klustertyp. Men om din applikation kan hantera anslutningar till flera MySQL-portar kan du skicka läsningarna till round-robin-lyssnaren. Den här lyssnaren har mindre omkostnader och mycket snabbare jämfört med läs-skriv-delad lyssnare.
För vår MariaDB-replikeringsinställning, anslut till någon av dessa slutpunkter som databasvärd/portkombination:
- 192.168.0.200 port 4008 - MaxScale - läs/skriv eller endast skriv
- 192.168.0.200 port 4006 - MaxScale - balanserad skrivskyddad
- 192.168.0.91 port 3306 - MariaDB Server (master) - läs/skriv
- 192.168.0.92 port 3306 - MariaDB Server (slav) - skrivskyddad
- 192.168.0.93 port 3306 - MariaDB Server (slav) - skrivskyddad
Observera för multi-master kluster typ som Galera Cluster och NDB Cluster, port 4006 kan användas som multi-write balanserade anslutningar istället. Med MaxScale har du många alternativ att välja mellan när du ansluter till databasen, och var och en av dem ger sina egna fördelar.
MaxScale Clustering med Docker Swarm
Med Docker Swarm kan vi skapa en grupp av MaxScale-instanser via Swarm-tjänsten med mer än en replik tillsammans med Swarm Configs. Importera först konfigurationsfilen till Swarm:
$ cat maxscale.conf | docker config create maxscale_config -
Verifiera med:
$ docker config inspect --pretty maxscale_config
Ge sedan MaxScale-databasanvändaren att ansluta från alla Swarm-värdar i nätverket:
MariaDB> CREATE USER 'maxscale'@'192.168.0.%' IDENTIFIED BY 'my_s3cret';
MariaDB> GRANT ALL PRIVILEGES ON *.* TO [email protected]'192.168.0.%';
När vi startar Swarm-tjänsten för MaxScale kan vi skapa flera behållare (kallade repliker) mappning till samma konfigurationsfil som nedan:
$ docker service create \
--name maxscale-cluster \
--replicas=3 \
--publish published=4008,target=4008 \
--publish published=4006,target=4006 \
--config source=maxscale_config,target=/etc/maxscale.cnf \
mariadb/maxscale
Ovanstående kommer att skapa tre MaxScale-behållare spridda över Swarm-noder. Verifiera med:
$ docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
yj6u2xcdj7lo maxscale-cluster replicated 3/3 mariadb/maxscale:latest *:4006->4006/tcp, *:4008->4008/tcp
Om applikationerna körs inom Swarm-nätverket kan du helt enkelt använda tjänstens namn "maxscale-cluster" som databasvärd för dina applikationer. Externt kan du ansluta till vilken som helst av Docker-värdarna på de publicerade portarna och Swarm-nätverket kommer att dirigera och balansera anslutningarna till rätt behållare på ett round-robin-sätt. Vid det här laget kan vår arkitektur illustreras enligt nedan:
I den andra delen kommer vi att titta på avancerade användningsfall av MaxScale på Docker som tjänstekontroll, konfigurationshantering, frågebehandling, säkerhet och klusteravstämning.