Otimização do MySQL, php-fpm, APC, Varnish e Nginx para o Cache Total WordPress / W3?

1

Estou configurando meu primeiro VPS e parece estar funcionando bem. Instalado Nginx, php-fpm (como um socket unix), APC, Varnish e MySQL no servidor Ubuntu 12.04 com OnApp, e tudo funciona e é muito rápido, pelo menos na minha extremidade.

Atm eu tenho um VPS com 1 core (Xeon (R) X5660 é o que o VPS usa iirc), 1.2GHz e 768MB de RAM, tudo limitado com OnApp. Fazendo um teste ab, eu tenho isso:

ab -c 10 -n 1000 http://198.136.50.39/
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 198.136.50.39 (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests


Server Software:        
Server Hostname:        198.136.50.39
Server Port:            80

Document Path:          /
Document Length:        6482 bytes

Concurrency Level:      10
Time taken for tests:   41.695 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      6952000 bytes
HTML transferred:       6482000 bytes
Requests per second:    23.98 [#/sec] (mean)
Time per request:       416.946 [ms] (mean)
Time per request:       41.695 [ms] (mean, across all concurrent requests)
Transfer rate:          162.83 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:      167  203  57.3    182     614
Processing:   173  212  82.9    189    2015
Waiting:      169  206  59.8    185     726
Total:        345  415 126.5    373    2419

Percentage of the requests served within a certain time (ms)
  50%    373
  66%    388
  75%    410
  80%    430
  90%    504
  95%    708
  98%    866
  99%    931
 100%   2419 (longest request)

Enquanto eu fazia o teste eu estava dando uma olhada nas estatísticas do VPS com o htop, e parece que ele não usou mais de 230 mb de RAM em todo o teste, e a CPU ficou com 2 ~ 4% de uso, o que é prety legal eu acho. Mas parece que os pedidos por segundo foram um pouco baixos. O que é que vocês acham? Parece ok para a configuração que tenho e eu estou sendo paranóico, ou é ruim? Com as configurações padrão eu usei loadimpact.com para dar uma olhada, com 25 usuários (teste padrão livre) e carga padrão como 130ms ... depois que eu comecei a bagunçar as configurações, fiz o teste novamente e ele pulou para 250ms, então eu acho que estou fazendo algo errado.

Comecei a tentar otimizar o MySQL para ele, usando tutoriais encontrados na internet para caixas de baixo custo e link . Percona me deu alguns números realmente grandes, então eu fiz uma mistura de ambos.

Eu também otimizei o php-fpm e o Nginx, lendo os wikis e tutoriais em toda a Internet. Eu usarei este VPS para um site WordPress com cerca de 5 mil visitantes diários e 13 a 15 mil pageviews diários. O W3 Total Cache está configurado para fazer cache de banco de dados e de objetos usando o APC e o cache minify / page com disco aprimorado ... mas antes de migrar o site para esse servidor e ir ao vivo com ele, quero otimizar tudo e ter certeza de que seja rápido.

Eu também uso o MaxCDN (não ativo no VPS atm) e usarei o CloudFlare como um servidor DNS. Alguém pode me ajudar a otimizar, por favor?

Minha configuração do MySQL é semelhante a este:

[mysqld_safe]
open_files_limit = 8192

[mysqld]
skip_external_locking
skip_slave_start
bind-address        = 127.0.0.1
key_buffer      = 64M
join_buffer_size        = 1M
read_buffer_size        = 1M
sort_buffer_size        = 2M
max_allowed_packet  = 16M
max_connect_errors      = 10
thread_stack        = 192K
myisam-recover         = BACKUP
max_connections        = 400
table_cache            = 1024
thread_cache_size      = 286
interactive_timeout    = 25
wait_timeout           = 1000
query_cache_type    = 1
query_cache_limit   = 1M
query_cache_size        = 32M
max_write_lock_count = 1
expire_logs_days    = 10
max_binlog_size         = 100M

innodb_flush_method            = O_DIRECT
innodb_buffer_pool_size        = 10M

skip_name_resolve
sql_mode                       = STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_AUTO_VALUE_ON_ZERO,NO_ENGINE_SUBSTITUTION,NO_ZERO_DATE,NO_ZERO_IN_DATE,ONLY_FULL_GROUP_BY

tmp_table_size      = 16M
max_heap_table_size = 16M

[mysqldump]
quick
quote-names
max_allowed_packet  = 16M

[mysql]
#no-auto-rehash # faster start of mysql but no tab completition

[isamchk]
key_buffer      = 16M

A configuração do meu Nginx é assim:

worker_processes 1;

events {
    worker_connections 1024;
}

http {

    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 15;
    types_hash_max_size 2048;
    server_tokens off;

    open_file_cache max=1000 inactive=300s;
    open_file_cache_valid 360s;
    open_file_cache_min_uses 2;
    open_file_cache_errors off;

        client_body_buffer_size 8K;
        client_header_buffer_size 1k;
        client_max_body_size 2m;
        large_client_header_buffers 2 1k;

        client_body_timeout   10;
        client_header_timeout 10;
        send_timeout          10;

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

    error_log /var/log/nginx/error.log;

    gzip on;
    gzip_disable "msie6";

    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 9;
    gzip_buffers 16 8k;
    gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;

A configuração do Nginx do meu site tem esta aparência:

server {

    listen 8080;
    server_name www.ubuntubrsc.com ubuntubrsc.com;

    root /var/www;
    index index.php index.html index.htm;
        include /var/www/nginx.conf;

        error_log /var/log/nginx/blog.error_log;

        if ($host ~* ^[^.]+\.[^.]+$) {
        rewrite ^(.*)$ http://www.$host$1 permanent;
        }

    location / {
        try_files $uri $uri/ /index.php;
        }

        location = /favicon.ico {
    log_not_found off;
    access_log off;
        }

        location = /robots.txt {
    allow all;
    log_not_found off;
    access_log off;
        }

        location ~ /\. {
    deny all;
    access_log off;
    log_not_found off;
        }

        location ~* ^/wp-content/uploads/.*.php$ {
    deny all;
    access_log off;
    log_not_found off;
        }

        rewrite /wp-admin$ $scheme://$host$uri/ permanent;

        location ~ \.(css|js|htc)$ {
        root /var/www/ubuntu-online/;
        expires 31536000s;
        add_header Pragma "public";
        add_header Cache-Control "max-age=31536000, public, must-revalidate, proxy-revalidate";
        }
        location ~ \.(html|htm|rtf|rtx|svg|svgz|txt|xsd|xsl|xml)$ {
        root /var/www/ubuntu-online/;
        expires 3600s;
        add_header Pragma "public";
        add_header Cache-Control "max-age=3600, public, must-revalidate, proxy-revalidate";
        }
        location ~ \.(gif|gz|gzip|ico|jpg|jpeg|jpe|swf)$ {
        root /var/www/ubuntu-online/;
        expires 31536000s;
        add_header Pragma "public";
        add_header Cache-Control "max-age=31536000, public, must-revalidate, proxy-revalidate";
        }

    error_page 404 = @wordpress;
    log_not_found off;

    location @wordpress {
        include /etc/nginx/fastcgi_params;      
        fastcgi_pass unix:/var/run/php5-fpm.sock;
            fastcgi_param SCRIPT_NAME /index.php;
            fastcgi_param SCRIPT_FILENAME $document_root/index.php;
        }

    location ~ \.php$ {
                try_files $uri =404;

        include /etc/nginx/fastcgi_params;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        if (-f $request_filename) {
                fastcgi_pass unix:/var/run/php5-fpm.sock;
            }
    }
      }

A parte do cache do ubuntu-online é porque eu não sei se as configurações do W3 Total Cache estão disponíveis para todas as pastas dentro de / www / var /, então eu adicionei aquelas com "root / var / www / ubuntu-online / " para ter certeza. Devo apagá-los?

No php.ini eu editei alguns materiais para aumentar a segurança, como open_basedir e outras coisas, e também habilitei um cache interno php para editar 2 linhas, mas não me lembro o que era.

Além disso, essas são as configurações do APC:

[APC]
apc.enabled = 1
apc.cache_by_default = 1
apc.stat = 1
apc.shm_segments = 1
apc.shm_size = 64
apc.ttl = 7200

E finalmente, meu pool php-fpm:

listen = /var/run/php5-fpm.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0666
pm.max_children = 9
pm.start_servers = 3
pm.min_spare_servers = 2
pm.max_spare_servers = 4
pm.max_requests = 200

Além disso, como eu sei que o Varnish está trabalhando com o WordPress? Eu sei que tenho que fazer algumas configurações específicas para verniz e WP jogar bem juntos, e eu fiz seguir este link , mas como eu sei que está funcionando?

Obrigado em todos avançados (:

    
por Julian Fernandes 25.05.2012 / 22:50

1 resposta

2

Você tem uma configuração muito boa para sua carga. 20rps para scripts php é suficiente para 200k + pageviews diários.

As coisas para você são: %código%  - este valor é muito pequeno. Todos os seus dados ativos no innodb devem caber no buffer pool, deixando espaço suficiente para logs transacionais.

innodb_buffer_pool_size = 10M - você pode ficar sem isso rapidamente. Eu sugiro que você verifique as conexões nginx sob carga real usando o módulo stubstatus e ajuste os primeiros dias em que seu serviço será executado.

Você também pode aumentar a simultaneidade do php worker_connections 1024; - para usar RAM e CPU extras. Faça isso se você tiver problemas com o backlog completo do tcp ( pm.max_children = 9 )

Você pode atingir o limite max_children se tiver uma alta taxa de solicitações e / ou seus scripts forem lentos o suficiente. Aumentar o máximo de threads / processos em funcionamento aumentará a média de carga se os seus scripts estiverem ligados à cpu.

Deixe-me mostrar-lhe a matemática básica e aproximada. Você tem scripts que funcionam 100ms e usa 5ms cpu time (100ms é disco / rede IO wait) - em média.

Se você tiver mais de 9 * 1000/100 = 90 solicitações por segundo, seu backlog tcp começará a crescer e novas solicitações aguardarão algum tempo até que ele seja iniciado.

Seus scripts consumirão 90 * 10/1000 = 45% do tempo do usuário da CPU a partir do núcleo da CPU. Não muito, não é?

Se você aumentar max_children para 15, poderá receber 150 solicitações por segundo sem diminuir a velocidade, mas os scripts poderão consumir 75% do tempo da CPU do núcleo único.

É bom até que você tenha muita carga. Se você não tiver CPU ou RAM suficientes para trabalhar com a concorrência escolhida - seu servidor atingirá a média de carga - isso significa que os scripts ficarão lentos devido ao congestionamento da CPU. Servidor com valores de Carga Média aproximadamente 2-4 vezes da contagem de núcleos da CPU geralmente é responsivo o suficiente. O processamento de solicitações será um pouco mais lento, mas você pode processar uma taxa de solicitação mais alta. Se você não tiver RAM suficiente - o servidor começará a trocar, carregar discos e limitar a CPU.

Portanto, muito poucos max_children - você não manipulará a taxa de solicitação alta. Demasiado - e o seu servidor ficará suspenso sob alta carga.

    
por 27.05.2012 / 06:05