Ter um balanceador de carga ou proxy reverso na frente do servidor MySQL ou MariaDB adiciona um pouco de complexidade à configuração do banco de dados, o que pode levar a algumas coisas a se comportarem de maneira diferente. Teoricamente, um balanceador de carga que fica na frente dos servidores MySQL (por exemplo, um HAProxy na frente de um Galera Cluster) deve agir apenas como um gerenciador de conexões e distribuir as conexões para os servidores backend de acordo com algum algoritmo de balanceamento. O MySQL, por outro lado, tem sua própria maneira de gerenciar conexões de clientes. Idealmente, precisaríamos configurar esses dois componentes juntos para evitar comportamentos inesperados e restringir a superfície de solução de problemas ao depurar problemas.
Se você tiver essa configuração, é importante entender esses componentes, pois eles podem afetar o desempenho geral do serviço de banco de dados. Nesta postagem do blog, vamos mergulhar nas max_connections do MySQL e HAProxy maxconn opções respectivamente. Observe que o tempo limite é outro parâmetro importante que devemos saber, mas abordaremos isso em um post separado.
Conexões máximas do MySQL
Recursos relacionados Balanceamento de carga MySQL com HAProxy - Tutorial Webinar Replay and Q&A:como implantar e gerenciar ProxySQL, HAProxy e MaxScale Webinar Replay &Slides:Como criar infraestruturas de banco de dados escaláveis com MariaDB e HAProxyO número de conexões permitidas a um servidor MySQL é controlado pelo max_connections variável do sistema. O valor padrão é 151 (MySQL 5.7).
Para determinar um bom número para max_connections , as fórmulas básicas são:
Onde,
**Variável innodb_additional_mem_pool_size é removido no MySQL 5.7.4+. Se você estiver executando na versão mais antiga, leve essa variável em consideração.
E,
Usando as fórmulas acima, podemos calcular um max_connections adequado valor para este servidor MySQL em particular. Para iniciar o processo, pare todas as conexões dos clientes e reinicie o servidor MySQL. Certifique-se de ter apenas o número mínimo de processos em execução naquele momento específico. Você pode usar 'mysqladmin' ou 'SHOW PROCESSLIST' para este propósito:
$ 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)
Da saída acima, podemos dizer que apenas um usuário está conectado ao servidor MySQL que é root. Em seguida, recupere a RAM disponível (em MB) do host (procure na coluna 'disponível'):
$ free -m
total used free shared buff/cache available
Mem: 3778 1427 508 148 1842 1928
Swap: 2047 4 2043
Apenas para informação, a coluna 'disponível' fornece uma estimativa de quanta memória está disponível para iniciar novos aplicativos, sem troca (disponível apenas no kernel 3.14+).
Em seguida, especifique a memória disponível, 1928 MB na seguinte instrução:
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 |
+--------------------------+
**Variável innodb_additional_mem_pool_size é removido no MySQL 5.7.4+. Se você estiver executando na versão mais antiga, leve essa variável em consideração.
A partir deste exemplo, podemos ter até 265 conexões MySQL simultaneamente de acordo com a RAM disponível que o host possui. Não faz sentido configurar um valor maior que esse. Em seguida, anexe a seguinte linha dentro do arquivo de configuração do MySQL, sob a diretiva [mysqld]:
max_connections = 265
Reinicie o serviço MySQL para aplicar a alteração. Quando o total de conexões simultâneas atingir 265, você receberá um erro "Too many connections" ao tentar se conectar ao servidor mysqld. Isso significa que todas as conexões disponíveis estão em uso por outros clientes. O MySQL realmente permite max_connections +1 clientes para conectar. A conexão extra é reservada para uso por contas que possuem o privilégio SUPER. Portanto, se você enfrentar esse erro, tente acessar o servidor como usuário root (ou qualquer outro usuário SUPER) e consulte a lista de processos para iniciar a solução de problemas.
Conexões máximas do HAProxy
O HAProxy tem 3 tipos de conexões máximas (maxconn) - global, defaults/listen e default-server. Suponha uma instância HAProxy configurada com dois listeners, um para multi-writer escutando na porta 3307 (as conexões são distribuídas para todos os servidores MySQL de back-end) e outro é single-writer na porta 3308 (as conexões são encaminhadas para um único servidor MySQL):
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]
Vejamos o significado de algumas das linhas de configuração:
global.maxconn [a]
O número total de conexões simultâneas que têm permissão para se conectar a esta instância do HAProxy. Normalmente, esse valor é o valor mais alto de todos. Nesse caso, o HAProxy aceitará no máximo 2.000 conexões por vez e as distribuirá para todos os ouvintes definidos no processo HAProxy ou no trabalhador (você pode executar vários processos HAProxy usando nbproc opção).
O HAProxy deixará de aceitar conexões quando esse limite for atingido. O parâmetro "ulimit-n" é ajustado automaticamente para este valor. Como os soquetes são considerados equivalentes aos arquivos do ponto de vista do sistema, o limite de descritores de arquivo padrão é bastante pequeno. Você provavelmente desejará aumentar o limite padrão ajustando o kernel para descritores de arquivo.
defaults.maxconn [b]
Valor máximo de conexões padrão para todos os ouvintes. Não faz sentido se este valor for maior que global.maxconn .
Se a linha "maxconn" estiver faltando na estrofe "listen" (listen.maxconn ), o ouvinte obedecerá a esse valor. Neste caso, o listener mysql_3308 obterá no máximo 3 conexões por vez. Por segurança, defina este valor igual a global.maxconn , dividido pelo número de ouvintes. No entanto, se você quiser priorizar outros ouvintes para ter mais conexões, use listen.maxconn em vez de.
ouvir.maxconn [c]
O máximo de conexões permitidas para o ouvinte correspondente. O ouvinte tem precedência sobre defaults.maxconn se especificado. Não faz sentido se este valor for maior que global.maxconn .
Para uma distribuição justa de conexões para servidores de backend, como no caso de um ouvinte multi-gravador (mysql_3307), defina este valor como listen.default-server.maxconn multiplique pelo número de servidores backend. Neste exemplo, um valor melhor deve ser 12 em vez de 8 [c]. Se optarmos por manter essa configuração, espera-se que db1 e db2 recebam no máximo 3 conexões cada, enquanto db3 receberá no máximo 2 conexões (devido ao balanceamento de lessconn), o que equivale a 8 conexões no total. Não atingirá o limite especificado em [d].
Para ouvinte de gravador único (mysql_3308) onde as conexões devem ser alocadas para um e apenas um servidor backend por vez, defina este valor para ser igual ou maior que listen.default-server.maxconn .
listen.default-server.maxconn [d][e]
Este é o número máximo de conexões que cada servidor de back-end pode receber por vez. Não faz sentido se este valor for maior que listen.maxconn ou defaults.maxconn . Este valor deve ser menor ou igual ao max_connections do MySQL variável. Caso contrário, você corre o risco de esgotar as conexões com o servidor MySQL de backend, especialmente quando as variáveis de tempo limite do MySQL são configuradas abaixo dos tempos limite do HAProxy.
Neste exemplo, configuramos cada servidor MySQL para obter apenas no máximo 4 conexões por vez para nós Galera com vários gravadores [d]. Enquanto o nó Galera de gravador único obterá no máximo 3 conexões por vez, devido ao limite que se aplica a partir de [b]. Como especificamos "backup" [f] para o outro nó, o nó ativo obterá imediatamente todas as 3 conexões alocadas para este ouvinte.
A explicação acima pode ser ilustrada no diagrama a seguir:
Para resumir a distribuição de conexões, espera-se que o db1 obtenha um número máximo de 6 conexões (3 de 3307 + 3 de 3308). O db2 obterá 3 conexões (a menos que o db1 fique inativo, onde obterá 3 adicionais) e o db3 manterá 2 conexões, independentemente das alterações de topologia no cluster.
Monitoramento de conexão com ClusterControl
Com o ClusterControl, você pode monitorar o uso da conexão MySQL e HAProxy a partir da interface do usuário. A captura de tela a seguir fornece um resumo do consultor de conexão MySQL (ClusterControl -> Performance -> Advisors) onde ele monitora as conexões MySQL atuais e já usadas para cada servidor no cluster:
Para o HAProxy, o ClusterControl se integra à página de estatísticas do HAProxy para coletar métricas. Eles são apresentados na guia Nós:
A partir da captura de tela acima, podemos dizer que cada servidor de back-end no ouvinte de vários gravadores obtém no máximo 8 conexões. 4 sessões simultâneas estão em execução. Eles são destacados no quadrado vermelho superior, enquanto o ouvinte de gravador único atende a 2 conexões e as encaminha para um único nó, respectivamente.
Conclusão
Configurar o máximo de conexões para o servidor HAProxy e MySQL é importante para garantir uma boa distribuição de carga para nossos servidores de banco de dados e proteger os servidores MySQL de sobrecarregar ou esgotar suas conexões.