IO de disco alta inexplicavelmente causado por processos de trabalho do nginx

5

Acabei de configurar um servidor LTS do Ubuntu 12.04.2 que serve um grande número de arquivos estáticos bastante grandes. A configuração é a mesma que em outra máquina que funciona muito bem. A outra máquina usa o Ubuntu 11.10 com o nginx 1.0.5. A máquina com o problema usa o nginx 1.1.19 e dificilmente pode empurrar em torno de 20MB / s (mas está em uma linha dedicada de 1Gbit) com o iotop mostrando alto IO de disco pelo nginx. Isso é da iotop:

  TID  PRIO  USER     DISK READ  DISK WRITE  SWAPIN     IO>    COMMAND
 4569 be/4 www-data  754.61 K/s    0.00 B/s  0.00 % 99.99 % nginx: worker process
 4571 be/4 www-data 1257.69 K/s    0.00 B/s  0.00 % 99.99 % nginx: worker process
 4574 be/4 www-data    2.46 M/s    0.00 B/s  0.00 % 99.99 % nginx: worker process
 3951 be/4 www-data 1760.77 K/s    0.00 B/s  0.00 % 99.99 % nginx: worker process is     shutting down
 3950 be/4 www-data  503.08 K/s    0.00 B/s  0.00 % 99.99 % nginx: worker process is shutting down
 4573 be/4 www-data 2012.31 K/s    0.00 B/s  0.00 % 99.99 % nginx: worker process
 3952 be/4 www-data 1006.15 K/s    0.00 B/s  0.00 % 99.99 % nginx: worker process is shutting down
 3954 be/4 www-data 1760.77 K/s    0.00 B/s  0.00 % 99.99 % nginx: worker process is shutting down
 4572 be/4 www-data    4.05 M/s    0.00 B/s  0.00 % 99.99 % nginx: worker process
 3956 be/4 www-data    2.70 M/s    0.00 B/s  0.00 % 99.99 % nginx: worker process is shutting down
 3953 be/4 www-data  251.54 K/s    0.00 B/s  0.00 % 99.99 % nginx: worker process is shutting down
 4567 be/4 www-data    2.21 M/s    0.00 B/s  0.00 % 98.30 % nginx: worker process
 4570 be/4 www-data  754.61 K/s    0.00 B/s  0.00 % 97.91 % nginx: worker process
 3949 be/4 www-data 1006.15 K/s    0.00 B/s  0.00 % 88.21 % nginx: worker process is shutting down
 3955 be/4 www-data 1509.23 K/s    0.00 B/s  0.00 % 84.60 % nginx: worker process is shutting down

Portanto, por algum motivo, os processos que tentam desligar fazem com que o IO e o servidor entrem em um estado quase sem resposta, com a carga crescendo até 5-6 (essa é uma máquina dual core). A utilização da CPU, entretanto, é de 0,5%

Depois de reiniciar o nginx, tudo fica bem por algum tempo e isso acontece novamente.

Este é o mais recente do log de erros do nginx:

013/03/18 13:09:28 [alert] 3676#0: open socket #297 left in connection 145

e então isso acontece:

2013/03/18 13:10:11 [alert] 3749#0: 100 worker_connections are not enough

e este é o nginx.conf:

user www-data;
worker_processes 8;
worker_rlimit_nofile 20480;
pid /var/run/nginx.pid;

events {
    worker_connections 100;
    # multi_accept on;
}

http {

    ##
    # Basic Settings
    ##

    sendfile off;
        output_buffers 1 512k;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 5;
    types_hash_max_size 2048;

Qualquer ajuda será muito apreciada!

EDITAR:

Sendfile ativado e desativado não faz diferença.

worker_rlimit_nofile == worker_connections não faz diferença.

worker_processes não altera nada também.

smartctl não mostra problemas com o disco, no entanto eu tentei com o segundo disco nesta máquina e ainda não há diferença.

    
por Velo 18.03.2013 / 14:47

2 respostas

2

HDDs relativamente recentes podem fazer 150MB / s (1.2Gbps) em leituras seqüenciais (e gravações), mas se você tiver várias leituras / gravações paralelas (mesmo que cada leitura ainda seja sequencial), a velocidade de transferência cairá facilmente 10 ×.

Portanto, 20MB / s (160Mbps) parece uma limitação do seu HDD .

Talvez o outro servidor tenha um SSD, ou tenha mais memória, e tenha esses arquivos em cache, mas este tem algo errado no lado do cache (provavelmente pouca memória, mas talvez configurações de kernel mal otimizadas).

De qualquer forma, isso provavelmente soaria como algo fora do controle do nginx.

Você pode tentar aumentar seus buffers de memória nginx em várias dobras, na tentativa de tornar as leituras um pouco mais sequenciais, mas se você tiver apenas um disco rígido baseado em platter (por exemplo, no máximo 150MB / s em uma única leitura sequencial , queda de várias dobras em múltiplas leituras), e nenhum cache é utilizado devido a pouca memória, então você não será capaz de empurrar para qualquer lugar perto de 1Gbps (128MB / s).

Se você realmente precisa de uma taxa de transferência de 1 Gbps: se os arquivos mais comuns puderem ser armazenados em cache na memória, obtenha mais memória; mais, pegue um SSD rápido.

    
por 20.03.2013 / 19:39
0

Eu transformaria sendfile em:

 sendfile on

Acho que evita cópias desnecessárias e economiza em chamadas do sistema. Além disso, o tcp_nopush só estará ativo se o sendfile estiver ativado. Veja aqui.

Além disso, remova types_hash_max_size.

    
por 18.03.2013 / 14:52