MySQL InnoDB Cluster se skládá ze 3 komponent:
- MySQL Group Replication (skupina databázových serverů, které se navzájem replikují s odolností proti chybám).
- MySQL Router (směrovač dotazů na zdravé databázové uzly)
- MySQL Shell (pomocník, klient, konfigurační nástroj)
V první části tohoto návodu nasadíme MySQL InnoDB Cluster. Na internetu je k dispozici řada praktických výukových programů, ale tento návod pokrývá všechny nezbytné kroky/příkazy k instalaci a spuštění clusteru na jednom místě. Ve druhé části tohoto blogového příspěvku se budeme zabývat monitorováním, správou a škálováním a také některými problémy při práci s MySQL InnoDB Clusterem.
Následující diagram ilustruje naši architekturu po nasazení:
Chystáme se nasadit celkem 4 uzly; Tříuzlová replikace skupiny MySQL a jeden uzel směrovače MySQL společně umístěné na aplikačním serveru. Všechny servery běží na Ubuntu 18.04 Bionic.
Instalace MySQL
Následující kroky by měly být provedeny na všech databázových uzlech db1, db2 a db3.
Nejprve musíme provést nějaké mapování hostitele. To je zásadní, pokud chcete použít název hostitele jako identifikátor hostitele v InnoDB Cluster a toto je doporučený způsob. Mapujte všechny hostitele jako následující v /etc/hosts:
$ vi /etc/hosts
192.168.10.40 router apps
192.168.10.41 db1 db1.local
192.168.10.42 db2 db2.local
192.168.10.43 db3 db3.local
127.0.0.1 localhost localhost.localdomain
Zastavte a deaktivujte AppArmor:
$ service apparmor stop
$ service apparmor teardown
$ systemctl disable apparmor
Stáhněte si nejnovější úložiště konfigurace APT z webu úložiště MySQL Ubuntu na adrese https://repo.mysql.com/apt/ubuntu/pool/mysql-apt-config/m/mysql-apt-config/ . V době psaní tohoto článku je nejnovější datován 15. října 2019, což je mysql-apt-config_0.8.14-1_all.deb:
$ wget https://repo.mysql.com/apt/ubuntu/pool/mysql-apt-config/m/mysql-apt-config/mysql-apt-config_0.8.14-1_all.deb
Nainstalujte balíček a nakonfigurujte jej pro "mysql-8.0":
$ dpkg -i mysql-apt-config_0.8.14-1_all.deb
Nainstalujte klíč GPG:
$ apt-key adv --recv-keys --keyserver ha.pool.sks-keyservers.net 5072E1F5
Aktualizujte repolistu:
$ apt-get update
Nainstalujte Python a poté server MySQL a shell MySQL:
$ apt-get -y install mysql-server mysql-shell
Zobrazí se vám následující průvodci konfigurací:
- Nastavit heslo root – zadejte silné heslo pro uživatele root MySQL.
- Nastavte metodu autentizace – zvolte „Použít starší metodu autentizace (zachovat kompatibilitu MySQL 5.x)“
V tomto okamžiku by měla být nainstalována MySQL. Ověřte pomocí:
$ systemctl status mysql
Ujistěte se, že máte stav „aktivní (běžící)“.
Příprava serveru pro InnoDB Cluster
Následující kroky by měly být provedeny na všech databázových uzlech db1, db2 a db3.
Nakonfigurujte server MySQL tak, aby podporoval replikaci skupin. Nejjednodušší a doporučený způsob, jak toho dosáhnout, je použít nový MySQL Shell:
$ mysqlsh
Ověřte se jako místní uživatel root a postupujte podle průvodce konfigurací, jak je znázorněno v příkladu níže:
MySQL JS > dba.configureLocalInstance("[email protected]:3306");
Po ověření byste měli dostat řadu otázek, jako jsou následující:
Odpovědi na tyto otázky s následujícími odpověďmi:
- Výběr 2 – Vytvořte nový účet správce pro cluster InnoDB s minimálními požadovanými granty
- Název účtu:[email protected]%
- Heslo:mys3cret&&
- Potvrďte heslo:mys3cret&&
- Chcete provést požadované změny konfigurace?:y
- Chcete restartovat instanci po její konfiguraci?:y
Nezapomeňte opakovat výše uvedené na všech uzlech databáze. V tomto okamžiku by měl démon MySQL naslouchat všem IP adresám a je povolena replikace skupin. Nyní můžeme přistoupit k vytvoření clusteru.
Vytvoření clusteru
Nyní jsme připraveni vytvořit cluster. Na db1 se připojte jako správce clusteru z prostředí MySQL:
MySQL|JS> shell.connect('[email protected]:3306');
Creating a session to '[email protected]:3306'
Please provide the password for '[email protected]:3306': ***********
Save password for '[email protected]:3306'? [Y]es/[N]o/Ne[v]er (default No): Y
Fetching schema names for autocompletion... Press ^C to stop.
Your MySQL connection id is 9
Server version: 8.0.18 MySQL Community Server - GPL
No default schema selected; type \use <schema> to set one.
<ClassicSession:[email protected]:3306>
Měli byste být připojeni jako [email protected] (zjistíte to tak, že se podíváte na řetězec výzvy před '>'). Nyní můžeme vytvořit nový cluster:
MySQL|db1:3306 ssl|JS> cluster = dba.createCluster('my_innodb_cluster');
Zkontrolujte stav clusteru:
MySQL|db1:3306 ssl|JS> cluster.status()
{
"clusterName": "my_innodb_cluster",
"defaultReplicaSet": {
"name": "default",
"primary": "db1:3306",
"ssl": "REQUIRED",
"status": "OK_NO_TOLERANCE",
"statusText": "Cluster is NOT tolerant to any failures.",
"topology": {
"db1:3306": {
"address": "db1:3306",
"mode": "R/W",
"readReplicas": {},
"replicationLag": null,
"role": "HA",
"status": "ONLINE",
"version": "8.0.18"
}
},
"topologyMode": "Single-Primary"
},
"groupInformationSourceMember": "db1:3306"
}
V tomto okamžiku je součástí klastru pouze db1. Výchozí režim topologie je Single-Primary, podobný konceptu sady replik, kde je zapisovatelem vždy pouze jeden uzel. Zbývající uzly v clusteru budou čtečky.
Věnujte pozornost stavu clusteru, který říká OK_NO_TOLERANCE, a dalšímu vysvětlení pod klíčem statusText. V konceptu sady replik nebude jeden uzel poskytovat žádnou odolnost proti chybám. K automatizaci převzetí služeb při selhání primárního uzlu jsou vyžadovány minimálně 3 uzly. Na to se podíváme později.
Nyní přidejte druhý uzel, db2, a přijměte výchozí metodu obnovy, "Clone":
MySQL|db1:3306 ssl|JS> cluster.addInstance('[email protected]:3306');
Následující snímek obrazovky ukazuje průběh inicializace db2 poté, co jsme provedli výše uvedený příkaz. Operaci synchronizace provádí automaticky MySQL:
Zkontrolujte stav klastru a db2:
MySQL|db1:3306 ssl|JS> cluster.status()
{
"clusterName": "my_innodb_cluster",
"defaultReplicaSet": {
"name": "default",
"primary": "db1:3306",
"ssl": "REQUIRED",
"status": "OK_NO_TOLERANCE",
"statusText": "Cluster is NOT tolerant to any failures.",
"topology": {
"db1:3306": {
"address": "db1:3306",
"mode": "R/W",
"readReplicas": {},
"replicationLag": null,
"role": "HA",
"status": "ONLINE",
"version": "8.0.18"
},
"db2:3306": {
"address": "db2:3306",
"mode": "R/O",
"readReplicas": {},
"replicationLag": null,
"role": "HA",
"status": "ONLINE",
"version": "8.0.18"
}
},
"topologyMode": "Single-Primary"
},
"groupInformationSourceMember": "db1:3306"
}
V tomto okamžiku máme v clusteru dva uzly, db1 a db2. Stav stále zobrazuje OK_NO_TOLERANCE s dalším vysvětlením pod hodnotou statusText. Jak je uvedeno výše, MySQL Group Replication vyžaduje alespoň 3 uzly v clusteru pro odolnost proti chybám. Proto musíme přidat třetí uzel, jak je znázorněno dále.
Přidejte poslední uzel db3 a přijměte výchozí metodu obnovy „Klonovat“ podobnou db2:
MySQL|db1:3306 ssl|JS> cluster.addInstance('[email protected]:3306');
Následující snímek obrazovky ukazuje průběh inicializace db3 poté, co jsme provedli výše uvedený příkaz. Operaci synchronizace provádí automaticky MySQL:
Zkontrolujte stav clusteru a db3:
MySQL|db1:3306 ssl|JS> cluster.status()
{
"clusterName": "my_innodb_cluster",
"defaultReplicaSet": {
"name": "default",
"primary": "db1:3306",
"ssl": "REQUIRED",
"status": "OK",
"statusText": "Cluster is ONLINE and can tolerate up to ONE failure.",
"topology": {
"db1:3306": {
"address": "db1:3306",
"mode": "R/W",
"readReplicas": {},
"replicationLag": null,
"role": "HA",
"status": "ONLINE",
"version": "8.0.18"
},
"db2:3306": {
"address": "db2:3306",
"mode": "R/O",
"readReplicas": {},
"replicationLag": null,
"role": "HA",
"status": "ONLINE",
"version": "8.0.18"
},
"db3:3306": {
"address": "db3:3306",
"mode": "R/O",
"readReplicas": {},
"replicationLag": null,
"role": "HA",
"status": "ONLINE",
"version": "8.0.18"
}
},
"topologyMode": "Single-Primary"
},
"groupInformationSourceMember": "db1:3306"
}
Nyní cluster vypadá dobře, stav je v pořádku a cluster může tolerovat až jeden uzel selhání najednou. Primární uzel je db1, kde se zobrazuje „primární“:„db1:3306“ a „režim“:„R/W“, zatímco ostatní uzly jsou ve stavu „R/O“. Pokud zkontrolujete hodnoty read_only a super_read_only na RO uzlech, obě se zobrazí jako true.
Naše nasazení MySQL Group Replication je nyní dokončeno a synchronizováno.
Nasazení směrovače
Na aplikačním serveru, na kterém budeme spouštět naši aplikaci, se ujistěte, že je mapování hostitele správné:
$ vim /etc/hosts
192.168.10.40 router apps
192.168.10.41 db1 db1.local
192.168.10.42 db2 db2.local
192.168.10.43 db3 db3.local
127.0.0.1 localhost localhost.localdomain
Zastavte a deaktivujte AppArmor:
$ service apparmor stop
$ service apparmor teardown
$ systemctl disable apparmor
Poté nainstalujte balíček úložiště MySQL, podobně jako jsme provedli při instalaci databáze:
$ wget https://repo.mysql.com/apt/ubuntu/pool/mysql-apt-config/m/mysql-apt-config/mysql-apt-config_0.8.14-1_all.deb
$ dpkg -i mysql-apt-config_0.8.14-1_all.deb
Přidat klíč GPG:
$ apt-key adv --recv-keys --keyserver ha.pool.sks-keyservers.net 5072E1F5
Aktualizujte seznam repo:
$ apt-get update
Nainstalujte router a klienta MySQL:
$ apt-get -y install mysql-router mysql-client
MySQL Router je nyní nainstalován pod /usr/bin/mysqlrouter. MySQL router poskytuje bootstrap příznak pro automatickou konfiguraci provozu routeru s MySQL InnoDB clusterem. Co musíme udělat, je zadat URI řetězce do jednoho databázového uzlu jako uživatel správce clusteru InnoDB (clusteradmin).
Pro zjednodušení konfigurace spustíme proces mysqlrouter jako uživatel root:
$ mysqlrouter --bootstrap [email protected]:3306 --directory myrouter --user=root
Zde je to, co bychom měli získat po zadání hesla pro uživatele clusteradmin:
Příkaz bootstrap nám pomůže vygenerovat konfigurační soubor routeru na /root/myrouter/mysqlrouter.conf. Nyní můžeme spustit démona mysqlrouter pomocí následujícího příkazu z aktuálního adresáře:
$ myrouter/start.sh
Ověřte, zda očekávané porty naslouchají správně:
$ netstat -tulpn | grep mysql
tcp 0 0 0.0.0.0:6446 0.0.0.0:* LISTEN 14726/mysqlrouter
tcp 0 0 0.0.0.0:6447 0.0.0.0:* LISTEN 14726/mysqlrouter
tcp 0 0 0.0.0.0:64470 0.0.0.0:* LISTEN 14726/mysqlrouter
tcp 0 0 0.0.0.0:64460 0.0.0.0:* LISTEN 14726/mysqlrouter
Nyní může naše aplikace používat port 6446 pro čtení/zápis a 6447 pro připojení MySQL pouze pro čtení.
Připojování ke klastru
Vytvořme uživatele databáze na hlavním uzlu. Na db1 se připojte k serveru MySQL prostřednictvím prostředí MySQL:
$ mysqlsh [email protected]:3306
Přepnutí z režimu Javascript do režimu SQL:
MySQL|localhost:3306 ssl|JS> \sql
Switching to SQL mode... Commands end with ;
Vytvořte databázi:
MySQL|localhost:3306 ssl|SQL> CREATE DATABASE sbtest;
Vytvořte uživatele databáze:
MySQL|localhost:3306 ssl|SQL> CREATE USER [email protected]'%' IDENTIFIED BY 'password';
Přidělte uživateli databázi:
MySQL|localhost:3306 ssl|SQL> GRANT ALL PRIVILEGES ON sbtest.* TO [email protected]'%';
Nyní je naše databáze a uživatel připraven. Pojďme nainstalovat sysbench, abychom vygenerovali nějaká testovací data. Na serveru aplikace proveďte:
$ apt -y install sysbench mysql-client
Nyní můžeme otestovat na aplikačním serveru připojení k serveru MySQL přes router MySQL. Pro připojení pro zápis se připojte k portu 6446 hostitele routeru:
$ mysql -usbtest -p -h192.168.10.40 -P6446 -e 'select user(), @@hostname, @@read_only, @@super_read_only'
+---------------+------------+-------------+-------------------+
| user() | @@hostname | @@read_only | @@super_read_only |
+---------------+------------+-------------+-------------------+
| [email protected] | db1 | 0 | 0 |
+---------------+------------+-------------+-------------------+
Pro připojení pouze pro čtení se připojte k portu 6447 hostitele routeru:
$ mysql -usbtest -p -h192.168.10.40 -P6447 -e 'select user(), @@hostname, @@read_only, @@super_read_only'
+---------------+------------+-------------+-------------------+
| user() | @@hostname | @@read_only | @@super_read_only |
+---------------+------------+-------------+-------------------+
| [email protected] | db3 | 1 | 1 |
+---------------+------------+-------------+-------------------+
Vypadá dobře. Nyní můžeme generovat některá testovací data pomocí sysbench. Na aplikačním serveru vygenerujte 20 tabulek se 100 000 řádky na tabulku připojením k portu 6446 aplikačního serveru:
$ sysbench \
/usr/share/sysbench/oltp_common.lua \
--db-driver=mysql \
--mysql-user=sbtest \
--mysql-db=sbtest \
--mysql-password=password \
--mysql-port=6446 \
--mysql-host=192.168.10.40 \
--tables=20 \
--table-size=100000 \
prepare
Chcete-li provést jednoduchý test čtení a zápisu na portu 6446 po dobu 300 sekund, spusťte:
$ sysbench \
/usr/share/sysbench/oltp_read_write.lua \
--report-interval=2 \
--threads=8 \
--time=300 \
--db-driver=mysql \
--mysql-host=192.168.10.40 \
--mysql-port=6446 \
--mysql-user=sbtest \
--mysql-db=sbtest \
--mysql-password=password \
--tables=20 \
--table-size=100000 \
run
Pro zátěže pouze pro čtení můžeme odeslat připojení MySQL na port 6447:
$ sysbench \
/usr/share/sysbench/oltp_read_only.lua \
--report-interval=2 \
--threads=1 \
--time=300 \
--db-driver=mysql \
--mysql-host=192.168.10.40 \
--mysql-port=6447 \
--mysql-user=sbtest \
--mysql-db=sbtest \
--mysql-password=password \
--tables=20 \
--table-size=100000 \
run
Závěr
To je vše. Naše nastavení MySQL InnoDB Cluster je nyní kompletní a všechny jeho komponenty běží a jsou otestovány. Ve druhé části se podíváme na správu, monitorování a škálování operací clusteru a také na řešení řady běžných problémů při práci s clusterem MySQL InnoDB. Zůstaňte naladěni!