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

Novedades de la replicación de MySQL en MySQL 8.0

La replicación en MySQL existe desde hace mucho tiempo y ha ido mejorando constantemente a lo largo de los años. Ha sido más una evolución que una revolución. Esto es perfectamente comprensible, ya que la replicación es una característica importante de la que muchos dependen:tiene que funcionar.

En las últimas versiones de MySQL, hemos visto mejoras en el rendimiento de la replicación a través del soporte para aplicar transacciones en paralelo. En MySQL 5.6, la paralelización se realizaba a nivel de esquema:todas las transacciones que se habían ejecutado en esquemas separados podían ejecutarse a la vez. Esta fue una buena mejora para aquellas cargas de trabajo que tenían múltiples esquemas en un solo servidor, y la carga se distribuyó de manera más o menos uniforme entre los esquemas.

En MySQL 5.7, se agregó otro método de paralelización, llamado "reloj lógico". Permitió obtener cierto nivel de concurrencia en un esclavo, incluso si todos sus datos se almacenaron en un solo esquema. Se basó, en resumen, en el hecho de que algunas transacciones se comprometían juntas debido a una latencia añadida por el hardware. Incluso podría agregar esa latencia manualmente, para lograr una mejor paralelización en los esclavos usando binlog_group_commit_sync_delay.

Esta solución fue realmente agradable pero no sin inconvenientes. Cada retraso en la confirmación de una transacción podría eventualmente afectar las partes de la aplicación que enfrentan los usuarios. Claro, puede establecer retrasos dentro de un rango de varios milisegundos, pero incluso entonces, es la latencia adicional lo que ralentiza la aplicación.

Mejoras en el rendimiento de la replicación en MySQL 8.0

MySQL 8.0, que a partir de ahora (agosto de 2017) todavía está en estado beta, trae algunas mejoras interesantes a la replicación. Originalmente, se desarrolló para Group Replication (GR), pero como GR utiliza la replicación regular bajo el capó, la replicación MySQL "normal" se benefició de ella. La mejora que mencionamos es la información de seguimiento de dependencias almacenada en el registro binario. Lo que sucede es que MySQL 8.0 ahora tiene una forma de almacenar información sobre qué filas se vieron afectadas por una transacción determinada (el llamado conjunto de escritura), y compara los conjuntos de escritura de diferentes transacciones. Esto permite identificar aquellas transacciones que no trabajaron en el mismo subconjunto de filas y, por lo tanto, se pueden aplicar en paralelo. Esto puede permitir aumentar el nivel de paralelización varias veces en comparación con la implementación de MySQL 5.7. Lo que debe tener en cuenta es que, eventualmente, un esclavo verá una vista diferente de los datos, una que nunca apareció en el maestro. Esto se debe a que las transacciones pueden aplicarse en un orden diferente al del maestro. Sin embargo, esto no debería ser un problema. La implementación actual de la replicación multiproceso en MySQL 5.7 también puede causar este problema, a menos que habilite explícitamente el orden de confirmación de esclavos.

Para controlar este nuevo comportamiento, una variable binlog_transaction_dependency_tracking ha sido introducido. Puede tomar tres valores:

  • COMMIT_ORDER:este es el predeterminado, utiliza el mecanismo predeterminado disponible en MySQL 5.7.
  • WRITESET:permite una mejor paralelización y el maestro comienza a almacenar los datos del conjunto de escritura en un registro binario.
  • WRITESET_SESSION:esto garantiza que las transacciones se ejecutarán en el esclavo en orden y se elimina el problema con un esclavo que ve un estado de base de datos que nunca se vio en el maestro. Reduce la paralelización, pero aún puede proporcionar un mejor rendimiento que la configuración predeterminada.

Valor de referencia

En julio, en mysqlhighavailability.com, Vitor Oliveira escribió una publicación en la que intentaba medir el rendimiento de los nuevos modos. Usó el mejor de los casos, sin durabilidad alguna, para mostrar la diferencia entre los modos antiguo y nuevo. Decidimos usar el mismo enfoque, esta vez en una configuración más real:registro binario habilitado con log_slave_updates. La configuración de durabilidad se dejó por defecto (por lo tanto, sync_binlog=1 - ese es el nuevo valor predeterminado en MySQL 8.0, el búfer de doble escritura habilitado, las sumas de verificación de InnoDB habilitadas, etc.) La única excepción en la durabilidad fue innodb_flush_log_at_trx_commit establecido en 2.

Usamos instancias m4.2xl, 32G, 8 núcleos (por lo que slave_parallel_workers se configuró en 8). También usamos el script sysbench, oltp_read_write.lua. Se almacenaron 16 millones de filas en 32 tablas en un volumen gp2 de 1000 GB (eso es 3000 IOPS). Probamos el rendimiento de todos los modos para 1, 2, 4, 8, 16 y 32 conexiones sysbench simultáneas. El proceso fue el siguiente:detenga el esclavo, ejecute 100k transacciones, inicie el esclavo y calcule cuánto tiempo lleva eliminar el retraso del esclavo.

