Mysql
 sql >> Datenbank >  >> RDS >> Mysql

So clustern Sie Ihre ProxySQL-Load-Balancer

Eine Proxy-Schicht zwischen Anwendungen und Datenbanken besteht normalerweise aus mehreren Proxy-Knoten für hohe Verfügbarkeit. Dies ist bei ProxySQL nicht anders. ProxySQL kann, genau wie andere moderne Proxys, verwendet werden, um komplexe Logik für das Routing von Abfragen zu erstellen. Sie können Abfrageregeln hinzufügen, um Abfragen an bestimmte Hosts zu senden, Sie können Abfragen zwischenspeichern, Backend-Server hinzufügen und entfernen oder Benutzer verwalten, die eine Verbindung zu ProxySQL und MySQL herstellen dürfen. Zahlreiche ProxySQL-Knoten in der Proxy-Schicht führen jedoch zu einem weiteren Problem – der Synchronisierung über verteilte Instanzen hinweg. Alle Regeln oder andere Logik müssen über Instanzen hinweg synchronisiert werden, um sicherzustellen, dass sie sich gleich verhalten. Auch wenn nicht alle Proxys den Datenverkehr verarbeiten, funktionieren sie dennoch als Standby. Für den Fall, dass sie die Arbeit übernehmen müssen, möchten Sie keine Überraschungen erleben, wenn die verwendete Instanz nicht über die neuesten Konfigurationsänderungen verfügt.

Es ist ziemlich umständlich, dies manuell sicherzustellen - die Änderungen von Hand auf allen Knoten vorzunehmen. Sie können Tools wie Ansible, Chef oder Puppet verwenden, um Konfigurationen zu verwalten, aber der Synchronisierungsprozess muss codiert und getestet werden. ClusterControl kann Ihnen hier durch eine Option zum Synchronisieren von Konfigurationen zwischen ProxySQL-Instanzen helfen, aber es kann auch die anderen Komponenten einrichten und verwalten, die für Hochverfügbarkeit erforderlich sind, z. B. virtuelle IP. Aber ab Version 1.4.2 bietet ProxySQL einen nativen Clustering- und Konfigurationssynchronisierungsmechanismus. In diesem Blog-Beitrag werden wir erörtern, wie Sie es mit einer Mischung aus Aktionen einrichten, die in der ClusterControl- und ProxySQL-Befehlszeilen-Verwaltungsschnittstelle ausgeführt werden.

Lassen Sie uns zunächst einen Blick auf eine typische Replikationsumgebung werfen, die von ClusterControl bereitgestellt wird.

Wie Sie dem Screenshot entnehmen können, handelt es sich um eine MySQL-Replikationseinrichtung mit drei ProxySQL-Instanzen. ProxySQL-Hochverfügbarkeit wird durch Keepalived und Virtual IP implementiert, das immer einem der ProxySQL-Knoten zugewiesen wird. Es gibt ein paar Schritte, die wir ausführen müssen, um das ProxySQL-Clustering zu konfigurieren. Zuerst müssen wir definieren, welchen Benutzer ProxySQL verwenden soll, um Informationen zwischen den Knoten auszutauschen. Lassen Sie uns einen neuen über dem bestehenden administrativen Benutzer definieren:

Als nächstes müssen wir diesen Benutzer in den Einstellungen admin-cluster_password und admin-cluster_username definieren.

Dies wurde nur auf einem der Knoten (10.0.0.126) durchgeführt. Lassen Sie uns diese Konfigurationsänderung mit den verbleibenden ProxySQL-Knoten synchronisieren.

Wie bereits erwähnt, können Sie mit ClusterControl die Konfiguration zwischen ProxySQL-Knoten in nur wenigen Schritten synchronisieren. Wenn der Job die Synchronisierung von 10.0.0.127 mit 10.0.0.126 beendet hat, gibt es nur noch den letzten Knoten, den wir synchronisieren müssen.

Danach müssen wir eine kleine Änderung in der administrativen ProxySQL-Befehlszeilenschnittstelle vornehmen, die normalerweise über Port 6032 erreichbar ist. Wir müssen Einträge in der Tabelle „proxysql_servers“ erstellen, die die Knoten in unserem ProxySQL-Cluster definieren würden.

mysql> INSERT INTO proxysql_servers (hostname) VALUES ('10.0.0.126'), ('10.0.0.127'), ('10.0.0.128');
Query OK, 3 rows affected (0.00 sec)
mysql> LOAD PROXYSQL SERVERS TO RUNTIME;
Query OK, 0 rows affected (0.01 sec)
mysql> SAVE PROXYSQL SERVERS TO DISK;
Query OK, 0 rows affected (0.01 sec)

Nach dem Laden der Änderung zur Laufzeit sollte ProxySQL mit der Synchronisierung der Knoten beginnen. Es gibt einige Stellen, an denen Sie den Status des Clusters verfolgen können.

