ProxySQL - ein Tool zum Demultiplexen von Verbindungen

Hallo, mein Name ist Alexander Yakovlev, ich arbeite für Citimobil und operiere. Heute werde ich Ihnen von einem sehr interessanten ProxySQL-Produkt erzählen - es ist ein leistungsstarker MySQL-Proxy, der viele Dinge kann - Anfragen per Maske abfangen und töten, mit denen Sie nach SQL-Injection suchen, die Last duplizieren und vieles mehr können. Ich werde über unsere Erfahrungen mit ihm sprechen.
Früher oder später wird jedes große IT-Projekt, dessen Entwicklung mit zwei Servern begann, auf die unten beschriebene Situation stoßen. Stellen Sie sich vor, das Projekt hatte ursprünglich nur eine Datenbank - den Master-Server. Allmählich kamen ein paar Sklaven hinzu. Dann führten sie Scherben ein.

Und eines schönen Tages steigt die Last plötzlich um das Zehnfache. Zum Beispiel, weil Ihr Hauptkonkurrent gefallen ist und Kunden zu Ihnen geeilt sind. An diesem Punkt scheint es Ihnen, dass Sie die Last einfach durch Hinzufügen von Webservern skalieren können. Aber nachdem Sie dies getan haben, entsteht eine unangenehme Situation.

Betrachten Sie das Beispiel eines Assistenten. Angenommen, Sie haben 50 Webserver und alle 200 PHP-Fpm-Prozesse. Dann kommen 50 * 200 Verbindungen zum Master und zu diesem Zeitpunkt kommen 50 * 200 / Anzahl der Slaves zu jedem Slave (wenn natürlich Roundrobin in Haproxy konfiguriert ist) - siehe Abbildung unten. Natürlich sind 10 Tausend Verbindungen zum Master viel, aber immer noch erträglich, und wenn es 200 Websites gibt, ist die Anzahl der Verbindungen noch größer und eine Verbindung = ein Thread.
Es war in diesem Engpass, auf den wir gestoßen sind.

Bild

Dann haben wir angefangen zu streiten: Die Verbindung zum Assistenten ist immer im Code installiert, aber ist sie für alle fpm-Prozesse notwendig? Wahrscheinlich nicht. Wir haben festgestellt, dass eine große Anzahl von Persist-Verbindungen zum Master einfach in Slips hängen. Und sie beschlossen, dass wir Demultiplex brauchen.

Bild

Zu diesem Zweck haben wir auf ein Produkt namens ProxySQL aufmerksam gemacht. Es funktioniert wie ein normaler Reverse-Proxy: Es werden Verbindungen zu ihm hergestellt und der Datenverkehr wird gemäß bestimmten in der Konfiguration festgelegten Regeln neu verteilt.

Wir haben ProxySQL auf allen unseren Webservern installiert und in der Anwendungskonfiguration angegeben, dass der Aufruf der Master-Datenbank unter der Adresse 127.0.0.1 ausgeführt wird. Wenn vor 200 FPM-Mitarbeitern auf jedem Webserver 200 Verbindungen von diesem Computer zur Master-Basis bedeuteten, hat sich die Situation jetzt geändert. Diese 200 Verbindungen kommen in ProxySQL und 50-70 gehen zu unterschiedlichen Zeiten aus. Das heißt, ProxySQL kann vorhandene Verbindungen wiederverwenden.

Dank Demultiplexing haben wir die Anzahl der Verbindungen bei allen Mastern um das 3- bis 10-fache reduziert. Siehe das aktuelle Verbindungsdiagramm eines der Master unten.

Bild

Dank ProxySQL haben wir den oben genannten Engpass beseitigt. Dies ist jedoch nicht der einzige Workflow, den wir mit diesem Tool verbessert haben.
Wir haben den zweiten Prozess noch nicht abgeschlossen, stehen aber kurz vor dem Abschluss. Mit ProxySQL planen wir, die tatsächliche Last in der Testumgebung zu duplizieren. Dies ist erforderlich, um neue Funktionen im Kampfverkehr zu überprüfen.

Wie wird dies umgesetzt? Die Anwendung wechselt zu ProxySQL und sendet Datenverkehr auf zwei Wegen: an die Kampfdatenbanken, damit die Anwendung funktioniert, und an die Testumgebung, um unter Last nach neuen Funktionen zu suchen.

Das Merkmal von ProxySQL ist, dass es eine Konfiguration gibt, die in unserem Fall über Puppet bereitgestellt wird (für Puppet gibt es ein ProxySQL-Modul), aber es gibt auch das Konzept der Laufzeitzone, um Änderungen vorzunehmen (Server hinzufügen, Benutzer hinzufügen, Server und Benutzer löschen) ), Sie benötigen nicht den üblichen Neustart / Neuladen., Alles wird über die ProxySQL-Konsole erledigt, zum Beispiel so.

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

Im Detail natürlich in der offiziellen Dokumentation proxysql.com/documentation

Vielen Dank für Ihre Aufmerksamkeit.

Unsere Konfiguration, mit der wir das oben beschriebene Problem gelöst haben, siehe unten.

Unsere Konfiguration

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