Una nueva herramienta para resolver tus problemas de escalabilidad de MySQL

Desde que existió la replicación de MySQL, la gente soñó con una buena solución para distribuir automáticamente la lectura de las operaciones de escritura mediante el envío de scripts al maestro de MySQL y el equilibrio de la carga de lectura en un conjunto de esclavos de MySQL. Si bien al principio parece fácil de resolver, la realidad es mucho más compleja.

Primero, la herramienta debe asegurarse de analizar y analizar correctamente todas las formas de soporte de SQL MySQL para poder leer por escribir, algo que no es tan fácil como parece. En segundo lugar, debemos considerar si una sesión está en una transacción o no.

Mientras está en una transacción, el nivel de aislamiento de transacción predeterminado en InnoDB, lectura repetible y el marco MVCC garantiza que obtenga una vista coherente durante la transacción. Esto significa que todas las declaraciones ejecutadas en una transacción deben ejecutarse en el maestro, pero, cuando la transacción se confirma o retrocede, las siguientes declaraciones seleccionadas en la sesión se pueden volver a cargar balanceadas en los esclavos, si la sesión está en modo. por supuesto.

Entonces, ¿qué haces con las sesiones que establecen variables? ¿Limita estas sesiones al maestro o se las repite al esclavo? Si está recuperando los comandos variables establecidos, debe asociar la conexión del cliente con un conjunto de conexiones backend de MySQL, compuesto por al menos un maestro y un esclavo. ¿Qué pasa con los objetos temporales como «crear una tabla temporal…»? ¿Qué pasa cuando un esclavo llega tarde o si empeora, la replicación se interrumpe? Estos son solo algunos de los desafíos a los que te enfrentas cuando quieres construir una herramienta para hacer la división de lectura/escritura.

En los últimos años, una serie de productos han intentado hacer frente al desafío de dividir la lectura/escritura. MySQL_proxy fue el primer intento conocido de resolver este problema, pero terminó con algunas limitaciones. ScaleARC hace un trabajo mucho mejor y es muy útil, pero aún tiene algunas limitaciones. El último competidor es MaxScale de MariaDB y esta publicación es una hoja de ruta de mi primera implementación de MaxScale para un cliente.

Permítanme presentarles primero qué es exactamente MaxScale. MaxScale es un proyecto de código abierto, desarrollado por MariaDB, que pretende ser un proxy modular para MySQL. La mayor parte de la funcionalidad de MaxScale se implementa como módulos, que incluyen, por ejemplo, módulos para el protocolo MySQL, el cliente y el servidor.

Otras familias de módulos disponibles incluyen enrutadores, monitores y filtros. Los enrutadores se utilizan para determinar dónde enviar una solicitud, la división de lectura/escritura la realiza el enrutador readwritesplit. El enrutador readwritesplit utiliza un servidor MySQL integrado para analizar consultas… lo suficientemente inteligente y difícil de superar en términos de análisis de consultas.

Hay otros enrutadores disponibles, el enrutador readconn es básicamente un equilibrador de carga de turnos con pesos opcionales, el enrutador esquema es una forma de distribuir sus datos por esquema y el enrutador binlog es útil para manejar una gran cantidad de esclavos (consulte Booking .Conversation of Jean-François Gagné de .com en PLMCE15 para ver cómo se puede utilizar).

Los monitores son módulos que contienen información en los servidores backend de MySQL. Hay monitores para la configuración de replicación, para Galera y para el clúster NDB. Finalmente, los filtros son módulos que se pueden insertar en la pila de software para manipular consultas y resultados. Todos esos módulos tienen API bien definidas y, por lo tanto, escribir un módulo personalizado es bastante fácil, incluso para alguien que no es desarrollador como yo, se requieren habilidades básicas de C. Todo el manejo de eventos de MaxScale usa epoll y admite varios subprocesos.

En los últimos meses he estado trabajando con un cliente que tiene un problema desafiante. En un clúster PXC, tienen más de 30 000 consultas/s y, debido a su modelo de escritura y para evitar problemas de certificación, quieren poder escribir en un solo nodo y equilibrar la carga de lectura. La aplicación no puede realizar la división de lectura/escritura, por lo que sin una herramienta de división, solo se puede usar un nodo para todo el tráfico. Por supuesto, para facilitar las cosas, usan mucho código Java que configura toneladas de variables de sesión. Además, para cumplir con la norma ISO 27001, quieren poder registrar todas las solicitudes de análisis de seguridad (y también de análisis de rendimiento, ¿por qué no?). Por lo tanto, alta tasa de consultas, división de lectura/escritura y registro completo de consultas, como dije, un problema desafiante.