mysql> SELECT * FROM stats_proxysql_servers_checksums;
+------------+------+-------------------+---------+------------+--------------------+------------+------------+------------+
| hostname   | port | name              | version | epoch      | checksum           | changed_at | updated_at | diff_check |
+------------+------+-------------------+---------+------------+--------------------+------------+------------+------------+
| 10.0.0.128 | 6032 | admin_variables   | 0       | 0          |                    | 0          | 1539773916 | 0          |
| 10.0.0.128 | 6032 | mysql_query_rules | 2       | 1539772933 | 0x3FEC69A5C9D96848 | 1539773546 | 1539773916 | 0          |
| 10.0.0.128 | 6032 | mysql_servers     | 4       | 1539772933 | 0x3659DCF3E53498A0 | 1539773546 | 1539773916 | 0          |
| 10.0.0.128 | 6032 | mysql_users       | 2       | 1539772933 | 0xDD5F0BB01235E930 | 1539773546 | 1539773916 | 0          |
| 10.0.0.128 | 6032 | mysql_variables   | 0       | 0          |                    | 0          | 1539773916 | 0          |
| 10.0.0.128 | 6032 | proxysql_servers  | 2       | 1539773835 | 0x8EB13E2B48C3FDB0 | 1539773835 | 1539773916 | 0          |
| 10.0.0.127 | 6032 | admin_variables   | 0       | 0          |                    | 0          | 1539773916 | 0          |
| 10.0.0.127 | 6032 | mysql_query_rules | 3       | 1539773719 | 0x3FEC69A5C9D96848 | 1539773546 | 1539773916 | 0          |
| 10.0.0.127 | 6032 | mysql_servers     | 5       | 1539773719 | 0x3659DCF3E53498A0 | 1539773546 | 1539773916 | 0          |
| 10.0.0.127 | 6032 | mysql_users       | 3       | 1539773719 | 0xDD5F0BB01235E930 | 1539773546 | 1539773916 | 0          |
| 10.0.0.127 | 6032 | mysql_variables   | 0       | 0          |                    | 0          | 1539773916 | 0          |
| 10.0.0.127 | 6032 | proxysql_servers  | 2       | 1539773812 | 0x8EB13E2B48C3FDB0 | 1539773813 | 1539773916 | 0          |
| 10.0.0.126 | 6032 | admin_variables   | 0       | 0          |                    | 0          | 1539773916 | 0          |
| 10.0.0.126 | 6032 | mysql_query_rules | 1       | 1539770578 | 0x3FEC69A5C9D96848 | 1539773546 | 1539773916 | 0          |
| 10.0.0.126 | 6032 | mysql_servers     | 3       | 1539771053 | 0x3659DCF3E53498A0 | 1539773546 | 1539773916 | 0          |
| 10.0.0.126 | 6032 | mysql_users       | 1       | 1539770578 | 0xDD5F0BB01235E930 | 1539773546 | 1539773916 | 0          |
| 10.0.0.126 | 6032 | mysql_variables   | 0       | 0          |                    | 0          | 1539773916 | 0          |
| 10.0.0.126 | 6032 | proxysql_servers  | 2       | 1539773546 | 0x8EB13E2B48C3FDB0 | 1539773546 | 1539773916 | 0          |
+------------+------+-------------------+---------+------------+--------------------+------------+------------+------------+
18 rows in set (0.00 sec)

Die Tabelle stats_proxysql_servers_checksums enthält unter anderem eine Liste der Knoten im Cluster, synchronisierte Tabellen, Versionen und Prüfsummen der Tabelle. Wenn die Prüfsumme nicht übereinstimmt, versucht ProxySQL, die neueste Version von einem Cluster-Peer abzurufen. Ausführlichere Informationen zum Inhalt dieser Tabelle finden Sie in der ProxySQL-Dokumentation.

Eine weitere Informationsquelle über den Prozess ist das Protokoll von ProxySQL (standardmäßig befindet es sich in /var/lib/proxysql/proxysql.log).

2018-10-17 11:00:25 [INFO] Cluster: detected a new checksum for mysql_query_rules from peer 10.0.0.126:6032, version 2, epoch 1539774025, checksum 0xD615D5416F61AA72 . Not syncing yet …
2018-10-17 11:00:27 [INFO] Cluster: detected a peer 10.0.0.126:6032 with mysql_query_rules version 2, epoch 1539774025, diff_check 3. Own version: 2, epoch: 1539772933. Proceeding with remote sync
2018-10-17 11:00:28 [INFO] Cluster: detected a peer 10.0.0.126:6032 with mysql_query_rules version 2, epoch 1539774025, diff_check 4. Own version: 2, epoch: 1539772933. Proceeding with remote sync
2018-10-17 11:00:28 [INFO] Cluster: detected peer 10.0.0.126:6032 with mysql_query_rules version 2, epoch 1539774025
2018-10-17 11:00:28 [INFO] Cluster: Fetching MySQL Query Rules from peer 10.0.0.126:6032 started
2018-10-17 11:00:28 [INFO] Cluster: Fetching MySQL Query Rules from peer 10.0.0.126:6032 completed
2018-10-17 11:00:28 [INFO] Cluster: Loading to runtime MySQL Query Rules from peer 10.0.0.126:6032
2018-10-17 11:00:28 [INFO] Cluster: Saving to disk MySQL Query Rules from peer 10.0.0.126:6032

