ProxySQL - un outil pour démultiplexer les connexions

Bonjour, je m'appelle Alexander Yakovlev, je travaille pour Citimobil et j'exploite. Aujourd'hui, je vais vous parler d'un produit ProxySQL très intéressant - c'est un proxy MySQL haute performance qui peut faire beaucoup de choses - attraper et tuer les demandes par masque, avec lui, vous pouvez rechercher une injection SQL, dupliquer la charge et bien plus encore. Je vais parler de notre expérience avec lui.
Tôt ou tard, tout grand projet informatique, dont le développement a commencé avec une paire de serveurs, rencontrera la situation décrite ci-dessous. Imaginez que le projet n'avait initialement qu'une seule base de données - le serveur maître. Peu à peu, un tas d'esclaves y ont été ajoutés. Puis ils ont introduit le sharding.

Et un beau jour, la charge augmente soudainement 10 fois. Par exemple, parce que votre principal concurrent est tombé et que les clients se sont précipités vers vous. À ce stade, il vous semble que vous pouvez simplement faire évoluer la charge en ajoutant des serveurs Web. Mais après cela, une situation désagréable se présente.

Prenons l'exemple d'un assistant. Disons que vous avez 50 serveurs Web et tous les 200 processus php-fpm. Ensuite, 50 * 200 connexions arriveront au maître, et à ce 50 * 200 / nombre d'esclaves viendra à chaque esclave (si, bien sûr, roundrobin est configuré en haproxy) - voir l'image ci-dessous. Bien sûr, 10 000 connexions au maître, c'est beaucoup, mais toujours supportable, et s'il y a 200 sites Web, le nombre de connexions sera encore plus, et une connexion = un thread.
C'est dans ce goulot d'étranglement que nous nous sommes heurtés.

image

Ensuite, nous avons commencé à discuter: la connexion à l'assistant est toujours installée dans le code, mais est-elle nécessaire pour tous les processus fpm? Probablement pas. Nous avons remarqué qu'un grand nombre de connexions persistantes au maître se bloquent simplement par glissement. Et ils ont décidé que nous avions besoin du démultiplexage.

image

Pour ce faire, nous avons attiré l'attention sur un produit appelé ProxySQL. Il fonctionne comme un proxy inverse normal: des connexions y sont établies et il redistribue le trafic selon certaines règles spécifiées dans la configuration.

Nous avons installé ProxySQL sur tous nos serveurs Web, et dans la configuration de l'application, nous avons spécifié que l'appel à la base de données master est effectué à 127.0.0.1. Si avant 200 travailleurs FPM sur chaque serveur Web signifiaient 200 connexions à la base principale à partir de cette machine, la situation a maintenant changé. Ces 200 connexions proviennent de ProxySQL et 50 à 70 s'éteignent à des moments différents. Autrement dit, ProxySQL peut réutiliser les connexions existantes.

Grâce au démultiplexage, nous avons réduit le nombre de connexions de 3 à 10 fois sur tous les maîtres, voir le graphique des connexions actuelles de l'un des maîtres ci-dessous.

image

Grâce à ProxySQL, nous nous sommes débarrassés du goulot d'étranglement ci-dessus. Mais ce n'est pas le seul flux de travail que nous avons amélioré avec cet outil.
Nous n'avons pas encore achevé le deuxième processus, mais nous sommes très près de l'achèvement. En utilisant ProxySQL, nous prévoyons de dupliquer la charge réelle dans l'environnement de test. Cela est nécessaire pour vérifier les nouvelles fonctionnalités avec le trafic de combat.

Comment cela sera-t-il mis en œuvre? L'application va à ProxySQL, et elle envoie du trafic sur deux routes: aux bases de données de combat pour que l'application fonctionne, et à l'environnement de test pour vérifier les nouvelles fonctionnalités en cours de chargement.

La fonctionnalité de ProxySQL est qu'il y a sa configuration, qui dans notre cas est déployée via marionnette (pour marionnette il y a un module ProxySQL), mais il y a aussi le concept de la zone d'exécution, afin de faire un changement (ajouter un serveur, ajouter un utilisateur, supprimer un serveur et un utilisateur ), vous n'avez pas besoin du redémarrage / rechargement habituel., Tout se fait via la console ProxySQL, par exemple comme ceci.

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;"

Plus en détail, bien sûr, dans la documentation officielle proxysql.com/documentation

Merci de votre attention.

Notre configuration, avec laquelle nous avons résolu le problème décrit ci-dessus, voir ci-dessous.

Notre 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