MySQL InnoDB Cluster se compose de 3 composants :
- MySQL Group Replication (un groupe de serveurs de base de données qui se répliquent les uns aux autres avec une tolérance aux pannes).
- MySQL Router (routeur de requêtes vers les nœuds sains de la base de données)
- MySQL Shell (helper, client, outil de configuration)
Dans la première partie de cette procédure pas à pas, nous allons déployer un cluster MySQL InnoDB. Il existe un certain nombre de didacticiels pratiques disponibles en ligne, mais cette procédure pas à pas couvre toutes les étapes/commandes nécessaires pour installer et exécuter le cluster en un seul endroit. Nous couvrirons les opérations de surveillance, de gestion et de mise à l'échelle ainsi que certains pièges liés au cluster MySQL InnoDB dans la deuxième partie de cet article de blog.
Le schéma suivant illustre notre architecture post-déploiement :
Nous allons déployer un total de 4 nœuds ; Une réplication de groupe MySQL à trois nœuds et un nœud de routeur MySQL colocalisés au sein du serveur d'applications. Tous les serveurs fonctionnent sur Ubuntu 18.04 Bionic.
Installer MySQL
Les étapes suivantes doivent être effectuées sur tous les nœuds de base de données db1, db2 et db3.
Tout d'abord, nous devons faire un mappage d'hôte. Ceci est crucial si vous souhaitez utiliser le nom d'hôte comme identifiant d'hôte dans InnoDB Cluster et c'est la méthode recommandée. Mappez tous les hôtes comme suit dans /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
Arrêtez et désactivez AppArmor :
$ service apparmor stop
$ service apparmor teardown
$ systemctl disable apparmor
Téléchargez le dernier référentiel de configuration APT à partir du site Web du référentiel MySQL Ubuntu à l'adresse https://repo.mysql.com/apt/ubuntu/pool/mysql-apt-config/m/mysql-apt-config/ . Au moment d'écrire ces lignes, le dernier est daté du 15 octobre 2019 et est 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
Installez le paquet et configurez-le pour "mysql-8.0":
$ dpkg -i mysql-apt-config_0.8.14-1_all.deb
Installez la clé GPG :
$ apt-key adv --recv-keys --keyserver ha.pool.sks-keyservers.net 5072E1F5
Mettre à jour le repolist :
$ apt-get update
Installez Python et suivi du serveur MySQL et du shell MySQL :
$ apt-get -y install mysql-server mysql-shell
Les assistants de configuration suivants vous seront présentés :
- Définir un mot de passe root - Spécifiez un mot de passe fort pour l'utilisateur root MySQL.
- Définissez la méthode d'authentification - Choisissez "Utiliser la méthode d'authentification héritée (Conserver la compatibilité MySQL 5.x)"
MySQL devrait avoir été installé à ce stade. Vérifiez avec :
$ systemctl status mysql
Assurez-vous d'obtenir un état "actif (en cours d'exécution)".
Préparation du serveur pour le cluster InnoDB
Les étapes suivantes doivent être effectuées sur tous les nœuds de base de données db1, db2 et db3.
Configurez le serveur MySQL pour prendre en charge la réplication de groupe. La méthode la plus simple et la plus recommandée consiste à utiliser le nouveau shell MySQL :
$ mysqlsh
Authentifiez-vous en tant qu'utilisateur racine local et suivez l'assistant de configuration en conséquence, comme indiqué dans l'exemple ci-dessous :
MySQL JS > dba.configureLocalInstance("[email protected]:3306");
Une fois authentifié, vous devriez recevoir un certain nombre de questions comme celles-ci :
Réponses à ces questions avec les réponses suivantes :
- Choix 2 - Créer un nouveau compte administrateur pour le cluster InnoDB avec un minimum de subventions requises
- Nom du compte :[email protected]%
- Mot de passe :mys3cret&&
- Confirmer le mot de passe :mys3cret&&
- Voulez-vous effectuer les modifications de configuration requises ? :y
- Voulez-vous redémarrer l'instance après l'avoir configuré ? : y
N'oubliez pas de répéter ce qui précède sur tous les nœuds de la base de données. À ce stade, le démon MySQL doit écouter toutes les adresses IP et la réplication de groupe est activée. Nous pouvons maintenant procéder à la création du cluster.
Création du cluster
Nous sommes maintenant prêts à créer un cluster. Sur db1, connectez-vous en tant qu'administrateur de cluster depuis MySQL Shell :
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>
Vous devez être connecté en tant qu'[email protected] (vous pouvez le savoir en regardant la chaîne d'invite avant '>'). Nous pouvons maintenant créer un nouveau cluster :
MySQL|db1:3306 ssl|JS> cluster = dba.createCluster('my_innodb_cluster');
Vérifiez l'état du cluster :
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"
}
À ce stade, seul db1 fait partie du cluster. Le mode de topologie par défaut est Single-Primary, similaire à un concept de jeu de répliques où un seul nœud est un écrivain à la fois. Les nœuds restants du cluster seront des lecteurs.
Faites attention au statut du cluster qui indique OK_NO_TOLERANCE, et plus d'explications sous la clé statusText. Dans un concept de jeu de répliques, un nœud ne fournira aucune tolérance aux pannes. Un minimum de 3 nœuds est requis pour automatiser le basculement du nœud principal. Nous allons examiner cela plus tard.
Ajoutez maintenant le deuxième nœud, db2 et acceptez la méthode de récupération par défaut, "Clone":
MySQL|db1:3306 ssl|JS> cluster.addInstance('[email protected]:3306');
La capture d'écran suivante montre la progression de l'initialisation de db2 après l'exécution de la commande ci-dessus. L'opération de synchronisation est effectuée automatiquement par MySQL :
Vérifiez l'état du cluster et de 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"
}
À ce stade, nous avons deux nœuds dans le cluster, db1 et db2. Le statut affiche toujours OK_NO_TOLERANCE avec plus d'explications sous la valeur statusText. Comme indiqué ci-dessus, la réplication de groupe MySQL nécessite au moins 3 nœuds dans un cluster pour la tolérance aux pannes. C'est pourquoi nous devons ajouter le troisième nœud comme indiqué ci-dessous.
Ajoutez le dernier nœud, db3 et acceptez la méthode de récupération par défaut, "Clone" similaire à db2 :
MySQL|db1:3306 ssl|JS> cluster.addInstance('[email protected]:3306');
La capture d'écran suivante montre la progression de l'initialisation de db3 après l'exécution de la commande ci-dessus. L'opération de synchronisation est effectuée automatiquement par MySQL :
Vérifiez l'état du cluster et de 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"
}
Maintenant, le cluster semble bon, où l'état est OK et le cluster peut tolérer jusqu'à un nœud défaillant à la fois. Le nœud principal est db1 où il affiche "primary":"db1:3306" et "mode":"R/W", tandis que les autres nœuds sont à l'état "R/O". Si vous cochez les valeurs read_only et super_read_only sur les nœuds RO, les deux s'affichent comme vrais.
Notre déploiement de MySQL Group Replication est maintenant terminé et synchronisé.
Déploiement du routeur
Sur le serveur d'application sur lequel nous allons exécuter notre application, assurez-vous que le mappage de l'hôte est correct :
$ 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
Arrêtez et désactivez AppArmor :
$ service apparmor stop
$ service apparmor teardown
$ systemctl disable apparmor
Ensuite, installez le package de référentiel MySQL, similaire à ce que nous avons fait lors de l'installation de la base de données :
$ 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
Ajouter une clé GPG :
$ apt-key adv --recv-keys --keyserver ha.pool.sks-keyservers.net 5072E1F5
Mettez à jour la liste des dépôts :
$ apt-get update
Installez le routeur et le client MySQL :
$ apt-get -y install mysql-router mysql-client
MySQL Router est maintenant installé sous /usr/bin/mysqlrouter. Le routeur MySQL fournit un indicateur d'amorçage pour configurer automatiquement le fonctionnement du routeur avec un cluster MySQL InnoDB. Ce que nous devons faire est de spécifier la chaîne URI à l'un des nœuds de la base de données en tant qu'utilisateur administrateur du cluster InnoDB (clusteradmin).
Pour simplifier la configuration, nous allons exécuter le processus mysqlrouter en tant qu'utilisateur root :
$ mysqlrouter --bootstrap [email protected]:3306 --directory myrouter --user=root
Voici ce que nous devrions obtenir après avoir spécifié le mot de passe pour l'utilisateur clusteradmin :
La commande bootstrap nous aidera à générer le fichier de configuration du routeur à /root/myrouter/mysqlrouter.conf. Nous pouvons maintenant démarrer le démon mysqlrouter avec la commande suivante depuis le répertoire courant :
$ myrouter/start.sh
Vérifiez si les ports prévus écoutent correctement :
$ 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
Notre application peut désormais utiliser le port 6446 pour la lecture/écriture et le port 6447 pour les connexions MySQL en lecture seule.
Connexion au cluster
Créons un utilisateur de base de données sur le nœud maître. Sur db1, connectez-vous au serveur MySQL via le shell MySQL :
$ mysqlsh [email protected]:3306
Passer du mode Javascript au mode SQL :
MySQL|localhost:3306 ssl|JS> \sql
Switching to SQL mode... Commands end with ;
Créer une base de données :
MySQL|localhost:3306 ssl|SQL> CREATE DATABASE sbtest;
Créer un utilisateur de base de données :
MySQL|localhost:3306 ssl|SQL> CREATE USER [email protected]'%' IDENTIFIED BY 'password';
Accordez l'utilisateur à la base de données :
MySQL|localhost:3306 ssl|SQL> GRANT ALL PRIVILEGES ON sbtest.* TO [email protected]'%';
Maintenant, notre base de données et notre utilisateur sont prêts. Installons sysbench pour générer des données de test. Sur le serveur d'application, faites :
$ apt -y install sysbench mysql-client
Nous pouvons maintenant tester sur le serveur d'application pour se connecter au serveur MySQL via le routeur MySQL. Pour une connexion en écriture, connectez-vous au port 6446 de l'hôte du routeur :
$ 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 |
+---------------+------------+-------------+-------------------+
Pour une connexion en lecture seule, connectez-vous au port 6447 de l'hôte du routeur :
$ 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 |
+---------------+------------+-------------+-------------------+
Cela semble bon. Nous pouvons maintenant générer des données de test avec sysbench. Sur le serveur d'application, générez 20 tables de 100 000 lignes par table en vous connectant au port 6446 du serveur d'application :
$ 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
Pour effectuer un simple test de lecture-écriture sur le port 6446 pendant 300 secondes, exécutez :
$ 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
Pour les charges de travail en lecture seule, nous pouvons envoyer la connexion MySQL au 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
Conclusion
C'est tout. Notre configuration MySQL InnoDB Cluster est maintenant terminée avec tous ses composants en cours d'exécution et testés. Dans la deuxième partie, nous allons examiner les opérations de gestion, de surveillance et de mise à l'échelle du cluster ainsi que les solutions à un certain nombre de problèmes courants liés au cluster MySQL InnoDB. Restez à l'écoute !