Posts tagged with “slave”


Thu 3 Dec

Alta disponibilidad en replicación con Mysql-MMM

Montar un sistema de replicación es sencillo y rápido. Nos ofrece muchas ventajas, siempre y cuando funcione correctamente y no fallen los equipos. Ahora imagina con las siguientes características:

  • Dos equipos en maestro-maestro.
  • 50 equipos esclavos, 25 colgando del maestro 1 y otros 25 del maestro 2.

Ahora imagina que el maestro 1 se cae. Bien, recuerda que todo esto está en tu imaginación, no te intentes suicidar, aunque he de admitir que sería la solución mas razonable. Con la caida de ese Master, 25 equipos esclavos se han quedado desincronizados. Tenemos usuarios que ni pueden escribir y lo que leen está posiblemente anticuado. Cuando pones de nuevo el servidor en marcha compruebas que no se replican correctamente ya que alguna transacción quedó a medías. Tienes 26 ordenadores desincronizados y tienes que entrar uno a uno parando el proceso Slave, ejecutando el change_master, arranco de nuevo el slave, comprobando si se resincroniza o no. En el peor de los casos tienes que borrar la base de datos importándola de nuevo... El infierno convertido en SQL.

La solución

Para ayudarnos en esta tarea tenemos Mysql MMM (Multi-Master Replication Manager). Son una serie de scripts y demonios que se encargan de hacer esta tarea más sencilla. Entre sus características tenemos:

- Monitorización de la replicación
- Monitorización de los hosts
- Gestión del failover
- Balanceo de IPs entre nodos
- Gestión de grupos de escritura/lectura

El esquema de nuestra red cambia poco, si antes teniamos 52 servidores, ahora serán 53. El nuevo será un sistema de control que se encargará de conectarse a cada nodo y comprobar el estado y ejecutar las ordenes que le indiquemos mediante las utilidades de consola. Además será necesario más IPs que se asignarán al vuelo de un host a otro dependiendo de los hosts que se encuentren online.

A la hora de gestionar las IPs virtuales tenemos dos formas de hacerlo:

Exclusivo: Una única IP para muchos hosts. Si el host que la tiene se cae se balancea a otro. Generalmente se usa en los nodos de escritura.

Balanceado: Una IP por cada host. Si uno de los hosts se cae la IP se balancea a cualquier otro, pasando a tener dos IPs virtuales. Se usa para nodos en lectura.

Yo no voy a hacer el ejemplo con 52 hosts, siendo sincero me da mucha pereza. Así que el esquema de nuestro sistema de replicación en alta disponibilidad es el siguiente:

Al turrón

La parte de montar la arquitectura maestro/esclavo la damos por hecha :P Nos centraremos únicamente en MMM. Como vemos, el host de control tendrá la IP 10.100.1.14. Las IPs virtuales que usaremos serán 10.100.1.10 en modo exclusivo para las escrituras (DB1 y DB2) y 10.100.1.11 y 10.100.1.12 en modo balanceado para la lectura.

De esta forma, ya sea mediante un balanceador hardware o software (en la propia aplicación), los usuarios leerán de 10.100.1.11 y 10.100.1.12 (round robin) y escribirán en 10.100.1.10.

En el sistema de control se debe instalar:

  • mysql-mmm-common_2.0.10-1_all.deb
  • mysql-mmm-monitor_2.0.10-1_all.deb

Mientras que en los servidores de MySQL instalaremos:

  • mysql-mmm-common_2.0.10-1_all.deb
  • mysql-mmm-agent_2.0.10-1_all.deb

Sin olvidarnos de todas sus dependencias.

Los ficheros de configuración se guardan en /etc/mysql-mmm. Todos tienen uno en común llamado mmm_common.conf con este contenido:


active_master_role  writer
<host default>
    cluster_interface       eth1
    pid_path                /var/run/mmmd_agent.pid
    bin_path                /usr/bin/mysql-mmm/
        replication_user        replication
        replication_password    slave
    agent_user              mmm_agent
    agent_password          RepAgent
</host>
<host db1>
    ip                  10.100.1.1
    mode                    master
    peer                    db2
</host>
<host db2>
    ip                  10.100.1.2
    mode                    master
    peer                    db1
</host>
<host db3>
    ip                  10.100.1.3
    mode                    slave
</host>
<host db4>
    ip                  10.100.1.4
    mode                    slave
</host>
<role writer>
    hosts                   db1, db2
    ips                 10.100.1.10
    mode                    exclusive
</role>
<role reader>
    hosts                   db3, db4
    ips                 10.100.1.11, 10.100.1.12
    mode                    balanced
