Att ha en lastbalanserare eller omvänd proxy framför din MySQL- eller MariaDB-server lägger till lite komplexitet till din databasinstallation, vilket kan leda till att vissa saker beter sig annorlunda. Teoretiskt sett borde en lastbalanserare som sitter framför MySQL-servrar (till exempel en HAProxy framför ett Galera Cluster) bara fungera som en anslutningshanterare och distribuera anslutningarna till backend-servrarna enligt någon balanseringsalgoritm. MySQL, å andra sidan, har sitt eget sätt att hantera klientanslutningar. Helst skulle vi behöva konfigurera dessa två komponenter tillsammans för att undvika oväntade beteenden och begränsa felsökningsytan vid felsökning av problem.
Om du har en sådan installation är det viktigt att förstå dessa komponenter eftersom de kan påverka den övergripande prestandan för din databastjänst. I det här blogginlägget kommer vi att dyka in i MySQL:s max_connections och HAProxy maxconn alternativ. Observera att timeout är en annan viktig parameter som vi bör känna till, men vi kommer att ta upp det i ett separat inlägg.
MySQL:s maximala anslutningar
Relaterade resurser MySQL Load Balancing with HAProxy – Tutorial Webinar Replay and Q&A:hur man distribuerar och hanterar ProxySQL, HAProxy och MaxScale Webinar Replay &Slides:Hur man bygger skalbara databasinfrastrukturer med MariaDB &HAProxyAntalet tillåtna anslutningar till en MySQL-server styrs av max_connections systemvariabel. Standardvärdet är 151 (MySQL 5.7).
För att fastställa ett bra nummer för max_connections , de grundläggande formlerna är:
Var,
**Variabel innodb_additional_mem_pool_size tas bort i MySQL 5.7.4+. Om du kör i den äldre versionen, ta hänsyn till denna variabel.
Och,
Genom att använda formlerna ovan kan vi beräkna en lämplig max_anslutningar värde för just denna MySQL-server. För att starta processen, stoppa alla anslutningar från klienter och starta om MySQL-servern. Se till att du bara har det minsta antalet processer som körs i just det ögonblicket. Du kan använda 'mysqladmin' eller 'VISA PROCESSLISTA' för detta ändamål:
$ 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)
Från ovanstående utdata kan vi säga att endast en användare är ansluten till MySQL-servern som är root. Hämta sedan det tillgängliga RAM-minnet (i MB) för värden (se under kolumnen "tillgänglig"):
$ free -m
total used free shared buff/cache available
Mem: 3778 1427 508 148 1842 1928
Swap: 2047 4 2043
Bara för informationen ger kolumnen "tillgänglig" en uppskattning av hur mycket minne som är tillgängligt för att starta nya applikationer, utan att byta (endast tillgängligt i kärnan 3.14+).
Ange sedan tillgängligt minne, 1928 MB i följande sats:
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 |
+--------------------------+
**Variabel innodb_additional_mem_pool_size tas bort i MySQL 5.7.4+. Om du kör i den äldre versionen, ta hänsyn till denna variabel.
Från detta exempel kan vi ha upp till 265 MySQL-anslutningar samtidigt enligt det tillgängliga RAM-minnet som värden har. Det är inte vettigt att konfigurera ett högre värde än så. Lägg sedan till följande rad i MySQL-konfigurationsfilen under [mysqld]-direktivet:
max_connections = 265
Starta om MySQL-tjänsten för att tillämpa ändringen. När det totala antalet samtidiga anslutningar når 265, skulle du få ett "För många anslutningar"-fel när du försöker ansluta till mysqld-servern. Detta innebär att alla tillgängliga anslutningar används av andra klienter. MySQL tillåter faktiskt max_connections +1 klienter för att ansluta. Den extra anslutningen är reserverad för användning av konton som har SUPER-privilegiet. Så om du möter det här felet, bör du försöka komma åt servern som en root-användare (eller någon annan SUPER-användare) och titta på processlistan för att starta felsökningen.
HAProxys maximala anslutningar
HAProxy har 3 typer av maxanslutningar (maxconn) - global, standard/lyssna och standardserver. Antag att en HAProxy-instans konfigurerad med två lyssnare, en för multi-writer-lyssning på port 3307 (anslutningar distribueras till alla backend MySQL-servrar) och en annan är single-writer på port 3308 (anslutningar vidarebefordras till en enda 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]
Låt oss titta på innebörden av några av konfigurationsraderna:
global.maxconn [a]
Det totala antalet samtidiga anslutningar som tillåts ansluta till denna HAProxy-instans. Vanligtvis är detta värde det högsta värdet av alla. I det här fallet kommer HAProxy att acceptera maximalt 2000 anslutningar åt gången och distribuera dem till alla lyssnare som definierats i HAProxy-processen, eller arbetare (du kan köra flera HAProxy-processer med nbproc alternativ).
HAProxy kommer att sluta acceptera anslutningar när denna gräns nås. Parametern "ulimit-n" justeras automatiskt till detta värde. Eftersom sockets anses likvärdiga med filer ur systemperspektivet är standardgränsen för filbeskrivningar ganska liten. Du kommer förmodligen att vilja höja standardgränsen genom att ställa in kärnan för filbeskrivningar.
defaults.maxconn [b]
Ställer in maximalt anslutningsvärde för alla lyssnare. Det är inte vettigt om detta värde är högre än global.maxconn .
Om raden "maxconn" saknas under strofen "lyssna" (listen.maxconn ), kommer lyssnaren att följa detta värde. I det här fallet kommer mysql_3308-lyssnaren att få maximalt 3 anslutningar åt gången. För att vara säker, ställ in detta värde lika med global.maxconn , dividerat med antalet lyssnare. Men om du vill prioritera andra lyssnare för att få fler kontakter, använd listen.maxconn istället.
listen.maxconn [c]
Maximalt tillåtna anslutningar för motsvarande lyssnare. Lyssnaren har företräde framför defaults.maxconn om det anges. Det är inte vettigt om detta värde är högre än global.maxconn .
För en rättvis fördelning av anslutningar till backend-servrar som i fallet med en multi-writer-lyssnare (mysql_3307), ställ in detta värde som listen.default-server.maxconn multiplicera med antalet backend-servrar. I det här exemplet bör ett bättre värde vara 12 istället för 8 [c]. Om vi väljer att hålla fast vid denna konfiguration förväntas db1 och db2 få maximalt 3 anslutningar var, medan db3 får maximalt 2 anslutningar (på grund av balancering av leastconn), vilket uppgår till 8 anslutningar totalt. Den når inte den gräns som anges i [d].
För enskrivare avlyssnare (mysql_3308) där anslutningar ska allokeras till en och endast en backend-server åt gången, ställ in detta värde på samma eller högre än listen.default-server.maxconn .
listen.default-server.maxconn [d][e]
Detta är det maximala antalet anslutningar som varje backend-server kan ta emot åt gången. Det är inte vettigt om detta värde är högre än listen.maxconn eller defaults.maxconn . Detta värde bör vara lägre eller lika med MySQL:s max_connections variabel. Annars riskerar du att uttömma anslutningarna till backend MySQL-servern, speciellt när MySQL:s timeoutvariabler är konfigurerade lägre än HAProxys timeouts.
I det här exemplet har vi ställt in varje MySQL-server för att endast få maximalt 4 anslutningar åt gången för multi-writer Galera-noder [d]. Medan Galera-noden med en skribent kommer att få maximalt 3 anslutningar åt gången, på grund av gränsen som gäller från [b]. Eftersom vi angav "backup" [f] till den andra noden, kommer den aktiva noden på en gång att få alla 3 anslutningar tilldelade den här lyssnaren.
Ovanstående förklaring kan illustreras i följande diagram:
För att summera anslutningsfördelningen förväntas db1 få ett maximalt antal av 6 anslutningar (3 från 3307 + 3 från 3308). db2 kommer att få 3 anslutningar (om inte om db1 går ner, där den kommer att få ytterligare 3) och db3 kommer att hålla sig till 2 anslutningar oavsett topologiändringar i klustret.
Anslutningsövervakning med ClusterControl
Med ClusterControl kan du övervaka användningen av MySQL och HAProxy-anslutning från användargränssnittet. Följande skärmdump ger en sammanfattning av MySQL-anslutningsrådgivaren (ClusterControl -> Performance -> Advisors) där den övervakar de aktuella och någonsin använda MySQL-anslutningarna för varje server i klustret:
För HAProxy integreras ClusterControl med statistiksidan för HAProxy för att samla in mätvärden. Dessa presenteras under fliken Noder:
Från ovanstående skärmdump kan vi säga att varje backend-server på multi-writer-lyssnare får maximalt 8 anslutningar. 4 samtidiga sessioner körs. Dessa är markerade i den översta röda fyrkanten, medan en-skrivarens lyssnare betjänar 2 anslutningar och vidarebefordrar dem till en enskild nod.
Slutsats
Att konfigurera de maximala anslutningarna för HAProxy- och MySQL-server är viktigt för att säkerställa god belastningsfördelning till våra databasservrar och skydda MySQL-servrarna från att överbelasta eller utmatta dess anslutningar.