Het hebben van een load balancer of reverse proxy voor uw MySQL- of MariaDB-server voegt een beetje complexiteit toe aan uw databaseconfiguratie, wat ertoe kan leiden dat sommige dingen zich anders gedragen. Theoretisch zou een load balancer die zich voor MySQL-servers bevindt (bijvoorbeeld een HAProxy voor een Galera-cluster) gewoon moeten werken als een verbindingsbeheerder en de verbindingen naar de backend-servers verdelen volgens een evenwichtsalgoritme. MySQL daarentegen heeft zijn eigen manier om clientverbindingen te beheren. In het ideale geval zouden we deze twee componenten samen moeten configureren om onverwacht gedrag te voorkomen en de probleemoplossing bij het opsporen van fouten te verkleinen.
Als u een dergelijke installatie hebt, is het belangrijk om deze componenten te begrijpen, omdat ze de algehele prestaties van uw databaseservice kunnen beïnvloeden. In deze blogpost duiken we in MySQL's max_connections en HAProxy maxconn respectievelijk opties. Merk op dat time-out een andere belangrijke parameter is die we moeten weten, maar die gaan we in een apart bericht behandelen.
Maximale verbindingen van MySQL
Gerelateerde bronnen MySQL Load Balancing met HAProxy - Tutorial Webinar Replay en Q&A:hoe ProxySQL, HAProxy en MaxScale te implementeren en beheren Webinar Replay &Slides:Hoe schaalbare database-infrastructuren te bouwen met MariaDB &HAProxyHet aantal toegestane verbindingen met een MySQL-server wordt bepaald door de max_connections systeem variabele. De standaardwaarde is 151 (MySQL 5.7).
Om een goed aantal te bepalen voor max_connections , de basisformules zijn:
Waar,
**Variabele innodb_additional_mem_pool_size wordt verwijderd in MySQL 5.7.4+. Als je de oudere versie gebruikt, houd dan rekening met deze variabele.
En,
Door de bovenstaande formules te gebruiken, kunnen we een geschikte max_connections . berekenen waarde voor deze specifieke MySQL-server. Om het proces te starten, stopt u alle verbindingen van clients en start u de MySQL-server opnieuw. Zorg ervoor dat u op dat moment alleen het minimum aantal processen laat draaien. U kunt hiervoor 'mysqladmin' of 'SHOW PROCESSLIST' gebruiken:
$ 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)
Uit de bovenstaande uitvoer kunnen we zien dat er slechts één gebruiker is verbonden met de MySQL-server die root is. Haal vervolgens het beschikbare RAM (in MB) van de host op (kijk onder de kolom 'beschikbaar'):
$ free -m
total used free shared buff/cache available
Mem: 3778 1427 508 148 1842 1928
Swap: 2047 4 2043
Ter info, de kolom 'beschikbaar' geeft een schatting van hoeveel geheugen er beschikbaar is om nieuwe applicaties te starten, zonder swapping (alleen beschikbaar in kernel 3.14+).
Specificeer vervolgens het beschikbare geheugen, 1928 MB in de volgende instructie:
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 |
+--------------------------+
**Variabele innodb_additional_mem_pool_size wordt verwijderd in MySQL 5.7.4+. Als je de oudere versie gebruikt, houd dan rekening met deze variabele.
Uit dit voorbeeld kunnen we tot 265 MySQL-verbindingen tegelijk hebben, afhankelijk van het beschikbare RAM-geheugen dat de host heeft. Het heeft geen zin om een hogere waarde dan dat te configureren. Voeg vervolgens de volgende regel toe in het MySQL-configuratiebestand, onder de [mysqld]-richtlijn:
max_connections = 265
Start de MySQL-service opnieuw om de wijziging toe te passen. Wanneer het totale aantal gelijktijdige verbindingen 265 bereikt, krijgt u de foutmelding "Te veel verbindingen" wanneer u probeert verbinding te maken met de mysqld-server. Dit betekent dat alle beschikbare verbindingen door andere clients worden gebruikt. MySQL staat eigenlijk max_connections toe +1 klanten om verbinding te maken. De extra verbinding is gereserveerd voor gebruik door accounts die het SUPER-privilege hebben. Dus als u met deze fout wordt geconfronteerd, moet u proberen toegang te krijgen tot de server als rootgebruiker (of een andere SUPER-gebruiker) en naar de proceslijst te kijken om de probleemoplossing te starten.
Maximale verbindingen van HAProxy
HAProxy heeft 3 soorten max-verbindingen (maxconn) - globaal, standaard/luister en standaardserver. Stel dat een HAProxy-instantie is geconfigureerd met twee listeners, een voor het luisteren met meerdere schrijvers op poort 3307 (verbindingen worden gedistribueerd naar alle backend MySQL-servers) en een andere is een enkele schrijver op poort 3308 (verbindingen worden doorgestuurd naar een enkele MySQL-server):
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]
Laten we eens kijken naar de betekenis van enkele configuratieregels:
global.maxconn [a]
Het totale aantal gelijktijdige verbindingen dat verbinding mag maken met deze HAProxy-instantie. Meestal is deze waarde de hoogste van allemaal. In dit geval accepteert HAProxy maximaal 2000 verbindingen tegelijk en distribueert deze naar alle listeners die zijn gedefinieerd in het HAProxy-proces, of worker (u kunt meerdere HAProxy-processen uitvoeren met nbproc optie).
HAProxy stopt met het accepteren van verbindingen wanneer deze limiet is bereikt. De parameter "ulimit-n" wordt automatisch aangepast aan deze waarde. Aangezien sockets vanuit het systeemperspectief als gelijkwaardig aan bestanden worden beschouwd, is de standaardlimiet voor bestandsdescriptors vrij klein. Je zult waarschijnlijk de standaardlimiet willen verhogen door de kernel af te stemmen op bestandsdescriptors.
defaults.maxconn [b]
Standaardwaarde voor maximale verbindingen voor alle luisteraars. Het heeft geen zin als deze waarde hoger is dan global.maxconn .
Als de regel "maxconn" ontbreekt onder de strofe "listen" (listen.maxconn ), zal de luisteraar deze waarde gehoorzamen. In dit geval krijgt de mysql_3308 listener maximaal 3 verbindingen tegelijk. Stel voor de zekerheid deze waarde in op global.maxconn , gedeeld door het aantal luisteraars. Als je echter andere luisteraars prioriteit wilt geven om meer connecties te hebben, gebruik dan listen.maxconn in plaats daarvan.
listen.maxconn [c]
Het maximum aantal toegestane verbindingen voor de corresponderende luisteraar. De luisteraar heeft voorrang op defaults.maxconn indien gespecificeerd. Het heeft geen zin als deze waarde hoger is dan global.maxconn .
Voor een eerlijke verdeling van verbindingen met backend-servers, zoals in het geval van een luisteraar met meerdere schrijvers (mysql_3307), stelt u deze waarde in op listen.default-server.maxconn vermenigvuldig met het aantal backend-servers. In dit voorbeeld zou een betere waarde 12 moeten zijn in plaats van 8 [c]. Als we ervoor kiezen om bij deze configuratie te blijven, wordt verwacht dat db1 en db2 elk maximaal 3 verbindingen zullen ontvangen, terwijl db3 maximaal 2 verbindingen zal ontvangen (vanwege de leastconn-balancering), wat neerkomt op 8 verbindingen in totaal. Het zal de limiet niet bereiken zoals gespecificeerd in [d].
Voor single-writer listener (mysql_3308) waarbij verbindingen moeten worden toegewezen aan één en slechts één backend-server tegelijk, stelt u deze waarde in op hetzelfde of hoger dan listen.default-server.maxconn .
listen.default-server.maxconn [d][e]
Dit is het maximale aantal verbindingen dat elke backend-server tegelijk kan ontvangen. Het heeft geen zin als deze waarde hoger is dan listen.maxconn of defaults.maxconn . Deze waarde moet lager of gelijk zijn aan MySQL's max_connections variabel. Anders loopt u het risico de verbindingen met de backend MySQL-server uit te putten, vooral wanneer de time-outvariabelen van MySQL lager zijn geconfigureerd dan de time-outs van HAProxy.
In dit voorbeeld hebben we elke MySQL-server ingesteld om maximaal 4 verbindingen tegelijk te krijgen voor Galera-knooppunten met meerdere schrijvers [d]. Terwijl de single-writer Galera-node maximaal 3 verbindingen tegelijk krijgt, vanwege de limiet die van toepassing is vanaf [b]. Aangezien we "backup" [f] naar het andere knooppunt hebben gespecificeerd, krijgt het actieve knooppunt in één keer alle 3 verbindingen toegewezen aan deze luisteraar.
De bovenstaande uitleg kan worden geïllustreerd in het volgende diagram:
Om de verbindingendistributie samen te vatten, wordt verwacht dat db1 een maximum aantal van 6 verbindingen krijgt (3 van 3307 + 3 van 3308). De db2 krijgt 3 verbindingen (tenzij als db1 uitvalt, waar hij extra 3 krijgt) en db3 blijft bij 2 verbindingen, ongeacht de topologieveranderingen in het cluster.
Verbindingsbewaking met ClusterControl
Met ClusterControl kunt u het MySQL- en HAProxy-verbindingsgebruik volgen vanuit de gebruikersinterface. De volgende schermafbeelding geeft een samenvatting van de MySQL-verbindingsadviseur (ClusterControl -> Prestaties -> Adviseurs) waar deze de huidige en ooit gebruikte MySQL-verbindingen voor elke server in het cluster bewaakt:
Voor HAProxy integreert ClusterControl met de HAProxy-statistiekenpagina om statistieken te verzamelen. Deze worden weergegeven onder het tabblad Nodes:
Uit de bovenstaande schermafbeelding kunnen we zien dat elke backend-server op een luisteraar met meerdere schrijvers maximaal 8 verbindingen krijgt. Er lopen 4 gelijktijdige sessies. Deze worden gemarkeerd in het bovenste rode vierkant, terwijl de luisteraar met één schrijver twee verbindingen bedient en deze respectievelijk doorstuurt naar een enkel knooppunt.
Conclusie
Het configureren van het maximale aantal verbindingen voor de HAProxy- en MySQL-server is belangrijk om een goede verdeling van de belasting naar onze databaseservers te garanderen en de MySQL-servers te beschermen tegen overbelasting of uitputting van de verbindingen.