Implementar Percona Cluster - Parte 2

By rogerarjona Aug. 29, 2024, 4:34 p.m. Base de Datos

En este post, exploraremos cómo implementar un clúster utilizando MySQL y Percona para lograr alta disponibilidad, recuperación ante desastres y distribución de carga en entornos de producción. A través de ejemplos prácticos, veremos cómo configurar la replicación de datos, manejar la caída de un servidor con failover, reintegrar un servidor caído y distribuir la carga de consultas de manera eficiente.

Los ejemplos descritos a continuación se realizarón basandose en el siguiente diagrama:

diagrama.png

1. Replicación de Información

La replicación es la base de cualquier clúster de bases de datos. En nuestro setup, utilizamos Percona XtraDB Cluster para mantener los datos sincronizados entre los nodos.

1.1 Conectarse a cualquier servidor:

# NODO 1
ssh root@_ip_servidor_nodo1

# NODO 2
ssh root@_ip_servidor_nodo2

# NODO 3
ssh root@_ip_servidor_nodo3

# REPLICA
ssh root@_ip_servidor_replica

# PROXYSQL
ssh root@_ip_servidor_proxysql

Pass
xxxxxxxxxxxxxxxx

1.2 Conectarse a mysql admin de ProxySQL

mysql -u admin -padmin -h 127.0.0.1 -P 6032 --prompt='ProxySQLAdmin> '

1.3 Desde el proxy podemos ver nuestros nodos(servidores):

select * from mysql_servers;

percona_1_1.png

1.4 Para comprobar que todos los nodos estan conectados podemos hacer lo siguiente:

1.4.1 Conectarse a mysql en los nodos

mysql

1.4.2 Conectarse a la base de datos

mysql> use companydb;

1.4.3 Verificamos en todos los nodos el ultimo ID:

select * from Companies order by CompanyID DESC LIMIT 10 \G

percona_1_2.png

1.4.4 Hacer inserciones en el nodo 1 (se puede realizar desde cualquier nodo):

mysql> INSERT INTO Companies (CompanyID, Name, Address, Phone, Email) VALUES (NULL, 'Other Company', 'Unit 5699 Box 8173 DPO AP 62802', '+1-635-243-2015x623', '[email protected]');
mysql> INSERT INTO Companies (CompanyID, Name, Address, Phone, Email) VALUES (NULL, 'Other Company', 'Unit 5699 Box 8173 DPO AP 62802', '+1-635-243-2015x623', '[email protected]');
mysql> INSERT INTO Companies (CompanyID, Name, Address, Phone, Email) VALUES (NULL, 'Other Company', 'Unit 5699 Box 8173 DPO AP 62802', '+1-635-243-2015x623', '[email protected]');

Creamos 3 registros en el nodo 1, al crearlo, la información debería reflejarse en los otros nodos:

percona_1_3.png

Volvemos a verificar los últimos IDs

1.5 En todos los nodos, verificamos que la información se este replicando correctamente:

select * from Companies order by CompanyID DESC LIMIT 10 \G

Podemos observar que la información se ha replicado correctamente:

percona_1_4.png


NOTA

La replicación de información depende de los nodos, no depende del proxy. El proxy solamente decide a quien mandarle la consulta en especifico.


2. Servidor Caído/Failover

La alta disponibilidad es crítica en sistemas de producción. Si un nodo del clúster se cae, Percona maneja automáticamente el failover para garantizar que las operaciones continúen sin interrupción.

Ejemplo de Escenario: Imaginemos que el Nodo 3 del clúster se cae. Los demás nodos detectarán esta caída y continuarán manejando las peticiones sin necesidad de intervención manual.

2.1Verificamos nuestros nodos Desde el servidor de proxySQL ejecutamos lo siguiente:

ProxySQLAdmin> select * from mysql_galera_hostgroups;
ProxySQLAdmin> select * from runtime_mysql_servers;

Tomamos captura de nuestro grupo de escritura, para este ejemplo tenemos un nodo en linea, el cual es el nodo 3:

percona_2_1.png

Verificamos que nuestros nodos funcionan correctamente, incluyendo el de escritura:

2.2 Verificamos el estado de todos nuestros nodos En todos los nodos ejecutamos:

service mysql status

percona_2_2.png

2.3 Detenemos mysql en nuestro nodo de escritura En el nodo marcado como de escritura ejecutamos el siguiente comando:

service mysql stop

percona_2_3.png

2.4 Verificamos que nodo ahora es el de escritura: En el servidor de proxySQL ejecutamos lo siguiente:

select * from runtime_mysql_servers;

Una vez hecho esto podemos notar que ha tomado otro nodo de los pertenecientes al grupo de escritura, en este caso el nodo 2:

