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 de conexão. No entanto, quando recebemos nossos dias de tráfego intenso (mais de 50 mil visitas), o site rastreia e leva 30 segundos + para recuperar o conteúdo do apache.

O site está sendo executado no Expression Engine (CMS) (em PHP) e eu segui seu guia de otimização de carga pesada. Eu pesquisei e segui algumas para o apache com alguma sorte, conseguindo chegar onde está agora, mas preciso obter tempos de resposta constantes.

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

Alguma recomendação?

    
por Parrots 20.06.2009 / 16:08

6 respostas

18

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

  1. Caching PHP avançado (APC) como foi 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 este assunto, já que o mod_php é geralmente o mais rápido. No entanto, eu diria que você tem um único servidor Apache fornecendo tanto conteúdo PHP dinâmico quanto 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 porque o PHP é um módulo em todos os segmentos do Apache.

Para o Apache:

  1. Use o MPM do trabalhador
  2. Ativar KeepAlive

Você também pode ir mais longe ao considerar mudar do Apache para o Lighttpd ou Nginx . Eu amo o Apache. Eu uso o bobo de muitos de seus recursos avançados. Eu aceito sua 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 valerão 10 vezes quando for gasto analisando e corrigindo consultas, em vez de ajustar seus valores my.cnf. Eu não estou dizendo que não é importante ter seu caching, conexões, etc. correto ... mas para a maioria das pessoas é apenas 9% do problema.
  2. Durante o seu controle de qualidade, ative o log de consulta geral em seu teste / dev mysqld para capturar todas as consultas enviadas. (NÃO faça isso no seu servidor mysql de produção!)
  3. Use EXPLIQUE para analisar as consultas. Especialmente se você estiver usando uma estrutura com um ORM (abstrair o banco de dados e impedir que você escreva seu próprio SQL), você precisará limpar JOINS externos, SELECTs sem 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 profiler de consulta

Outras ferramentas que valem a pena considerar são mk-visual-explain

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

    
por 20.06.2009 / 17:57
6

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

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 vhost! Eliminará / reduzirá drasticamente as verificações de disco por todas as solicitações de http ... elas realmente são adicionadas.

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>
    
por 13.04.2011 / 05:46
5

Algumas coisas vêm à mente.

O cache de opcode é sempre uma boa ideia. Eu prefiro o link sobre a APC. Se você não está desenvolvendo com a APC ao longo do caminho, é quase sempre doloroso. Eaccelerator, embora não tão chique, parece funcionar.

Um proxy reverso também é uma boa ideia, mas você precisa observar o uso da RAM. Eu acho o Apache 2.2 com o mpm-worker para ocupar uma quantidade razoável de RAM por conta própria. No seu caso eu recomendaria algo mais claro como o Nginx e rodaria o Apache com PHP como FASTCGI ou simplesmente deixaria como por 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 um servidor de aplicativos.

Se você estiver executando uma versão bastante recente do Mysql 5.1, como pelo menos 5.1.24, agora você tem acesso a logs lentos de sub-segundos. Gostaria de começar long_query_time em 1 ou 2 e, em seguida, reduzi-lo para 0,5, como você obter um identificador sobre os realmente longos. Há também muitas informações de ajuste geral na rede para o Mysql, mas você não tem a RAM para fazer muito. Você aumentou alguma das configurações do padrão? A maioria dos arquivos my.cnf padrão é configurada para usar cerca de 64 MB de RAM. Pelo menos eu aumentaria o key_buffer de 16MB para 64MB.

Além disso, você está usando tabelas Myisam ou Innodb? Se você estiver mantendo sessão no banco de dados, será necessário alterar a tabela de sessão para Innodb (ou transformá-la em cookie) em vez de deixar uma tabela Mysiam que bloqueie em nível de tabela em vez de bloquear em nível de linha. Basicamente, qualquer tabela com mais de 20% de gravação para 80% de leituras é uma candidata a mudar para o Innodb. Lembre-se de que você precisa equilibrar a quantidade de RAM entre as tabelas Myisam e Innodb, pois os buffers de cada um são configurados separadamente.

E, por último, outros 512MB de RAM iriam longe na sua configuração ou até mesmo outro VPS de 512MB para rodar o Mysql se for mais barato ou mais ou menos o mesmo preço. Eu realmente me inclino para uma segunda instância porque isso duplicará o disco IO disponível. Um dos problemas com os servidores VPS é que o seu IO não está protegido de outras pessoas no mesmo servidor físico.

Hmmm meu post todo sorta brain, mas dá-lhe um monte de lugares para procurar. Boa sorte.

    
por 20.06.2009 / 19:19
2
  • Use um cache de opcode para o php como o apc.
  • Use um acelerador de http como o squid ou o verniz.
por 20.06.2009 / 16:23
1

Em uma situação de pouca memória (512Mb é 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 depois de muito ajustes, e há opções mais leves que isso. Obviamente, isso não é possível se houver recursos do Apache dos quais você depende que não sejam suportados em outros servidores.

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

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

    
por 20.06.2009 / 19:53
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 se tornou pesado no processador.

Um Benchmark do Wordpress AB (ab -n 500 -c 25 link ) do nginx / apc / phpfpm / mysql (local) no EC2 resultou em ~ 2 pedidos / segundo em seu nível de entrada "2GB RAM / 1 Compute Unit Server".

O mesmo Benchmark é executado contra a mesma pilha exata (implementada pelo script para o SO idêntico) em um Rackspace Cloudserver de 512 MB que retorna ~ 80 req / segundo. Então 4x menos ram, desempenho 40x neste experimento rudimentar.

O topo da exibição durante o AB mostra que o EC2 simplesmente não conseguiu lidar com a simultaneidade, e imediatamente atingirá 100% da carga da CPU e travará. Visualizando o topo no servidor de 512MB (CPU quad core virtualizado) durante o mesmo benchmark, os núcleos atingiriam ~ 60% de carga e lidariam suavemente com o benchmark.

Os VPS são extremamente fáceis de rodar e desligar sem compromisso, não faz mal colocar a infra-estrutura da sua VM / VPS no teste!

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

    
por 13.04.2011 / 06:38