Replicación con Multi-Threaded Slaves, sacando uso a nuestros cores
Ahora mismo, todos los servidores que compramos son multi-core o multi-cpu. MySQL ha ido solucionando sus problemas de escalabilidad, sobre todo a nivel del engine InnoDB, y la diferencia es clara entre MySQL 5.0 y MySQL 5.5, donde el rendimiento en entornos multicore es cada vez mayor. Pero aún queda un punto por mejorar, la replicación de MySQL.
En una replicación MySQL Master/Slave el problema se puede ver claramente. Mientras que en el maestro puedes tener cientos de threads modificando datos en paralelo, estos se escriben de forma ordenada en el binlog mientras que el slave, que solo tiene un thread para aplicar los cambios (SQL Thread), tiene que escribir los cambios uno a uno. De esta forma, el rendimiento que ganamos con la paralelización de las consultas, se pierden al llegar al Slave. Razón por la cual en entornos de alta carga siempre vemos que el esclavo va muy por detrás del Master aplicando los cambios (Seconds Behind Master).
Este es un problema que se está intentando solucionar en las versiones de desarrollo de MySQL. En la versión 5.6 se ha introducido un nuevo concepto llamado Workers, que son diferentes SQL Threads para la aplicación en paralelo de los cambios.

Podemos descargar una versión de desarrollo con esta funcionalidad desde http://labs.mysql.com/.
Con una serie nueva de parámetros que veremos a continuación podemos decirle a nuestro Slave cuantos Workers debe lanzar. Cada Worker podrá escribir los cambios del relaylog en paralelo, siempre y cuando pertenezcan a diferentes bases de datos. Por lo que de momento, para poder sacar beneficio a esta nueva funcionalidad, deberás tener diferentes bases de datos, cosa que es bastante habitual en entornos complejos donde el Sharding es la norma a seguir.
En primer lugar, debemos decirle a nuestro MySQL que ahora algunos de los estados relacionados con la replicación la queremos guardar en base de datos, concretamente en tablas dentro de la BD mysql:
relay-log-info-repository="TABLE" master-info-repository="TABLE"
relay-log-info-repository: esta variable indica donde se guardará la posición en la que nos encontramos dentro del relay log master-info-repository: esta variable indica donde se guardará la información referente a su master
Todas las opciones se encuentran ya documentadas en http://dev.mysql.com/doc/refman/5.6/en/replication-options-binary-log.html. Es recomendable tener esta URL a mano, ya que al ser algo que se encuentra en desarrollo, las especificaciones y las opciones cambian constantemente.
Una vez hecho, nos conectamos al Slave y le decimos que queremos cuatro Workers.
mysql> STOP SLAVE; Query OK, 0 rows affected (0.00 sec) mysql> SET GLOBAL slave_parallel_workers=4; Query OK, 0 rows affected (0.00 sec) mysql> SELECT @@slave_parallel_workers; +------------------------------+ | @@slave_parallel_workers | +------------------------------+ | 4 | +------------------------------+ 1 row in set (0.00 sec) mysql> START SLAVE; Query OK, 0 rows affected (0.05 sec)
A continuación comprobamos si realmente se han lanzado los 4 procesos:
mysql> show processlist; +----+-------------+------+---------+------+---------------------------------------------+ | Id | User | db | Command | Time | State | +----+-------------+------+---------+------+---------------------------------------------+ | 1 | root | NULL | Query | 0 | init | | 8 | system user | NULL | Connect | 2 | Waiting for master to send event | | 9 | system user | NULL | Connect | 2 | Slave has read all relay log; waiting [...] | | 10 | system user | NULL | Connect | 2 | Waiting for an event from sql thread | | 11 | system user | NULL | Connect | 2 | Waiting for an event from sql thread | | 12 | system user | NULL | Connect | 2 | Waiting for an event from sql thread | | 13 | system user | NULL | Connect | 2 | Waiting for an event from sql thread | +----+-------------+------+---------+------+---------------------------------------------+ 7 rows in set (0.00 sec)
Ahora mismo ya tenemos cuatro threads SQL para la aplicación de datos en paralelo. Como hemos comentado anteriormente, es posible aplicar cambios en paralelo siempre que estos sean de bases de datos diferentes. Por lo no tiene sentido que el número de threads que lancemos sea superior al del número de bases de datos que queremos replicar.
Esta es solo una más de las múltiples mejoras que se están implantando en la rama de desarrollo, intentaré manteneros informados de todas las novedades interesantes que sigan surgiendo :)







