sql >> Base de Datos >  >> RDS >> Mysql

MySQL InnoDB Cluster 8.0:un recorrido completo de implementación:primera parte

MySQL InnoDB Cluster consta de 3 componentes:

  • Replicación de grupo de MySQL (un grupo de servidores de bases de datos que se replican entre sí con tolerancia a fallas).
  • Enrutador MySQL (enrutador de consultas a los nodos de la base de datos en buen estado)
  • MySQL Shell (ayudante, cliente, herramienta de configuración)

En la primera parte de este tutorial, implementaremos un clúster MySQL InnoDB. Hay varios tutoriales prácticos disponibles en línea, pero este tutorial cubre todos los pasos/comandos necesarios para instalar y ejecutar el clúster en un solo lugar. Cubriremos las operaciones de monitoreo, administración y escalado, así como algunos errores al tratar con MySQL InnoDB Cluster en la segunda parte de esta publicación de blog.

El siguiente diagrama ilustra nuestra arquitectura posterior a la implementación:

Vamos a implementar un total de 4 nodos; Una replicación de grupo MySQL de tres nodos y un nodo de enrutador MySQL ubicados dentro del servidor de aplicaciones. Todos los servidores se ejecutan en Ubuntu 18.04 Bionic.

Instalación de MySQL

Los siguientes pasos deben realizarse en todos los nodos de base de datos db1, db2 y db3.

En primer lugar, tenemos que hacer un mapeo de host. Esto es crucial si desea utilizar el nombre de host como identificador de host en InnoDB Cluster y esta es la forma recomendada de hacerlo. Asigne todos los hosts de la siguiente manera dentro de /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

Detener y deshabilitar AppArmor:

$ service apparmor stop
$ service apparmor teardown
$ systemctl disable apparmor

Descargue el repositorio de configuración APT más reciente del sitio web del repositorio MySQL Ubuntu en https://repo.mysql.com/apt/ubuntu/pool/mysql-apt-config/m/mysql-apt-config/ . En el momento de escribir este artículo, el último está fechado el 15 de octubre de 2019 y es 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

Instalar el paquete y configurarlo para "mysql-8.0":

$ dpkg -i mysql-apt-config_0.8.14-1_all.deb

Instale la clave GPG:

$ apt-key adv --recv-keys --keyserver ha.pool.sks-keyservers.net 5072E1F5

Actualizar el repolis:

$ apt-get update

Instale Python y luego el servidor MySQL y el shell de MySQL:

$ apt-get -y install mysql-server mysql-shell

Se le presentarán los siguientes asistentes de configuración:

  1. Establezca una contraseña de root:especifique una contraseña segura para el usuario root de MySQL.
  2. Establezca el método de autenticación:elija "Usar el método de autenticación heredado (mantener la compatibilidad con MySQL 5.x)"

MySQL debería haberse instalado en este punto. Verifique con:

$ systemctl status mysql

Asegúrese de obtener un estado "activo (en ejecución)".

Preparación del servidor para el clúster InnoDB

Los siguientes pasos deben realizarse en todos los nodos de base de datos db1, db2 y db3.

Configure el servidor MySQL para admitir la replicación de grupos. La forma más fácil y recomendada de hacer esto es usar el nuevo MySQL Shell:

$ mysqlsh

Autentíquese como usuario raíz local y siga el asistente de configuración como se muestra en el siguiente ejemplo:

MySQL  JS > dba.configureLocalInstance("[email protected]:3306");

Una vez autenticado, debería recibir una serie de preguntas como las siguientes:

Respuestas a esas preguntas con las siguientes respuestas:

  • Elección 2:cree una nueva cuenta de administrador para el clúster de InnoDB con las concesiones mínimas requeridas
  • Nombre de cuenta:[email protected]%
  • Contraseña:mys3cret&&
  • Confirmar contraseña:mys3cret&&
  • ¿Desea realizar los cambios de configuración necesarios?:y
  • ¿Desea reiniciar la instancia después de configurarla?:y

No olvide repetir lo anterior en todos los nodos de la base de datos. En este punto, el demonio MySQL debe estar escuchando todas las direcciones IP y la replicación de grupo está habilitada. Ahora podemos proceder a crear el clúster.

Creación del clúster

Ahora estamos listos para crear un clúster. En db1, conéctese como administrador del clúster desde 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>

Debería estar conectado como [email protected] (puede saberlo mirando la cadena de solicitud antes de '>'). Ahora podemos crear un nuevo clúster:

MySQL|db1:3306 ssl|JS> cluster = dba.createCluster('my_innodb_cluster');

Verifique el estado del clúster:

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"
}

En este punto, solo db1 es parte del clúster. El modo de topología predeterminado es Single-Primary, similar a un concepto de conjunto de réplicas en el que solo un nodo es un escritor a la vez. Los nodos restantes en el clúster serán lectores.

Preste atención al estado del clúster que dice OK_NO_TOLERANCE y una explicación más detallada en la tecla statusText. En un concepto de conjunto de réplicas, un nodo no proporcionará tolerancia a fallas. Se requiere un mínimo de 3 nodos para automatizar la conmutación por error del nodo principal. Vamos a investigar esto más adelante.

Ahora agregue el segundo nodo, db2 y acepte el método de recuperación predeterminado, "Clonar":

MySQL|db1:3306 ssl|JS> cluster.addInstance('[email protected]:3306');