percona_2_4.png

2.5 Levantamos nuevamente nuestro servidor caído: En el servidor caido ejecutamos lo siguiente:

service mysql start

Finalmente al levantar nuevamente nuestro servidor podemos observar que lo vuelve a tomar como el servidor principal de escritura (Esto puede variar dependiendo si se ha terminado de sincronizar):

percona_2_5.png

3. Reintegro de un Servidor Caído/Failover

Una vez que el servidor caído está de vuelta en línea, se debe reintegrar al clúster y ponerse al día con la replicación de datos.

Ejemplo de reintegración:

3.1 Detenemos mysql en cualquiera de nuestros nodos En cualquier nodo ejecutamos:

service mysql stop

3.2 Insertamos registros Hacer inserciones en cualquiera de los nodos sobrantes (Se pueden realizar desde cualquier nodo):

mysql> INSERT INTO Companies (CompanyID, Name, Address, Phone, Email) VALUES (NULL, 'Other Company', 'Unit 5699 Box 8173 DPO AP 62802', '+1-635-243-2015x623', '[email protected]');
mysql> INSERT INTO Companies (CompanyID, Name, Address, Phone, Email) VALUES (NULL, 'Other Company', 'Unit 5699 Box 8173 DPO AP 62802', '+1-635-243-2015x623', '[email protected]');
mysql> INSERT INTO Companies (CompanyID, Name, Address, Phone, Email) VALUES (NULL, 'Other Company', 'Unit 5699 Box 8173 DPO AP 62802', '+1-635-243-2015x623', '[email protected]');
mysql> INSERT INTO Companies (CompanyID, Name, Address, Phone, Email) VALUES (NULL, 'Other Company', 'Unit 5699 Box 8173 DPO AP 62802', '+1-635-243-2015x623', '[email protected]');
mysql> INSERT INTO Companies (CompanyID, Name, Address, Phone, Email) VALUES (NULL, 'Other Company', 'Unit 5699 Box 8173 DPO AP 62802', '+1-635-243-2015x623', '[email protected]');

Para esta prueba, teniendo un servidor detenido realizamos una inserción de 5 registros, la cual se replico hacia nuestro servidor que esta en linea:

percona_3_1.png

3.3 Levantamos el nodo faltante En el nodo caido ejecutamos:

service mysql start

Levantamos nuevamente nuestro nodo y al hacerlo se nos replica la información que se agrego previamente:

percona_3_2.png

Levantamos nuevamente nuestro nodo y al hacerlo se nos replica la información que se agrego previamente:

select * from Companies order by CompanyID DESC LIMIT 10 \G

NOTA

Extrabackup tiene una forma de conocer el ultimo hash de los registros insertados, con esto se guiá de que tan sincronizado esta con las otras bases de datos.


4. Distribución de Carga de Consultas

Para optimizar el rendimiento, es importante distribuir las consultas entre los nodos disponibles en el clúster. Esto se puede lograr utilizando un balanceador de carga como ProxySQL o configurando adecuadamente la lógica de la aplicación.

Ejemplo de balanceo de carga:

4.1 Conectarse al mysql admin de ProxySQL

ssh root@_ip_servidor_proxysql

4.2 Consultar el host que responde una consulta: Ejecutamos:

mysql -u apps -p"It_is_so_Secure1" -h 127.0.0.1 -P 3306 -e "SELECT @@hostname;"

Al realizar una consulta podemos observar como nos responde un nodo diferente cada vez:

percona_4_1.png

4.3 Insertamos un registro con el nombre del host Hacemos una consulta para insertar y una para el select del host en la misma linea:

mysql -u apps -p"It_is_so_Secure1" -h 127.0.0.1 -P 3306 -e "INSERT INTO companydb.Companies (CompanyID, Name, Address, Phone, Email) VALUES (NULL, CONCAT('Empresa por: ', @@hostname), 'Unit 5699 Box 8173 DPO AP 62802', '+1-635-243-2015x623', '[email protected]');SELECT @@hostname;"

Si hacemos inserciones y consultas simultaneamente, podemos observar como por cada consulta nos responde un nodo diferente, sin embargo, las inserciones siempre se hacen en el nodo 3 el cual es nuestro nodo de escritura:

percona_4_2.png

4.4 Comprobamos los últimos registros

mysql -u apps -p"It_is_so_Secure1" -h 127.0.0.1 -P 3306 -e "select * from companydb.Companies order by CompanyID DESC LIMIT 10 \G"

5. Levantar un nuevo Nodo

5.1 Instalar PXC

Desde una instancia nueva de ubuntu 20.04:

