High Mysql Connections

2

Ter um desafio para descobrir por que os resultados são como são. Talvez faltando algo óbvio. Desculpe, isso não é muito específico. Mas se alguém tiver uma indicação sobre áreas para focar isso seria muito útil. Felicidades.

Teste de carga

São cerca de 5486 gravações em db por minuto / 90 por segundo. Eu posso ver os seguintes erros nos logs conforme os servidores ficam sobrecarregados:

  • 11: Recurso temporariamente indisponível) ao conectar-se ao upstream
  • Tempo limite da produção upstream (110: Tempo limite da conexão esgotado) durante a leitura do cabeçalho de resposta do upstream

Problema

Ao executar o teste de carga, veja os seguintes problemas:

  • A página que executa a atualização / gravação (aquela que o teste de carga está atingindo) diminui e demora 10 20 segundos para carregar.
  • 404 arbitrários dados pelo Nginx em qualquer uma das páginas. Os resultados mostram que talvez 10-20% das solicitações durante o período de pico resultam em 404.

Acho que eles são dois problemas separados e possivelmente não relacionados. Não consigo ver linhas planas nos gráficos, o que sugere um limite sendo atingido.

  • Os servidores Web ficam em torno de 60% da CPU e permanecem estáveis. RAM parece OK.
  • Os servidores de banco de dados ficam em torno de 20% da CPU e permanecem estáveis. RAM parece OK.
  • Conexões de banco de dados vão para 1500/2000. Isso parece duvidoso. Embora não seja uma linha plana, o que sugere que não está atingindo um limite.
  • Os limites de conexão de rede parecem estar OK.
  • Tabelas indexadas sempre que possível / apropriado.

Infraestrutura

AWS RDS MySQL  1 x operações de gravação db.m3.xlarge  1 x db.m3.xlarge DB Replicado para operações de leitura

Webservers do AWS EC2 Linux, Nginx, PHP-FPM 6 x c3.2xlarge

Config

/etc/php-fpm.d/domain.com.conf

[domain.com]

user = nginx
group = nginx

;;;The address on which to accept FastCGI requests
listen = /var/run/php-fpm/domain.com.sock

;;;A value of '-1' means unlimited.  Althought this may be based on ulimit hard limit.
;;;May be worth setting as desired in case of the above.
listen.backlog = -1

;;;dynamic - the number of child processes is set dynamically based on the following      directives: pm.max_children, pm.start_servers, pm.min_spare_servers, pm.max_spare_servers.
pm = dynamic
;;;maximum number of child processes to be created when pm is set to dynamic
pm.max_children = 512
;;;The number of child processes created on startup. Used only when pm is set to dynamic.
pm.start_servers = 8
;;;The desired minimum number of idle server processes. Used only when pm is set to dynamic.
pm.min_spare_servers = 2
The desired maximum number of idle server processes. Used only when pm is set to dynamic
pm.max_spare_servers = 16
;;;The number of requests each child process should execute before respawning.
pm.max_requests = 500
;;;The URI to view the FPM status page.
pm.status_path = /status/fpm/domain.com
;;;The timeout for serving a single request. This option should be used when the    'max_execution_time' ini option does not stop script execution
request_terminate_timeout = 30

;;;Set open file descriptor rlimit. Default value: system defined value.
;;;rlimit_files

;;;rlimit_core int
;;;Set max core size rlimit. Possible Values: 'unlimited' or an integer greater or equal to       0. Default value: system defined value.

php_admin_value[post_max_size] = 8M
php_admin_value[upload_max_filesize] = 8M

php_admin_value[disable_functions] = exec,passthru,system,proc_open,popen,show_source

;;; Site specific custom flags go here

;;; End of site specific flags

slowlog = /var/log/nginx/slow-query-$pool.log

request_slowlog_timeout = 10s

chdir = /

Nginx - /etc/nginx/nginx.conf

events {
    worker_connections 19000;
# essential for linux, optmized to serve many clients with each thread
use epoll;
multi_accept on;
}
worker_rlimit_nofile    20000;

http {
    include         /etc/nginx/mime.types;
default_type    application/octet-stream;

log_format  proxy_combined  '$http_x_real_ip - $remote_user [$time_local] "$request" '
      '$status $body_bytes_sent "$http_referer" "$http_user_agent"';


access_log      /var/log/nginx/access.log   proxy_combined;

sendfile        on;

## Start: Size Limits & Buffer Overflows ##
client_body_buffer_size     1K;
client_header_buffer_size   1k;
# client_max_body_size        1k;
large_client_header_buffers 2 1k;
## END: Size Limits & Buffer Overflows ##

## Start: Caching file descriptors ##
open_file_cache             max=1000 inactive=20s;
open_file_cache_valid       30s;
open_file_cache_min_uses    2;
open_file_cache_errors      on;
## END: Caching

## Start: Timeouts ##
client_body_timeout   10;
client_header_timeout 10;
keepalive_timeout     5 5;
send_timeout          10;
## End: Timeouts ##

server_tokens       off;
tcp_nodelay         on;

gzip                on;
gzip_http_version   1.1;
gzip_vary           on;
gzip_comp_level     6;
gzip_proxied        any;
gzip_types          text/plain text/html text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript text/x-js;
gzip_buffers        16 8k;
gzip_disable        "MSIE [1-6]\.(?!.*SV1)";

client_max_body_size 30M;

proxy_cache_path /var/cache/nginx/c2b levels=1:2 keys_zone=c2b-cache:8m max_size=100m inactive=60m;
proxy_temp_path /var/cache/tmp;
proxy_ignore_headers Set-Cookie X-Accel-Expires Expires Cache-Control;

# allow the server to close the connection after a client stops responding. Frees up socket-associated memory.
reset_timedout_connection on;

    include /etc/nginx/conf.d/*.conf;
}

Site específico do NGINX - /etc/nginx/conf.d/domain.com

# pass the PHP scripts to FastCGI server listening on
        location ~ \.php$ {
        fastcgi_pass unix:/var/run/php-fpm/domain.com.sock;
        fastcgi_index  index.php;

        fastcgi_param  SCRIPT_FILENAME  /var/www/domain.com/public_html/$fastcgi_script_name;           
        include        fastcgi_params;
        fastcgi_read_timeout 30;
}
    
por hokeycokey 13.07.2014 / 05:26

1 resposta

1

Cheguei ao ponto crucial da questão. Eu mudei as tabelas de banco de dados MySQL de MyISAM para Innodb (onde possível, como eu acho que pode encher as coisas se você usar a pesquisa de texto completo).

Há um pouco sobre isso aqui -

MyISAM Table lock issue

Pode encontrar mais informações com um rápido Google

Isso corrigiu isso. Agora vendo cerca de 60.000 conexões bem sucedidas por minuto.

    
por 19.07.2014 / 07:49