Otimize o apache / php / mysql em execução no VPS para carga pesada

17

Pergunta sobre como otimizar um servidor apache / mysql em um VPS com 512m de RAM. Sob carga normal, tudo corre rápido, sem atraso na conexão. No entanto, quando recebemos nossos dias de tráfego intenso (mais de 50 mil visitas), o site é rastreado e leva 30 segundos ou mais para recuperar o conteúdo do apache.

O site está sendo executado no Expression Engine (CMS) (em PHP) e eu segui o guia de otimização de carga pesada. Eu pesquisei no Google e segui alguns por aí para apache com alguma sorte, chegando até onde está agora, mas preciso obter tempos de resposta constantes.

Suponho que isso seja diferente da pergunta 'otimizar para pouca memória' aqui, pois tenho RAM suficiente (para o que estou tentando fazer), só preciso fazer com que o servidor não engasgue com carga pesada.

Alguma recomendação?

Papagaios
fonte
1
Apenas um follow-up - mudou para Lighttpd e já a diferença é incrível, lidando com a carga muito melhor. Tenho mais otimizações por vir, mas isso ajudou muito. E eu estava usando o eaccelerator, que havia escolhido na APC, desde que foi solicitado.
Papagaios

Respostas:

18

Para PHP, existem duas coisas importantes que aumentarão a capacidade:

  1. Cache avançado de PHP (APC), conforme mencionado. É isso que usamos no Yahoo !. Existem outros projetos semelhantes, mas este é o bebê de Rasmus.
  2. FastCGI em vez de mod_php. Há um debate sobre esse assunto, já que o mod_php é geralmente o mais rápido. No entanto, suponho que você tenha um único servidor Apache fornecendo conteúdo PHP dinâmico e ativos estáticos (JS, CSS, flash, imagens, PDFs etc.). As solicitações para esses ativos estáticos não precisam consumir tanta memória, mas como o PHP é um módulo, ele está em todos os threads do Apache.

Para o Apache:

  1. Usar trabalhador MPM
  2. Ativar KeepAlive

Você também pode ir longe ao considerar mudar do Apache para o Lighttpd ou Nginx . Eu amo o Apache. Eu uso o tolo de muitos dos seus recursos avançados. Aceito a sobrecarga porque preciso do que ela oferece. Para a pilha LAMP comum, é mais do que o necessário e um desperdício de recursos.

Para o MySQL:

  1. Seus esforços de otimização serão recompensados ​​10 vezes quando gastos analisando e corrigindo consultas, em vez de ajustar seus valores my.cnf. Não estou dizendo que não é importante obter o cache, as conexões, etc. corretos ... mas para a maioria das pessoas, isso representa apenas 9% do problema.
  2. Durante seu controle de qualidade, ative o log de consultas gerais no seu armazenamento temporário / dev mysqld para capturar todas as consultas enviadas. (NÃO faça isso no seu servidor mysql de produção!)
  3. Use EXPLAIN para analisar as consultas. Especialmente se você estiver usando uma estrutura com um ORM (abstrai o banco de dados e evita que você crie seu próprio SQL), será necessário limpar JOINs estranhos, SELECTs sem a cláusula WHERE, ORDER BYs que induzem 'using filesort' e consultas que não usam índices.
  4. Se você estiver usando o MySQL 5.1, aproveite o perfil de consulta .

Outras ferramentas que vale a pena considerar são o mk-visual-Explique

Eu citei 10 ótimas referências. Essas coisas devem fazer você cantarolar. Por favor, deixe-nos saber como fica.

Bruno Bronosky
fonte
6

Mova seus arquivos de sessão PHP para um tmpfs , use APC (ou outro) e remova todos os módulos PHP que você não precisa. Remova todos os módulos do Apache que você não precisa / usa.

Para criar um tmpfs (um diretório na RAM!)

mkdir /tmpfs; chmod 777 /tmpfs
mount -t tmpfs -o size=256M tmpfs /tmpfs

Em / etc / fstab, adicione a linha abaixo para criá-la na reinicialização!

tmpfs     /tmpfs    tmpfs   size=256m,mode=0777    0       0

Em /etc/apache2/php.ini, ajuste para armazenar suas sessões na RAM (tmpfs)!

session.save_handler = files
session.save_path = "/tmpfs"

Nota: Com seus arquivos PHP E arquivos de sessão na RAM, você mal toca no disco!

Use expires_module no apache para que os navegadores armazenem em cache a maioria das coisas.

ExpiresActive On
ExpiresDefault "access plus 90 days"
ExpiresByType image/gif "access plus 90 days"
ExpiresByType image/ico "access plus 90 days"
ExpiresByType image/png "access plus 90 days"
ExpiresByType image/jpeg "access plus 90 days"
ExpiresByType image/x-icon "access plus 90 days"
ExpiresByType text/css "Access plus 90 days"
ExpiresByType text/html "Access plus 90 days"
ExpiresByType application/x-shockwave-flash "Access plus 90 days"
ExpiresByType application/x-javascript "Access plus 90 days"

Não use arquivos .htaccess ! Em vez disso, codifique-os no arquivo de configuração do vhost! Eliminará / reduzirá drasticamente as verificações de disco de acordo com todas as solicitações de http ... realmente adiciona.

Options FollowSymLinks 
AllowOverride None

Exemplo de .htaccess usado no seu arquivo vhost.conf ...

<Directory /home/user/www/site.com/secure>
    Order Allow,Deny
    Deny from All