En primer lugar, no sabemos realmente qué sucedió cuando se ejecutó sysbench usando solo 1 subproceso. Cada prueba se ejecutó cinco veces después de una carrera de calentamiento. Esta configuración en particular se probó dos veces; los resultados son estables:la carga de trabajo de subproceso único fue la más rápida. Seguiremos investigando para entender qué sucedió.

Aparte de eso, el resto de los resultados están en línea con lo que esperábamos. COMMIT_ORDER es el más lento, especialmente para poco tráfico, 2-8 subprocesos. WRITESET_SESSION suele funcionar mejor que COMMIT_ORDER, pero es más lento que WRITESET para tráfico concurrente bajo.

¿Cómo me puede ayudar?

La primera ventaja es obvia:si su carga de trabajo es lenta pero sus esclavos tienden a retroceder en la replicación, pueden beneficiarse de un mejor rendimiento de replicación tan pronto como el maestro se actualice a 8.0. Dos notas aquí:primero:esta función es compatible con versiones anteriores y los esclavos 5.7 también pueden beneficiarse de ella. En segundo lugar, un recordatorio de que 8.0 aún se encuentra en estado beta, no lo alentamos a usar el software beta en producción, aunque es una necesidad urgente, esta es una opción para probar. Esta característica puede ayudarlo no solo cuando sus esclavos están retrasados. Es posible que estén completamente al día, pero cuando crea un nuevo esclavo o vuelve a aprovisionar uno existente, ese esclavo se retrasará. Tener la capacidad de usar el modo "WRITESET" hará que el proceso de aprovisionamiento de un nuevo host sea mucho más rápido.

Con todo, esta característica tendrá un impacto mucho mayor de lo que piensas. Teniendo en cuenta todos los puntos de referencia que muestran regresiones en el rendimiento cuando MySQL maneja tráfico de baja concurrencia, cualquier cosa que pueda ayudar a acelerar la replicación en tales entornos es una gran mejora.

Si usa maestros intermedios, esta también es una característica que debe buscar. Cualquier maestro intermedio agrega algo de serialización sobre cómo se manejan y ejecutan las transacciones; en el mundo real, la carga de trabajo en un maestro intermedio casi siempre será menos paralela que en el maestro. El uso de conjuntos de escritura para permitir una mejor paralelización no solo mejora la paralelización en el maestro intermedio, sino que también puede mejorar la paralelización en todos sus esclavos. Incluso es posible (aunque requeriría pruebas serias para verificar que todas las piezas encajen correctamente) usar un maestro intermedio 8.0 para mejorar el rendimiento de replicación de sus esclavos (tenga en cuenta que el esclavo MySQL 5.7 puede comprender los datos del conjunto de escritura y usarlos aunque no puede generarlo por sí mismo). Por supuesto, replicar de 8.0 a 5.7 suena bastante complicado (y no es solo porque 8.0 todavía es una versión beta). En algunas circunstancias, esto puede funcionar y puede acelerar la utilización de la CPU en sus esclavos 5.7.

Otros cambios en la replicación de MySQL

La introducción de los conjuntos de escritura, si bien es lo más interesante, no es el único cambio que le sucedió a la replicación de MySQL en MySQL 8.0. Veamos algunos otros cambios también importantes. Si usa un maestro anterior a MySQL 5.0, 8.0 no admitirá su formato de registro binario. No esperamos ver muchas configuraciones de este tipo, pero si usa un MySQL muy antiguo con replicación, definitivamente es el momento de actualizar.

Los valores predeterminados han cambiado para garantizar que la replicación sea lo más segura posible:master_info_repository y relay_log_info_repository se establecen en TABLE. Expire_log_days también se ha cambiado; ahora el valor predeterminado es 30. Además de expire_log_days , se ha agregado una nueva variable, binlog_expire_log_seconds , que permite una política de rotación binlog más detallada. Se agregaron algunas marcas de tiempo adicionales al registro binario para mejorar la observabilidad del retraso de replicación, introduciendo una granularidad de microsegundos.

Por supuesto, esta no es una lista completa de cambios y funciones relacionadas con la replicación de MySQL. Si desea obtener más información, puede consultar los registros de cambios de MySQL. Asegúrese de revisarlos todos; hasta ahora, se han agregado funciones en todas las versiones 8.0.

Como puede ver, la replicación de MySQL sigue cambiando y mejorando. Como dijimos al principio, tiene que ser un proceso lento, pero es realmente genial ver lo que está por venir. También es agradable ver que el trabajo para la replicación de grupos se filtra y se reutiliza en la replicación de MySQL "normal".