Probamos algunas soluciones. Uno era un equilibrador de carga de hardware que falló miserablemente: la implementación era demasiado simple y solo usaba expresiones regulares. Otra solución que probamos fue ScaleArc, pero necesitaba algunas reglas para incluir en la lista blanca las variables de sesión establecidas y repetirlas en varios servidores. ScaleArc podría haber hecho el trabajo, pero todas las reglas aumentan la carga de la CPU y el costo es por CPU. Las consultas pueden enviarse a rsyslog y agregarse para su análisis.

Finalmente, la implementación de HA es bastante minimalista y tuvimos algunos problemas con ella. A continuación, probamos MaxScale. En ese momento, no era GA y era (todavía) joven. Sin embargo, he escrito un módulo de filtro de registro de consultas para enviar todas las consultas a Kafka clúster y lo intentamos. Kafka es extremadamente adecuado para registrar un flujo tan grande de preguntas. De hecho, a 30k qps, los 3 nodos de Kafka apenas se mueven con CPU por debajo del 5% de un núcleo. Incluso si encontramos algunos problemas, recuerde que MaxScale es muy joven, parecía ser la solución con el mejor potencial y así seguimos adelante.

La gente de MariaDB detrás de MaxScale ha respondido muy bien a los problemas que hemos encontrado y finalmente hemos llegado a un punto muy útil y la prueba en el entorno piloto ha sido exitosa. La solución se ha implementado en el entorno de ensayo y, si todo va bien, pronto estará en producción. La siguiente figura muestra una vista simplificada del interior de MaxScale configurado para el cliente:

Casi todos los bloques de la figura están definidos en el archivo de configuración. Definimos un oyente TCP utilizando el protocolo MySQL (lado del cliente) que está vinculado a un enrutador, o un enrutador readwritesplit o un enrutador readconn.

El primer paso al enrutar una solicitud es asignar backends. Aquí es donde se toma la decisión de dividir lectura/escritura. Además, como parte de los pasos necesarios para atender una solicitud, se llaman 2 filtros, regexp (opcional) y Genlog. El filtro regexp se puede usar para parchear una aplicación y el filtro Genlog es el filtro de registro que escribí para ellos. El filtro Genlog enviará una cadena json que contiene lo que se puede encontrar en el registro general de consultas de MySQL más el tiempo de ejecución.

También se registran los intentos de autenticación, pero el proceso no se muestra en la figura. Un punto clave a tener en cuenta es que MaxScale almacena en caché la información de autenticación y se actualiza después de que falla la autenticación, el proceso de actualización se acelera para evitar sobrecargar los servidores back-end. Los servidores se monitorean continuamente, el intervalo es ajustable y el estado del servidor se usa cuando se toma la decisión de asignar un backend para una solicitud.

En términos de alta disponibilidad, he escrito un agente de recursos Pacemaker simple para MaxScale que hace algunas cosas fantásticas, como equilibrar la carga con IPTables (hablaré de eso en la próxima publicación). Con Pacemaker, tenemos una solución HA completa con un quórum y una pantalla en los que podemos confiar.

En términos de rendimiento, es muy bueno: un solo núcleo en un entorno virtual pudo leer/escribir dividir y iniciar sesión en Kafka a unas 10 000 consultas por segundo. Aunque MaxScale admite varios subprocesos, seguimos utilizando un solo subproceso por proceso, simplemente porque ofrece un rendimiento ligeramente superior y el agente Pacemaker personalizado maneja el uso de un conjunto de clones de instancias de MaxScale. Recuerde que primero comenzamos a usar MaxScale y las versiones beta no fueron manejadas con gracia por los cables, por lo que lo creamos con varias instancias únicas.

Entonces, dado que se necesita una conclusión, MaxScale ha demostrado ser una herramienta muy útil y flexible que le permite desarrollar soluciones a problemas que antes eran muy difíciles de tratar. En particular, si necesita hacer la división de lectura/escritura, pruebe MaxScale, es la mejor solución para este propósito que he encontrado hasta ahora. Mantente en contacto, definitivamente escribiré más publicaciones sobre MaxScale en un futuro cercano.

Author: Ing. Luis

A lo largo de conocer Windows y otros sistemas operativos me eh encontrado con diversos tipos de error, ahora brindo soluciones según mi experiencia-

Deja un comentario