</role>

Es bastante descriptivo :) Se identifican los hosts con su nombre, su ip y las IPs virtuales que compartirán (y en que modo lo harán). También se indica el usuario y contraseña para el usuario de replicación así como del del agente (serán usuarios de MySQL).

El nodo de control tendrá el fichero mmm_mon.conf:


include mmm_common.conf
<monitor>
    ip                  127.0.0.1
    pid_path                /var/run/mmmd_mon.pid
    bin_path                /usr/bin/mysql-mmm/
    status_path             /var/lib/misc/mmmd_mon.status
    ping_ips                10.100.1.1, 10.100.1.2, 10.100.1.3, 10.100.1.4
</monitor>
<host default>
    monitor_user            mmm_monitor
    monitor_password        RepMonitor
</host>
debug 0

Y cada de los servidores de mysql tendrá un mmm_agent.conf.


include mmm_common.conf
this db1

En cada host, se cambiará dbi por el nombre que corresponda.

Crear usuarios en Mysql

Hay que crear los siguiente usuarios:

GRANT REPLICATION CLIENT                 ON \*.* TO 'mmm_monitor'@'10.100.1.%' IDENTIFIED BY 'RepMonitor';
GRANT SUPER, REPLICATION CLIENT, PROCESS ON \*.* TO 'mmm_agent'@'10.100.1.%'   IDENTIFIED BY 'RepAgent';
GRANT REPLICATION SLAVE                  ON \*.* TO 'replication'@'10.100.1.%' IDENTIFIED BY 'slave';

- El usuario monitor se usa para comprobar el estado de los servidores Mysql.
- El usuario agent se usa para cambiar el read only mode, poner offline un equipo, ejecutar un change_master, etc.
- El usuario replication slave... para replicación ;)

Una vez todo configurado y montado, arrancarmos los servicios en cada host, uno el monitor y los demás los agentes.

Jugar con la consola

Una vez puesto en marcha todos los servidores saldrán en modo AWAITING_RECOVERY. La primera vez es necesario ponerlos online a mano:


MMM:~# mmm_control show
  db1(10.100.1.1) master/AWAITING_RECOVERY. Roles: 
  db2(10.100.1.2) master/AWAITING_RECOVERY. Roles: 
  db3(10.100.1.3) slave/AWAITING_RECOVERY. Roles: 
  db4(10.100.1.4) slave/AWAITING_RECOVERY. Roles:


Asi que los ponemos online :P

MMM:~# mmm_control set_online db1
OK: State of 'db1' changed to ONLINE. Now you can wait some time and check its new roles!
MMM:~# mmm_control set_online db2
OK: State of 'db2' changed to ONLINE. Now you can wait some time and check its new roles!
MMM:~# mmm_control set_online db3
OK: State of 'db3' changed to ONLINE. Now you can wait some time and check its new roles!
MMM:~# mmm_control set_online db4
OK: State of 'db4' changed to ONLINE. Now you can wait some time and check its new roles!

MMM:~# mmm_control show
  db1(10.100.1.1) master/ONLINE. Roles: writer(10.100.1.10)
  db2(10.100.1.2) master/ONLINE. Roles: 
  db3(10.100.1.3) slave/ONLINE. Roles: reader(10.100.1.12)
  db4(10.100.1.4) slave/ONLINE. Roles: reader(10.100.1.11)

Como podemos ver, ya están online. La IP virutal de escritura la tiene el nodo db1 mientras que los otros están en lectura. A partir de ahora el funcionamiento ya es automático. Si db1 se cae, la IP pasará a db2 y los esclavos db3 y db4 pasarán a tener como maestro a db2.

Si es necesario hacer alguna parada de servicio (cambiar hardware, mover el equipo de ubicación física, etc.) podemos dejar offline la máquina en cuestión de nuestro cluster. Por ejemplo, voy a dar de baja temporalmente db1:


MMM:~# mmm_control set_offline db1
OK: State of 'db1' changed to ADMIN_OFFLINE. Now you can wait some time and check all roles!


MMM:~# mmm_control show
  db1(10.100.1.1) master/ADMIN_OFFLINE. Roles: 
  db2(10.100.1.2) master/ONLINE. Roles: writer(10.100.1.10)
  db3(10.100.1.3) slave/ONLINE. Roles: reader(10.100.1.12)
  db4(10.100.1.4) slave/ONLINE. Roles: reader(10.100.1.11)

¿Mola verdad? Has parado un servidor maestro, no te has tenido que preocupar de los esclavos y ningún cliente se ha enterado de nada :)