apt update
apt update \
    && wget https://repo.percona.com/apt/percona-release_latest.generic_all.deb \
    && dpkg -i percona-release_latest.generic_all.deb \
    && percona-release setup pxc57 \
    && apt install -y libdbi-perl libdbd-mysql-perl libmecab2 socat  libcurl4-openssl-dev libev4 \
    && apt install -y percona-xtrabackup-24  qpress \
    && apt install -y percona-xtradb-cluster-full-57=5.7.40-31.63-1.focal percona-xtradb-cluster-server-5.7=5.7.40-31.63-1.focal percona-xtradb-cluster-client-5.7=5.7.40-31.63-1.focal percona-xtradb-cluster-test-5.7=5.7.40-31.63-1.focal percona-xtradb-cluster-5.7-dbg=5.7.40-31.63-1.focal percona-xtradb-cluster-server-debug-5.7=5.7.40-31.63-1.focal percona-xtradb-cluster-garbd-5.7=5.7.40-31.63-1.focal percona-xtradb-cluster-garbd-debug-5.7=5.7.40-31.63-1.focal percona-xtradb-cluster-common-5.7=5.7.40-31.63-1.focal \
    && systemctl start mysql

5.2 Editar el archivo

nano /etc/mysql/percona-xtradb-cluster.conf.d/wsrep.cnf

Agregar la configuración del nodo

GNU nano 4.8                /etc/mysql/percona-xtradb-cluster.conf.d/wsrep.cnf                          
[mysqld]
# Path to Galera library
wsrep_provider=/usr/lib/galera3/libgalera_smm.so

# Cluster connection URL contains IPs of nodes
#If no IP is found, this implies that a new cluster needs to be created,
#in order to do that you need to bootstrap this node
# Agregar las ip's incluidas la del nuevo nodo
wsrep_cluster_address=gcomm://192.168.12.3,192.168.12.4,192.168.12.5,192.168.12.6

# In order for Galera to work correctly binlog format should be ROW
binlog_format=ROW

# MyISAM storage engine has only experimental support
default_storage_engine=InnoDB

# Slave thread to use
# El numero de nucleos "nproc"
wsrep_slave_threads=4

wsrep_log_conflicts

# This changes how InnoDB autoincrement locks are managed and is a requirement for Galera
innodb_autoinc_lock_mode=2

# Node IP address
# IP del nodo actual
wsrep_node_address=192.168.12.6
# Cluster name
wsrep_cluster_name=pxc-cluster

#If wsrep_node_name is not specified,  then system hostname will be used
# Nombre para identificar al nodo
wsrep_node_name=Node-4

#pxc_strict_mode allowed values: DISABLED,PERMISSIVE,ENFORCING,MASTER
pxc_strict_mode=PERMISSIVE

# SST method
wsrep_sst_method=xtrabackup-v2

#Authentication for SST method
#wsrep_sst_auth="sstuser:s3cretPass"
wsrep_sst_auth="sstuser:xxxxxxxxxxxx"

Detener el servicio de mysql

service mysql stop

Iniciar de nuevo el servicio de mysql

service mysql start

Comprobamos que el servidor mysql se inicio correctamente:

service mysql status

percona_6_1.png

5.3 Entrar a mysql

mysql -u root -p
# Utilizar la contraseña de root

Listamos las bases de datos, las bases de datos de los otros nodos deben estar presentes:

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| companydb          |
| mughees            |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
6 rows in set (0.00 sec)

Seleccionamos la base de datos:

mysql> use companydb;

Consultamos los últimos registros, deben estar sincronizados con los otros nodos:

mysql> select * from Companies order by CompanyId DESC limit 10 \G
*************************** 1. row ***************************
CompanyID: 10078
     Name: Empresa por: Node-3
  Address: Unit 5699 Box 8173 DPO AP 62802
    Phone: +1-635-243-2015x623
    Email: jaredgill@miller.com
*************************** 2. row ***************************
CompanyID: 10075
     Name: Empresa por: Node-3
  Address: Unit 5699 Box 8173 DPO AP 62802
    Phone: +1-635-243-2015x623
    Email: jaredgill@miller.com

6. Realizar Backups y Restaurarlos

6.1 Realizar un backup

Para realizar el backup con extrabackup es necesario, generar el backup y prepararlo con las marcas de tiempo.

Crear un directorio:

mkdir /var/backupc

Generar el backup con xtrabackup

root@Replica:/var/backupc# xtrabackup --backup --target-dir=/var/backupc

percona_5_1.png

Preparar el backup con xtrabackup:

root@Replica:/var/backupc# xtrabackup --prepare --target-dir=/var/backupc

percona_5_2.png

6.2 Restaurar Backup


