Einen Load Balancer oder Reverse-Proxy vor Ihrem MySQL- oder MariaDB-Server zu haben, fügt Ihrem Datenbank-Setup ein wenig Komplexität hinzu, was dazu führen kann, dass sich einige Dinge anders verhalten. Theoretisch sollte ein Loadbalancer, der vor MySQL-Servern sitzt (zB ein HAProxy vor einem Galera-Cluster) nur wie ein Verbindungsmanager agieren und die Verbindungen zu den Backend-Servern nach einem Balancing-Algorithmus verteilen. MySQL hingegen hat seine eigene Art, Client-Verbindungen zu verwalten. Idealerweise müssten wir diese beiden Komponenten zusammen konfigurieren, um unerwartetes Verhalten zu vermeiden und die Fehlerbehebungsoberfläche beim Debuggen von Problemen einzugrenzen.
Wenn Sie eine solche Einrichtung haben, ist es wichtig, diese Komponenten zu verstehen, da sie sich auf die Gesamtleistung Ihres Datenbankdienstes auswirken können. In diesem Blogbeitrag werden wir uns mit max_connections von MySQL befassen und HAProxy maxconn Optionen bzw. Beachten Sie, dass die Zeitüberschreitung ein weiterer wichtiger Parameter ist, den wir kennen sollten, aber wir werden das in einem separaten Beitrag behandeln.
Maximale Verbindungen von MySQL
Zugehörige Ressourcen MySQL Load Balancing with HAProxy – Tutorial Webinar Replay and Q&A:how to deploy and manage ProxySQL, HAProxy and MaxScale Webinar Replay &Slides:How to build Scalable Database Infrastructures with MariaDB &HAProxyDie Anzahl der erlaubten Verbindungen zu einem MySQL-Server wird durch max_connections gesteuert Systemvariable. Der Standardwert ist 151 (MySQL 5.7).
Um eine gute Zahl für max_connections zu bestimmen , die Grundformeln sind:
Wo,
**Variable innodb_additional_mem_pool_size wird in MySQL 5.7.4+ entfernt. Wenn Sie die ältere Version verwenden, berücksichtigen Sie diese Variable.
Und,
Indem wir die obigen Formeln verwenden, können wir eine geeignete max_connections berechnen Wert für diesen bestimmten MySQL-Server. Um den Prozess zu starten, stoppen Sie alle Verbindungen von Clients und starten Sie den MySQL-Server neu. Stellen Sie sicher, dass zu diesem Zeitpunkt nur die minimale Anzahl von Prozessen ausgeführt wird. Sie können zu diesem Zweck 'mysqladmin' oder 'SHOW PROCESSLIST' verwenden:
$ mysqladmin -uroot -p processlist
+--------+------+-----------+------+---------+------+-------+------------------+----------+
| Id | User | Host | db | Command | Time | State | Info | Progress |
+--------+------+-----------+------+---------+------+-------+------------------+----------+
| 232172 | root | localhost | NULL | Query | 0 | NULL | show processlist | 0.000 |
+--------+------+-----------+------+---------+------+-------+------------------+----------+
1 row in set (0.00 sec)
Aus der obigen Ausgabe können wir erkennen, dass nur ein Benutzer mit dem MySQL-Server verbunden ist, der root ist. Rufen Sie dann den verfügbaren RAM (in MB) des Hosts ab (siehe Spalte „verfügbar“):
$ free -m
total used free shared buff/cache available
Mem: 3778 1427 508 148 1842 1928
Swap: 2047 4 2043
Nur zur Information, die Spalte 'verfügbar' gibt eine Schätzung, wie viel Speicher zum Starten neuer Anwendungen verfügbar ist, ohne Auslagerung (nur verfügbar in Kernel 3.14+).
Geben Sie dann den verfügbaren Speicher, 1928 MB, in der folgenden Anweisung an:
mysql> SELECT ROUND((1928 - (ROUND((@@innodb_buffer_pool_size + @@innodb_log_buffer_size + @@query_cache_size + @@tmp_table_size + @@key_buffer_size) / 1024 / 1024))) / (ROUND(@@read_buffer_size + @@read_rnd_buffer_size + @@sort_buffer_size + @@thread_stack + @@join_buffer_size + @@binlog_cache_size) / 1024 / 1024)) AS 'Possible Max Connections';
+--------------------------+
| Possible Max Connections |
+--------------------------+
| 265 |
+--------------------------+
**Variable innodb_additional_mem_pool_size wird in MySQL 5.7.4+ entfernt. Wenn Sie die ältere Version verwenden, berücksichtigen Sie diese Variable.
In diesem Beispiel können wir je nach verfügbarem RAM des Hosts bis zu 265 MySQL-Verbindungen gleichzeitig haben. Es macht keinen Sinn, einen höheren Wert zu konfigurieren. Fügen Sie dann die folgende Zeile in der MySQL-Konfigurationsdatei unter der Direktive [mysqld] hinzu:
max_connections = 265
Starten Sie den MySQL-Dienst neu, um die Änderung zu übernehmen. Wenn die Gesamtzahl der gleichzeitigen Verbindungen 265 erreicht, erhalten Sie beim Versuch, eine Verbindung zum mysqld-Server herzustellen, den Fehler „Zu viele Verbindungen“. Das bedeutet, dass alle verfügbaren Verbindungen von anderen Clients verwendet werden. MySQL erlaubt tatsächlich max_connections +1 Clients zum Verbinden. Die zusätzliche Verbindung ist für die Verwendung durch Konten reserviert, die über das SUPER-Privileg verfügen. Wenn Sie also auf diesen Fehler stoßen, sollten Sie versuchen, als Root-Benutzer (oder ein anderer SUPER-Benutzer) auf den Server zuzugreifen und sich die Prozessliste ansehen, um mit der Fehlerbehebung zu beginnen.
HAProxys maximale Verbindungen
HAProxy hat 3 Arten von maximalen Verbindungen (maxconn) - global, defaults/listen und default-server. Angenommen, eine HAProxy-Instanz, die mit zwei Listenern konfiguriert ist, einer für Multi-Writer-Listening auf Port 3307 (Verbindungen werden an alle Back-End-MySQL-Server verteilt) und einer als Single-Writer auf Port 3308 (Verbindungen werden an einen einzelnen MySQL-Server weitergeleitet):
global
...
maxconn 2000 #[a]
...
defaults
...
maxconn 3 #[b]
...
listen mysql_3307
...
maxconn 8 #[c]
balance leastconn
default-server port 9200 maxqueue 10 weight 10 maxconn 4 #[d]
server db1 192.168.55.171 check
server db2 192.168.55.172 check
server db3 192.168.55.173 check
listen mysql_3308
...
default-server port 9200 maxqueue 10 weight 10 maxconn 5 #[e]
server db1 192.168.55.171 check
server db2 192.168.55.172 check backup #[f]
Schauen wir uns die Bedeutung einiger Konfigurationszeilen an:
global.maxconn [a]
Die Gesamtzahl gleichzeitiger Verbindungen, die eine Verbindung zu dieser HAProxy-Instanz herstellen dürfen. Normalerweise ist dieser Wert der höchste Wert von allen. In diesem Fall akzeptiert HAProxy maximal 2000 Verbindungen gleichzeitig und verteilt sie an alle Listener, die im HAProxy-Prozess oder Worker definiert sind (Sie können mehrere HAProxy-Prozesse mit nbproc ausführen Option).
HAProxy akzeptiert keine Verbindungen mehr, wenn dieses Limit erreicht ist. Der Parameter „ulimit-n“ wird automatisch auf diesen Wert angepasst. Da Sockets aus der Systemperspektive als äquivalent zu Dateien angesehen werden, ist die Standardgrenze für Dateideskriptoren ziemlich gering. Wahrscheinlich möchten Sie das Standardlimit erhöhen, indem Sie den Kernel für Dateideskriptoren optimieren.
defaults.maxconn [b]
Legt den maximalen Verbindungswert für alle Listener fest. Es macht keinen Sinn, wenn dieser Wert höher als global.maxconn ist .
Wenn die Zeile „maxconn“ unter der Zeilengruppe „listen“ fehlt (listen.maxconn ), wird der Zuhörer diesen Wert befolgen. In diesem Fall erhält der Listener mysql_3308 maximal 3 Verbindungen gleichzeitig. Setzen Sie diesen Wert sicherheitshalber auf global.maxconn , dividiert durch die Anzahl der Zuhörer. Wenn Sie jedoch andere Listener priorisieren möchten, um mehr Verbindungen zu haben, verwenden Sie listen.maxconn stattdessen.
listen.maxconn [c]
Die maximal zulässigen Verbindungen für den entsprechenden Listener. Der Listener hat Vorrang vor defaults.maxconn falls angegeben. Es macht keinen Sinn, wenn dieser Wert höher als global.maxconn ist .
Für eine faire Verteilung von Verbindungen zu Backend-Servern wie im Fall eines Multi-Writer-Listeners (mysql_3307) setzen Sie diesen Wert auf listen.default-server.maxconn mit der Anzahl der Backend-Server multiplizieren. In diesem Beispiel sollte ein besserer Wert 12 statt 8 sein [c]. Wenn wir uns dafür entscheiden, bei dieser Konfiguration zu bleiben, wird erwartet, dass db1 und db2 jeweils maximal 3 Verbindungen erhalten, während db3 maximal 2 Verbindungen erhält (aufgrund des Leastconn-Ausgleichs), was insgesamt 8 Verbindungen ausmacht. Es wird das in [d] angegebene Limit nicht erreichen.
Für Single-Writer-Listener (mysql_3308), bei denen Verbindungen jeweils nur einem Backend-Server zugewiesen werden sollen, setzen Sie diesen Wert auf denselben oder einen höheren Wert als listen.default-server.maxconn .
listen.default-server.maxconn [d][e]
Dies ist die maximale Anzahl von Verbindungen, die jeder Back-End-Server gleichzeitig empfangen kann. Es macht keinen Sinn, wenn dieser Wert höher als listen.maxconn ist oder defaults.maxconn . Dieser Wert sollte kleiner oder gleich dem max_connections von MySQL sein Variable. Andernfalls riskieren Sie, dass die Verbindungen zum Backend-MySQL-Server erschöpft sind, insbesondere wenn die Timeout-Variablen von MySQL niedriger konfiguriert sind als die Timeouts von HAProxy.
In diesem Beispiel haben wir jeden MySQL-Server so eingestellt, dass er nur maximal 4 Verbindungen gleichzeitig für Multi-Writer-Galera-Knoten erhält [d]. Während der Single-Writer-Galera-Knoten aufgrund des Limits, das von [b] gilt, maximal 3 Verbindungen gleichzeitig erhält. Da wir "backup" [f] für den anderen Knoten angegeben haben, erhält der aktive Knoten sofort alle 3 Verbindungen, die diesem Listener zugewiesen sind.
Die obige Erklärung kann im folgenden Diagramm veranschaulicht werden:
Um die Verbindungsverteilung zusammenzufassen, wird erwartet, dass db1 eine maximale Anzahl von 6 Verbindungen erhält (3 von 3307 + 3 von 3308). db2 erhält 3 Verbindungen (es sei denn, db1 fällt aus, wo es weitere 3 erhält) und db3 bleibt bei 2 Verbindungen, unabhängig von Topologieänderungen im Cluster.
Verbindungsüberwachung mit ClusterControl
Mit ClusterControl können Sie die Nutzung von MySQL- und HAProxy-Verbindungen über die Benutzeroberfläche überwachen. Der folgende Screenshot bietet eine Zusammenfassung des MySQL-Verbindungsberaters (ClusterControl -> Performance -> Advisors), wo er die aktuellen und jemals verwendeten MySQL-Verbindungen für jeden Server im Cluster überwacht:
Für HAProxy lässt sich ClusterControl in die HAProxy-Statistikseite integrieren, um Metriken zu sammeln. Diese werden auf der Registerkarte "Knoten" angezeigt:
Aus dem obigen Screenshot können wir erkennen, dass jeder Backend-Server auf dem Multi-Writer-Listener maximal 8 Verbindungen erhält. Es laufen 4 Sitzungen gleichzeitig. Diese werden im oberen roten Quadrat hervorgehoben, während der Single-Writer-Listener 2 Verbindungen bedient und sie jeweils an einen einzelnen Knoten weiterleitet.
Schlussfolgerung
Das Konfigurieren der maximalen Verbindungen für HAProxy- und MySQL-Server ist wichtig, um eine gute Lastverteilung auf unsere Datenbankserver sicherzustellen und die MySQL-Server vor Überlastung oder Erschöpfung ihrer Verbindungen zu schützen.