Nossa configuração de VM (hospedada em VMware)
# cat /proc/cpuinfo |grep "cpu cores" | awk -F: '{ num+=$2 } END{ print "cpu cores", num }'
cpu cores 32
# free -h
total used free shared buffers cached
Mem: 62G 23G 39G 500K 349M 10G
-/+ buffers/cache: 12G 50G
Swap: 50G 0B 50G
Recebi do pt-variable-advisor um aviso sobre max_connections
:
pt-variable-advisor h=localhost,u=root,p=Quule0juqu7aifohvo2Ahratit --socket /var/vcap/sys/run/mysql/mysqld.sock
(...)
# WARN max_connections: If the server ever really has more than a thousand threads running, then the system is likely to spend more time scheduling threads than really doing useful work.
(...)
Por quê? Algum detalhe?
Configuração em my.cnf
max_connections = 15360
configurações do cluster prd db (MariaDB 10.1.xe Galera)
MariaDB [(none)]> SHOW STATUS WHERE `variable_name` = 'Threads_connected';
+-------------------+-------+
| Variable_name | Value |
+-------------------+-------+
| Threads_connected | 718 |
+-------------------+-------+
1 row in set (0.01 sec)
MariaDB [(none)]> SHOW STATUS WHERE `variable_name` = 'Max_used_connections';
+----------------------+-------+
| Variable_name | Value |
+----------------------+-------+
| Max_used_connections | 924 |
+----------------------+-------+
1 row in set (0.02 sec)
Encontrei um manual do MySQL e uma pergunta semelhante (muito) antiga .
O valor padrão é 151 para melhorar o desempenho
O número de conexões permitidas é controlado pela variável de sistema max_connections. O valor padrão é 151 para melhorar o desempenho quando o MySQL é usado com o servidor da Web Apache. (Anteriormente, o padrão era 100.) Se você precisar dar suporte a mais conexões, defina um valor maior para essa variável.
e
O número máximo de conexões que o MySQL suporta depende da qualidade da biblioteca de threads em uma determinada plataforma, da quantidade de RAM disponível, da quantidade de RAM usada para cada conexão, da carga de trabalho de cada conexão e do tempo de resposta desejado. Linux ou Solaris deve ser capaz de suportar pelo menos 500 a 1.000 conexões simultâneas rotineiramente e até 10.000 conexões
Atualmente temos 460 usuários e cada usuário pode fazer 100 max_connections
. Este seria o valor máximo. O 100 max_connections
por usuário e banco de dados é muito alto? Com o pool de conexões moderno, podemos definir isso para 20? Como devemos configurar para não correr o risco de sobrecarregar nosso servidor com troca de contexto? É possível que um aplicativo da Web use uma conexão (todas as instruções na mesma conexão)?
Há uma diferença entre
Threads_running
eThreads_connected
. O primeiro implica que muitas consultas estão fazendo algo simultaneamente. Os outros estão dormindo, esperando que o usuário (ou aplicativo) apresente outra instrução SQL ao servidor.max_connections
é um limite deThreads_connected
. (Max_used_connections
é uma "marca d'água alta".)Um sistema ocupado típico terá apenas 1 em cada 7 threads 'conectados' realmente em execução. E
Threads_connected
normalmente é muito menor quemax_connections
. (Como 20x)Mas, em tempos ruins, muitas conexões, cada uma fazendo alguma consulta lenta, leva o MySQL a tropeçar em si mesmo. A taxa de transferência (consultas/segundo) atinge o máximo e pode até diminuir; a latência passa do teto, e um DBA em pânico irá reiniciar a máquina porque ele acha que ela travou, não apenas ficou terrivelmente emaranhada.
A solução é encontrar as consultas lentas e descobrir como acelerá-las. Ou rearquitete o aplicativo para ser mais eficiente. Ou altere o esquema e os índices. Raramente é para obter hardware maior ou alterar os ajustáveis.
Em um servidor MySQL bem gerenciado, raramente vejo mais de 2-3 núcleos em uso. No entanto, milhares de consultas/segundo podem ser realizadas mesmo com poucos núcleos ativos.
No DBaaS, você fica à mercê dos clientes. Qualquer um deles pode escrever um aplicativo desleixado que monopolize conexões, núcleos, E/S, largura de banda de rede, qualquer coisa.
Considere limitar cada usuário a 10 conexões, a menos que ele explique o que precisa fazer e/ou pague mais dinheiro. Com o dinheiro extra, você pode isolá-lo em uma VM separada. Uma vez estimei, em uma loja com Apache e MySQL, que 10 threads inundariam o Apache, para o MaxChild precisava ser muito menor que o padrão. (Tínhamos páginas bastante pesadas.) Se você tem controle sobre servidores web, limite quantos threads eles têm. Isso é parar o problema antes que ele chegue ao MySQL.
Ao colocar cada usuário em sua própria VM, você consome recursos extras, mas pode evitar que os excessos de um prejudiquem os demais.
Aposto que muitos de seus clientes usam WordPress? Aqui está um patch de desempenho para o esquema: http://mysql.rjweb.org/doc.php/index_cookbook_mysql#speeding_up_wp_postmeta
Se você quiser evitar trocas de contexto, use o pool de encadeamentos MariaDB , ignore o que o pt-advisor disser e não limite suas conexões. é claro que se você tiver muitas solicitações simultâneas longas e intensivas da CPU, isso pode não ajudar muito e, nesse caso, você precisa descobrir como corrigir as consultas longas.