Wie Sie sehen können, haben wir hier Informationen darüber, dass eine neue Prüfsumme erkannt wurde und der Synchronisierungsprozess in Kraft ist.

Lassen Sie uns hier einen Moment innehalten und diskutieren, wie ProxySQL Konfigurationsaktualisierungen aus mehreren Quellen handhabt. Zunächst verfolgt ProxySQL Prüfsummen, um zu erkennen, wenn sich eine Konfiguration geändert hat. Es speichert auch, wann es passiert ist - diese Daten werden als Zeitstempel gespeichert, haben also eine Auflösung von einer Sekunde. ProxySQL hat zwei Variablen, die sich auch darauf auswirken, wie Änderungen synchronisiert werden.

Cluster_check_interval_ms – bestimmt, wie oft ProxySQL nach Konfigurationsänderungen suchen soll. Standardmäßig sind es 1000 ms.

Cluster_mysql_servers_diffs_before_sync – teilt uns mit, wie oft eine Prüfung eine Konfigurationsänderung erkennen soll, bevor sie synchronisiert wird. Die Standardeinstellung ist 3.

Das bedeutet, dass, selbst wenn Sie eine Konfigurationsänderung auf demselben Host vornehmen, diese weniger als 4 Sekunden dauert, die verbleibenden ProxySQL-Knoten möglicherweise nicht in der Lage sind, sie zu synchronisieren, da eine neue Änderung vor der vorherigen angezeigt wird synchronisiert wurde. Das bedeutet auch, dass Sie, wenn Sie Konfigurationsänderungen an mehreren ProxySQL-Instanzen vornehmen, diese mit einer Pause von mindestens 4 Sekunden dazwischen vornehmen sollten, da sonst einige der Änderungen verloren gehen und die Konfigurationen daher auseinanderlaufen. Beispielsweise fügen Sie Server1 auf Proxy1 hinzu und nach 2 Sekunden fügen Sie Server2 auf Proxy2 hinzu. Alle anderen Proxys lehnen die Änderung an Proxy1 ab, da sie erkennen, dass Proxy2 eine neuere Konfiguration hat. 4 Sekunden nach der Änderung auf Proxy2 ziehen alle Proxys (einschließlich Proxy1) die Konfiguration von Proxy2.

Da die Intra-Cluster-Kommunikation nicht synchron ist und ein ProxySQL-Knoten, an dem Sie die Änderungen vorgenommen haben, fehlschlägt, werden Änderungen möglicherweise nicht rechtzeitig repliziert. Der beste Ansatz besteht darin, dieselbe Änderung auf zwei ProxySQL-Knoten vorzunehmen. Auf diese Weise kann einer von ihnen eine neue Konfiguration verbreiten, es sei denn, beide schlagen genau gleichzeitig fehl.

Erwähnenswert ist auch, dass die ProxySQL-Clustertopologie sehr flexibel sein kann. In unserem Fall haben wir drei Knoten, alle haben drei Einträge in der Proxysql_servers-Tabelle. Solche Knoten bilden den Cluster, in dem Sie auf jeden Knoten schreiben können und die Änderungen weitergegeben werden. Darüber hinaus ist es möglich, externe Knoten hinzuzufügen, die im „Nur-Lese“-Modus arbeiten würden, was bedeutet, dass sie nur Änderungen am „Kern“-Cluster synchronisieren, aber keine direkt durchgeführten Änderungen weitergeben auf sich selbst. Alles, was Sie auf dem neuen Knoten brauchen, ist, dass nur die „Kern“-Cluster-Knoten in „proxysql_servers“ konfiguriert sind, und als Ergebnis stellt er eine Verbindung zu diesen Knoten her und erhält die Datenänderungen, aber er wird nicht vom Rest des Clusters abgefragt für seine Konfigurationsänderungen. Dieses Setup könnte verwendet werden, um eine Source of Truth mit mehreren Knoten im Cluster und anderen ProxySQL-Knoten zu erstellen, die nur die Konfiguration vom Haupt-„Kern“-Cluster erhalten.

Darüber hinaus unterstützt der ProxySQL-Cluster das automatische Wiederverknüpfen der Knoten – sie synchronisieren ihre Konfiguration beim Start. Es kann auch einfach skaliert werden, indem weitere Knoten hinzugefügt werden.

Wir hoffen, dass dieser Blogbeitrag Ihnen einen Einblick gibt, wie ProxySQL-Cluster konfiguriert werden können. Der ProxySQL-Cluster ist für ClusterControl transparent und wirkt sich nicht auf die Vorgänge aus, die Sie möglicherweise über die ClusterControl-Benutzeroberfläche ausführen möchten.