ProxySQL: una herramienta para demultiplexar conexiones

Hola, mi nombre es Alexander Yakovlev, trabajo para Citimobil y opero. Hoy les contaré sobre un producto ProxySQL muy interesante: es un Proxy MySQL de alto rendimiento que puede hacer muchas cosas: capturar y matar solicitudes por máscara, con él puede buscar inyección SQL, duplicar la carga y mucho más. Hablaré de nuestra experiencia con él.
Tarde o temprano, cualquier gran proyecto de TI, cuyo desarrollo comenzó con un par de servidores, se encontrará con la situación que se describe a continuación. Imagine que el proyecto inicialmente solo tenía una base de datos: el servidor maestro. Gradualmente, se le agregaron un montón de esclavos. Luego introdujeron el fragmentación.

Y un buen día, la carga de repente aumenta 10 veces. Por ejemplo, porque su principal competidor ha caído y los clientes se han apresurado hacia usted. En este punto, le parece que simplemente puede escalar la carga agregando servidores web. Pero después de haber hecho esto, surge una situación desagradable.

Considere el ejemplo de un mago. Digamos que tiene 50 servidores web y en cada 200 procesos php-fpm. Luego, llegarán 50 * 200 conexiones al maestro, y a ese 50 * 200 / número de esclavos vendrá a cada esclavo (si, por supuesto, la roundrobin está configurada en haproxy) - vea la imagen a continuación. Por supuesto, 10 mil conexiones al maestro es mucho, pero aún soportable, y si hay 200 sitios web, el número de conexiones será aún mayor, y una conexión = un hilo.
Fue en este cuello de botella con el que nos encontramos.

imagen

Entonces comenzamos a discutir: la conexión al maestro siempre está instalada en el código, pero ¿es necesaria para todos los procesos de fpm? Probablemente no. Notamos que una gran cantidad de conexiones persistentes al maestro simplemente cuelgan en resbalones. Y decidieron que necesitamos demultiplexar.

imagen

Para hacer esto, llamamos la atención sobre un producto llamado ProxySQL. Funciona como un proxy inverso normal: se establecen conexiones y redistribuye el tráfico de acuerdo con ciertas reglas especificadas en la configuración.

Instalamos ProxySQL en todos nuestros servidores web, y en la configuración de la aplicación, especificamos que la llamada a la base de datos maestra se realiza en 127.0.0.1. Si antes de 200 trabajadores de FPM en cada servidor web significaba 200 conexiones a la base maestra desde esta máquina, ahora la situación ha cambiado. Estas 200 conexiones vienen en ProxySQL, y 50-70 salen en diferentes momentos. Es decir, ProxySQL puede reutilizar las conexiones existentes.

Gracias a la demultiplexación, redujimos el número de conexiones entre 3 y 10 veces en todos los maestros, consulte el gráfico de conexiones actuales de uno de los maestros a continuación.

imagen

Gracias a ProxySQL, nos deshicimos del cuello de botella anterior. Pero este no es el único flujo de trabajo que hemos mejorado con esta herramienta.
Todavía no hemos completado el segundo proceso, pero estamos muy cerca de finalizar. Con ProxySQL, planeamos duplicar la carga real en el entorno de prueba. Esto es necesario para verificar nuevas características con el tráfico de combate.

¿Cómo se implementará esto? La aplicación va a ProxySQL y envía tráfico a lo largo de dos rutas: a las bases de datos de batalla para que la aplicación funcione, y al entorno de prueba para verificar si hay nuevas características bajo carga.

La característica de ProxySQL es que existe su configuración, que en nuestro caso se implementa a través de Puppet (para Puppet hay un módulo ProxySQL), pero también existe el concepto de zona de tiempo de ejecución, para realizar un cambio (agregar servidor, agregar usuario, eliminar servidor y usuario ), no necesita el reinicio / recarga habitual. Todo se hace a través de la consola ProxySQL, por ejemplo, de esta manera.

mysql -ulogin -ppassword -h 127.0.0.1 -P6032 -e "INSERT INTO mysql_users(username,password,default_hostgroup) VALUES ('sm_username','pass',1);;LOAD MYSQL USERS TO RUNTIME;SAVE MYSQL USERS TO DISK;"

Más detalladamente, por supuesto, en la documentación oficial proxysql.com/documentation

Gracias por su atención.

Nuestra configuración, con la que resolvimos el problema descrito anteriormente, ver a continuación.

Nuestra config

datadir="/var/lib/proxysql"

admin_variables=
{
    admin_credentials="user:pass"
    mysql_ifaces="0.0.0.0:6032"
    refresh_interval=2000
    web_enabled=true
    web_port=6080
    stats_credentials="stats:admin"
}

mysql_variables =
{
    threads = 1000
    max_connections = 2000
    default_query_delay= 0
    default_query_timeout=1
    have_compress=true
    poll_timeout=2000
    interfaces="0.0.0.0:6033;/tmp/proxysql.sock"
    default_schema="information_schema"
    stacksize=1048576
    server_version="5.7.22"
    connect_timeout_server=10000
    monitor_history=60000
    monitor_connect_interval=200000
    monitor_ping_interval=200000
    ping_interval_server_msec=5000
    ping_timeout_server=200
    commands_stats=true
    sessions_sort=true
    monitor_username="root"
    monitor_password="password"
    monitor_galera_healthcheck_interval=200
    monitor_galera_healthcheck_timeout=80
}

mysql_servers =
(
  {
    address = "ip_real_mysql_server",
    port = 3306,
    max_connections = 10000,
    host_group = 1,
  })
mysql_users =
(
  {
    username = "user",
    password = "pass",
    default_hostgroup = 1,
    transaction_persistent = 0,
    active = 1,
  })

All Articles