Tempos de conexão longos do PHP para o MySQL no EC2

4

Estou com um problema intermitente conectando-me a um escravo do banco de dados com o InnoDB. Intermitentemente eu recebo conexões demorando mais de 2 segundos. Esses servidores estão hospedados no EC2 da Amazon.

O servidor de aplicativos é o PHP 5.2 / Apache em execução no Ubuntu. O escravo DB está executando o XtraDB 5.1 da Percona no Ubuntu 9.10. Está usando uma matriz EBS Raid para o armazenamento de dados.

Já usamos o skip name resolve e ligamos ao endereço 0.0.0.0.

Este é um esboço do código PHP que está falhando

        $tmp = mysqli_init();
        $start_time = microtime(true);
        $tmp->options(MYSQLI_OPT_CONNECT_TIMEOUT, 2);
        $tmp->real_connect($DB_SERVERS[$server]['server'], 
                   $DB_SERVERS[$server]['username'], 
                   $DB_SERVERS[$server]['password'], 
                   $DB_SERVERS[$server]['schema'], 
                   $DB_SERVERS[$server]['port']);
        if(mysqli_connect_errno()){
            $timer = microtime(true) - $start_time;
            mail($errors_to,'DB connection error',$timer);
        }

Há mais de 300Mb disponíveis no servidor de banco de dados para novas conexões e o servidor não está nem perto do máximo permitido (60 de 1.200). A carga nos dois servidores é de < 2 em 4 instâncias m1.xlarge principais.

Alguns destaques da configuração do mysql

max_connections = 1200

thread_stack = 512K
thread_cache_size = 1024
thread_concurrency = 16

innodb-file-per-table
innodb_additional_mem_pool_size = 16M
innodb_buffer_pool_size = 13G

Qualquer ajuda para rastrear a origem da lentidão é bem-vinda.

[EDIT] Eu tenho atualizado os valores de sysctl para a rede, mas eles não parecem estar corrigindo o problema. Fiz os seguintes ajustes no banco de dados e nos servidores de aplicativos.

net.ipv4.tcp_window_scaling = 1
net.ipv4.tcp_sack = 0
net.ipv4.tcp_timestamps = 0
net.ipv4.tcp_fin_timeout = 20
net.ipv4.tcp_keepalive_time = 180
net.ipv4.tcp_max_syn_backlog = 1280
net.ipv4.tcp_synack_retries = 1
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 87380 16777216

[EDIT] Por sugestão do jaimieb, adicionei alguns traçados e capturei os seguintes dados usando o tempo. Este servidor lida com cerca de 51 consultas / segundo nesta hora do dia. O erro de conexão foi gerado uma vez (às 13:06:36) durante a janela de 3 minutos descrita abaixo. Como houve 1 falha e aproximadamente 9.200 conexões bem-sucedidas, acho que isso não produzirá nada significativo em termos de relatórios.

Script:

date >> /root/database_server.txt
(time mysql -h database_Server -D schema_name -u appuser -p apppassword -e '') > /dev/null 2>> /root/database_server.txt

Resultados:


=== Application Server 1 ===
Mon Feb 22 13:05:01 EST 2010
real    0m0.008s
user    0m0.001s
sys     0m0.000s

Mon Feb 22 13:06:01 EST 2010
real    0m0.007s
user    0m0.002s
sys     0m0.000s

Mon Feb 22 13:07:01 EST 2010
real    0m0.008s
user    0m0.000s
sys     0m0.001s

=== Application Server 2 ===
Mon Feb 22 13:05:01 EST 2010
real    0m0.009s
user    0m0.000s
sys     0m0.002s

Mon Feb 22 13:06:01 EST 2010
real    0m0.009s
user    0m0.001s
sys     0m0.003s

Mon Feb 22 13:07:01 EST 2010
real    0m0.008s
user    0m0.000s
sys     0m0.001s

=== Database Server ===
Mon Feb 22 13:05:01 EST 2010
real    0m0.016s
user    0m0.000s
sys     0m0.010s

Mon Feb 22 13:06:01 EST 2010
real    0m0.006s
user    0m0.010s
sys     0m0.000s

Mon Feb 22 13:07:01 EST 2010
real    0m0.016s
user    0m0.000s
sys     0m0.010s

[EDIT] Por uma sugestão recebida em uma pergunta do LinkedIn, tentei configurar o valor de back_log mais alto. Nós estávamos rodando o valor padrão (50) e aumentamos para 150. Nós também aumentamos o valor do kernel / proc / sys / net / core / somaxconn (conexões de soquete máximo) para 256 no servidor de aplicativo e banco de dados do padrão 128 Nós vimos alguma elevação na utilização do processador como resultado, mas ainda recebemos tempos limite de conexão.

    
por Erik Giberti 17.02.2010 / 22:07

3 respostas

2

Quão bem funciona se você eliminar o PHP da equação? Use o cliente CLI mysql para se conectar ao servidor. Experimente a partir do próprio servidor do banco de dados e do servidor de aplicativos:

time mysql -h localhost -D dbname -u username -ppassword -e ''
    
por 19.02.2010 / 21:08
1

Verifique seus servidores DNS, acho que o mysql pode estar tentando resolver o DNS reverso do host de conexão. Certifique-se também que o / etc / hosts é são e tem "127.0.0.1 localhost"

    
por 09.03.2010 / 22:24
0

Isso pode nem estar perto, mas você pode estar esperando o flush para o disco? Talvez o tempo limite?

Lembre-se de que você pode perder até 1 minuto de dados em caso de falha.

innodb_flush_log_at_trx_commit = 0 (o padrão é 1)

Isso fará com que o InnoDB apenas grave e liberte o buffer de log uma vez por segundo. : link

    
por 22.02.2010 / 19:49