La siguiente captura de pantalla muestra el progreso de inicialización de db2 después de ejecutar el comando anterior. MySQL realiza automáticamente la operación de sincronización:

Compruebe el estado del clúster y 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"
}

En este punto, tenemos dos nodos en el clúster, db1 y db2. El estado sigue mostrando OK_NO_TOLERANCE con una explicación más detallada en el valor del texto de estado. Como se indicó anteriormente, MySQL Group Replication requiere al menos 3 nodos en un clúster para la tolerancia a fallas. Es por eso que tenemos que agregar el tercer nodo como se muestra a continuación.

Agregue el último nodo, db3 y acepte el método de recuperación predeterminado, "Clonar", similar a db2:

MySQL|db1:3306 ssl|JS> cluster.addInstance('[email protected]:3306');

La siguiente captura de pantalla muestra el progreso de inicialización de db3 después de ejecutar el comando anterior. MySQL realiza automáticamente la operación de sincronización:

Compruebe el clúster y el estado 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"
}

Ahora el clúster se ve bien, donde el estado es correcto y el clúster puede tolerar hasta un nodo fallido a la vez. El nodo principal es db1 donde muestra "principal":"db1:3306" y "modo":"R/W", mientras que otros nodos están en estado "R/O". Si verifica los valores read_only y super_read_only en los nodos RO, ambos se muestran como verdaderos.

Nuestra implementación de MySQL Group Replication ahora está completa y sincronizada.

Implementación del enrutador

En el servidor de aplicaciones en el que vamos a ejecutar nuestra aplicación, asegúrese de que la asignación de host sea correcta:

$ 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

Detener y deshabilitar AppArmor:

$ service apparmor stop
$ service apparmor teardown
$ systemctl disable apparmor

Luego instale el paquete de repositorio MySQL, similar a lo que hemos hecho al realizar la instalación de la base de datos:

$ 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

Añadir clave GPG:

$ apt-key adv --recv-keys --keyserver ha.pool.sks-keyservers.net 5072E1F5

Actualice la lista de repositorios:

$ apt-get update

Instale el enrutador y el cliente MySQL:

$ apt-get -y install mysql-router mysql-client

MySQL Router ahora está instalado en /usr/bin/mysqlrouter. El enrutador MySQL proporciona un indicador de arranque para configurar automáticamente la operación del enrutador con un clúster MySQL InnoDB. Lo que debemos hacer es especificar el URI de la cadena en uno de los nodos de la base de datos como usuario administrador del clúster de InnoDB (clusteradmin).

Para simplificar la configuración, ejecutaremos el proceso mysqlrouter como usuario root:

$ mysqlrouter --bootstrap [email protected]:3306 --directory myrouter --user=root

Esto es lo que deberíamos obtener después de especificar la contraseña para el usuario clusteradmin:

El comando bootstrap nos ayudará a generar el archivo de configuración del enrutador en /root/myrouter/mysqlrouter.conf. Ahora podemos iniciar el demonio mysqlrouter con el siguiente comando desde el directorio actual:

$ myrouter/start.sh

Verifique si los puertos anticipados están escuchando correctamente:

$ 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

Ahora nuestra aplicación puede usar el puerto 6446 para lectura/escritura y el 6447 para conexiones MySQL de solo lectura.

Conexión al clúster

Vamos a crear un usuario de base de datos en el nodo principal. En db1, conéctese al servidor MySQL a través de MySQL shell:

$ mysqlsh [email protected]:3306

Cambiar del modo Javascript al modo SQL:

MySQL|localhost:3306 ssl|JS> \sql

Switching to SQL mode... Commands end with ;

Crear una base de datos:

MySQL|localhost:3306 ssl|SQL> CREATE DATABASE sbtest;

Crear un usuario de base de datos:

MySQL|localhost:3306 ssl|SQL> CREATE USER [email protected]'%' IDENTIFIED BY 'password';

Otorgar al usuario a la base de datos:

MySQL|localhost:3306 ssl|SQL> GRANT ALL PRIVILEGES ON sbtest.* TO [email protected]'%';

Ahora nuestra base de datos y usuario está listo. Instalemos sysbench para generar algunos datos de prueba. En el servidor de aplicaciones, haga:

$ apt -y install sysbench mysql-client

Ahora podemos probar en el servidor de aplicaciones para conectarnos al servidor MySQL a través del enrutador MySQL. Para una conexión de escritura, conéctese al puerto 6446 del host del enrutador:

$ 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                 |
+---------------+------------+-------------+-------------------+

Para una conexión de solo lectura, conéctese al puerto 6447 del host del enrutador:

$ 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                 |
+---------------+------------+-------------+-------------------+

Se ve bien. Ahora podemos generar algunos datos de prueba con sysbench. En el servidor de aplicaciones, genere 20 tablas con 100 000 filas por tabla conectándose al puerto 6446 del servidor de aplicaciones:

$ 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

Para realizar una prueba simple de lectura y escritura en el puerto 6446 durante 300 segundos, ejecute:

$ 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

Para cargas de trabajo de solo lectura, podemos enviar la conexión MySQL al puerto 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

Conclusión

Eso es todo. Nuestra configuración de MySQL InnoDB Cluster ahora está completa con todos sus componentes ejecutándose y probados. En la segunda parte, analizaremos las operaciones de administración, monitoreo y escalado del clúster, así como las soluciones a una serie de problemas comunes cuando se trata de MySQL InnoDB Cluster. ¡Estén atentos!