</Directory>
Anulado
fonte
5

Duas coisas vêm à mente.

O cache do Opcode é sempre uma boa ideia. Eu prefiro http://eaccelerator.net/ sobre APC. Se você não desenvolveu o APC ao longo do caminho, tentar adicioná-lo é quase sempre doloroso. O acelerador, embora não tão sofisticado, parece funcionar.

Um proxy reverso também é uma boa ideia, mas você precisa observar o uso da RAM. Acho o Apache 2.2 com mpm-worker para ocupar uma quantidade razoável de RAM por conta própria. No seu caso, eu recomendaria algo mais leve como o Nginx e execute o Apache com PHP como FASTCGI ou apenas deixe-o conforme o processo. A idéia de usar Varnish, Squid, Nginx, etc é fazer com que eles sirvam conteúdo estático, lidem com conexões de usuários e passem apenas solicitações PHP para o Apache, que você trata como servidor de aplicativos.

Se você estiver executando uma versão bastante recente do Mysql 5.1, como pelo menos 5.1.24, agora terá acesso a logs lentos abaixo de segundo. Eu começaria long_query_time em 1 ou 2 e depois o reduziria para 0,5 conforme você lida com os realmente longos. Também há muitas informações gerais de ajuste na rede para o Mysql, mas você não tem RAM para fazer muito. Você aumentou alguma das configurações do padrão? A maioria dos arquivos my.cnf padrão são configurados para usar cerca de 64 MB de RAM. É o mínimo que eu aumentaria o key_buffer de 16 MB para 64 MB.

Além disso, você está usando as tabelas Myisam ou Innodb? Se você estiver mantendo a sessão no banco de dados, altere a tabela de sessão para Innodb (ou faça com que seja um cookie) em vez de deixá-la como uma tabela Mysiam, que trava no nível da tabela em vez de no nível da linha. Basicamente, qualquer tabela com mais de 20% de gravação e 80% de leitura é candidata à mudança para o Innodb. Lembre-se de que você precisará equilibrar a quantidade de RAM entre as tabelas Myisam e Innodb, pois os buffers de cada uma são configurados separadamente.

E, por fim, outros 512 MB de RAM percorreriam um longo caminho em sua configuração ou até outros 512 MB VPS para executar o Mysql, se isso fosse mais barato ou aproximadamente o mesmo preço. Na verdade, eu me inclino para uma segunda instância, porque isso dobrará a E / S de disco disponível. Um dos problemas com os servidores VPS é que o seu IO não está protegido contra outras pessoas no mesmo servidor físico.

Hmmm, meu post está meio disperso, mas dá a você muitos lugares para procurar. Boa sorte.

Kashani
fonte
2
  • Use um cache de opcode para php como apc.
  • Use um acelerador http como squid ou verniz.
Wittwerch
fonte
1

Em uma situação de pouca memória (512 Mb é baixo, para um servidor de alto tráfego), vale a pena considerar sua escolha de servidor da Web e mecanismo de banco de dados.

O Lighttp é mais leve do que o Apache geralmente pode ser feito após muitos ajustes, e há opções mais leves do que isso mesmo. Obviamente, isso não é possível se houver recursos do Apache dos quais você depende e que não são suportados em outros servidores.

O sqlite é muito mais rígido que o mySQL e mais rápido em muitas condições também. Verifique se o mecanismo que você está usando suporta isso e também se ele faz uma tentativa.

A outra opção, a opção fácil, é obter mais RAM na VM, se você puder pagar.

David Spillett
fonte
1

Além das ótimas sugestões aqui, deve-se notar que todos os VPS não são criados iguais. Na minha experiência, o PHP acabou por ser pesado na CPU.

Um benchmark do Wordpress AB (ab -n 500 -c 25 http://domain.com/index.php ) do nginx / apc / phpfpm / mysql (local) no EC2 resultou em ~ 2 solicitações / segundo em seu nível de entrada "2GB Servidor de unidade de computação RAM / 1 ".

O mesmo Benchmark executado na mesma pilha exata (implementada por script em um SO idêntico) em um Rackspace Cloudserver de 512 MB retorna ~ 80 req / segundo. Portanto, 4x menos ram, desempenho 40x neste experimento rudimentar.

Ao visualizar a parte superior durante o AB, você vê que o EC2 simplesmente não conseguia lidar com a simultaneidade e atingia imediatamente 100% da carga da CPU e travava. Vendo a parte superior do servidor de 512 MB (CPU quad core virtualizada) durante o mesmo benchmark, os núcleos atingiriam ~ 60% de carga e manipulariam com facilidade o benchmark.

Os VPSs são extremamente fáceis de ativar e desativar sem compromisso, não faz mal colocar a infraestrutura em que sua VM / VPS reside em teste!

EDIT 1: Além disso, a Instância pequena "High CPU" do EC2 conseguiu apenas ~ 10 / req segundo, com a CPU ainda sendo o gargalo. Minha conclusão foi que você sacrifica o desempenho por estabilidade / robustez com o EC2, e é claro que existem muitos casos de uso que exigem esse ambiente.

iainlbc
fonte
Além disso, considere o nginx (v.1 lançado hoje). O wordpress.com trocou sua configuração litespeed pelo nginx, tornando-o claramente um servidor web capaz.
precisa saber é o seguinte
Nginx é realmente impressionante. Eu só queria que ele pudesse ler regras mod_rewrite a partir de arquivos .htaccess.
Martijn Heemels