NOTA

Levantamos un nuevo nodo para probar la restauración


Copiar el backup al nodo:

scp Node-5:/backup /var/backups/backupc

Nos conectamos al servidor:

ssh Node-5

En el servidor nos dirigimos a la carpeta que contiene el backup:

cd /var/backups/backupc

Detenemos mysql:

systemctl stop mysql

Aplicamos el comando rsync como root:

rsync -rvt --exclude 'xtrabackup_checkpoints' --exclude 'xtrabackup_logfile' ./ /var/lib/mysql

Asignamos permisos a la carpeta

chown -R mysql:mysql /var/lib/mysql/

Iniciamos mysql y comprobamos que el backup funcione:

systemctl start mysql

mysql -u root -p

Listamos las bases de datos:

show databases;

percona_5_3.png

Seleccionar la base de datos y consultar los ultimos registros:

mysql> use companydb;
mysql> SELECT * FROM Companies ORDER BY CompanyId DESC LIMIT 10 \G
*************************** 1. row ***************************
CompanyID: 10078
     Name: Empresa por: Node-3
  Address: Unit 5699 Box 8173 DPO AP 62802
    Phone: +1-635-243-2015x623
    Email: jaredgill@miller.com
*************************** 2. row ***************************
CompanyID: 10075
     Name: Empresa por: Node-3
  Address: Unit 5699 Box 8173 DPO AP 62802
    Phone: +1-635-243-2015x623
    Email: jaredgill@miller.com

percona_5_4.png


NOTA

La diferencia entre mysqldump y xtrabackup es que mysqldump generara un archivo .sql que contiene todas las consultas que se tienen que ejecutar para llegar al punto actual, xtrabackup copia el contenido de la capeta donde mysql guarda los datos y le agrega checkpoints para tener un punto de restauracion.

Mas informacion: https://docs.percona.com/percona-xtrabackup/innovation-release/about-xtrabackup.html


7. Levantar un nodo con xtrabackup y unirlo al cluster


NOTA

Para este ejercicio es necesario realizar los pasos del punto 6: Realizar Backups y Restaurarlos


7.1 Agregar el nuevo nodo con backup al cluster

Editar el archivo de configuración.

nano /etc/mysql/percona-xtradb-cluster.conf.d/wsrep.cnf

Agregar la configuración:

GNU nano 4.8                /etc/mysql/percona-xtradb-cluster.conf.d/wsrep.cnf                          
[mysqld]
# Path to Galera library
wsrep_provider=/usr/lib/galera3/libgalera_smm.so

# Cluster connection URL contains IPs of nodes
#If no IP is found, this implies that a new cluster needs to be created,
#in order to do that you need to bootstrap this node
wsrep_cluster_address=gcomm://192.168.12.3,192.168.12.4,192.168.12.5,192.168.12.6,192.168.12.7

# In order for Galera to work correctly binlog format should be ROW
binlog_format=ROW

# MyISAM storage engine has only experimental support
default_storage_engine=InnoDB

# Slave thread to use
wsrep_slave_threads=4

wsrep_log_conflicts

# This changes how InnoDB autoincrement locks are managed and is a requirement for Galera
innodb_autoinc_lock_mode=2

# Node IP address
wsrep_node_address=192.168.12.7
# Cluster name
wsrep_cluster_name=pxc-cluster

#If wsrep_node_name is not specified,  then system hostname will be used
wsrep_node_name=Node-5

#pxc_strict_mode allowed values: DISABLED,PERMISSIVE,ENFORCING,MASTER
pxc_strict_mode=PERMISSIVE

# SST method
wsrep_sst_method=xtrabackup-v2

#Authentication for SST method
#wsrep_sst_auth="sstuser:s3cretPass"
wsrep_sst_auth="sstuser:xxxxxxxxxxx"

Reiniciar mysql

service mysql stop
service mysql start

Comprobamos que se estén replicando los datos los datos:

mysql -u root -p
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| companydb          |
| mughees            |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
6 rows in set (0.01 sec)
mysql> use companydb;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> select * from Companies order by CompanyID DESC LIMIT 10 \G
*************************** 1. row ***************************
CompanyID: 10081
     Name: Other Company 3
  Address: Unit 5699 Box 8173 DPO AP 62802
    Phone: +1-635-243-2015x623
    Email: jaredgill@miller.com
*************************** 2. row ***************************
CompanyID: 10078
     Name: Empresa por: Node-3
  Address: Unit 5699 Box 8173 DPO AP 62802
    Phone: +1-635-243-2015x623
    Email: jaredgill@miller.com

Al finalizar los pasos realizados, nos quedaria de la siguiente manera:

perconaDiagramaF.png