Táticas para usar PHP em um site de alta carga


242

Antes de responder a isso, nunca desenvolvi nada popular o suficiente para atingir altas cargas de servidor. Trate-me como (um suspiro) um alienígena que acaba de desembarcar no planeta, apesar de conhecer PHP e algumas técnicas de otimização.


Estou desenvolvendo uma ferramenta em PHP que pode atingir muitos usuários, se funcionar corretamente. No entanto, embora eu seja totalmente capaz de desenvolver o programa, sou praticamente sem noção quando se trata de criar algo que possa lidar com um tráfego enorme. Então, aqui estão algumas perguntas (sinta-se à vontade para transformar essa pergunta também em um encadeamento de recursos).

Bases de dados

No momento, pretendo usar os recursos do MySQLi no PHP5. No entanto, como devo configurar os bancos de dados em relação a usuários e conteúdo? Eu realmente preciso de vários bancos de dados? No momento, tudo se mistura em um banco de dados - embora eu esteja pensando em espalhar dados do usuário para um, conteúdo real para outro e, finalmente, conteúdo principal do site (mestres de modelos etc.) para outro. Meu raciocínio por trás disso é que o envio de consultas para bancos de dados diferentes facilitará a carga neles como um banco de dados = 3 fontes de carregamento. Além disso, isso ainda seria eficaz se todos estivessem no mesmo servidor?

Armazenamento em cache

Eu tenho um sistema de modelo que é usado para criar as páginas e trocar variáveis. Os modelos mestres são armazenados no banco de dados e cada vez que um modelo é chamado, sua cópia em cache (um documento html) é chamada. No momento, tenho dois tipos de variáveis ​​nesses modelos - um var estático e um var dinâmico. Vars estáticos são geralmente coisas como nomes de páginas, o nome do site - coisas que não mudam frequentemente; Vars dinâmicos são coisas que mudam a cada carregamento da página.

Minha pergunta sobre isso:

Digamos que eu tenha comentários sobre diferentes artigos. Qual é uma solução melhor: armazene o modelo de comentário simples e renderize comentários (de uma chamada de banco de dados) toda vez que a página for carregada ou armazene uma cópia em cache da página de comentários como uma página html - sempre que um comentário for adicionado / editado / excluído a página é reconectada.

Finalmente

Alguém tem alguma dica / ponteiro para executar um site de alta carga em PHP. Tenho certeza de que é uma linguagem viável para usar - Facebook e Yahoo! dê uma grande precedência - mas há alguma experiência que eu deveria prestar atenção?


9
3,5 anos mais tarde e eu nem me lembro o que eu estava trabalhando, eu gostaria de saber o que eu pensei foi tão legal também :)
Ross

8
Que esta seja uma lição para você sobre otimização prematura :)
Rimu Atkinson

Respostas:


89

Não existem dois sites iguais. Você realmente precisa de uma ferramenta como jmeter e benchmark para ver onde estarão os pontos problemáticos. Você pode gastar muito tempo adivinhando e melhorando, mas não verá resultados reais até medir e comparar suas alterações.

Por exemplo, por muitos anos, o cache de consultas do MySQL foi a solução para todos os nossos problemas de desempenho. Se o seu site estiver lento, os especialistas em MySQL sugeriram ativar o cache de consultas. Acontece que, se você tiver uma carga de gravação alta, o cache é realmente prejudicial. Se você o ativasse sem testar, nunca saberia.

E não esqueça que você nunca terminou de dimensionar. Um site que lide com 10req / s precisará de alterações para oferecer suporte a 1000req / s. E se você tiver sorte o suficiente para suportar 10.000req / s, sua arquitetura provavelmente também parecerá completamente diferente.

Bases de dados

  • Não use o MySQLi - O PDO é a camada de acesso ao banco de dados OO 'moderna'. O recurso mais importante a ser usado são os espaços reservados nas suas consultas. É inteligente o suficiente para usar as preparações do servidor e outras otimizações para você também.
  • Você provavelmente não deseja quebrar seu banco de dados neste momento. Se você achar que um banco de dados não está cortando, existem várias técnicas para expandir, dependendo do seu aplicativo. A replicação para servidores adicionais normalmente funciona bem se você tiver mais leituras do que gravações. O sharding é uma técnica para dividir seus dados em várias máquinas.

Armazenamento em cache

  • Você provavelmente não deseja armazenar em cache no seu banco de dados. O banco de dados normalmente é o seu gargalo, portanto, adicionar mais IOs a ele normalmente é uma coisa ruim. Existem vários caches PHP por aí que realizam coisas semelhantes como APC e Zend.
  • Avalie seu sistema com o cache ativado e desativado. Aposto que seu cache é mais pesado do que servir as páginas diretamente.
  • Se levar muito tempo para criar seus comentários e dados de artigos a partir do banco de dados, integre o memcache ao seu sistema. Você pode armazenar em cache os resultados da consulta e armazená-los em uma instância armazenada em cache. É importante lembrar que a recuperação dos dados do memcache deve ser mais rápida do que montá-los no banco de dados para obter algum benefício.
  • Se seus artigos não forem dinâmicos ou você tiver alterações dinâmicas simples após a geração, considere gravar html ou php no disco. Você pode ter uma página index.php que procure no artigo o conteúdo do disco, se houver, transmite para o cliente. Caso contrário, gera o artigo, grava-o no disco e envia-o ao cliente. Excluir arquivos do disco faria com que as páginas fossem reescritas. Se um comentário for adicionado a um artigo, exclua a cópia em cache - ela será regenerada.

10
@ gravação em disco. Você pode até abandonar o index.php e deixar o Apache fazer o trabalho por você, para que index.php seja chamado apenas se o caminho não existir. Você usaria mode_rewrite para isso.
troelskn

5
-1, o PDO é significativamente mais lento que o MySQLi ou mesmo a extensão MySQL.
Alix Axel

4
O PDO foi muito mais lento que o mysqli e não funcionou corretamente para consultas aninhadas para mim. O Mysqli também suporta preparações do lado do servidor e parâmetros vinculados, assim como o DOP.
Daren Schwenke

5
Não acredito que isso foi aceito como resposta. Não é muito bom.
26610 symcbean

1
about: caching - imagens, css, htm e js ajudarão, também desative os cookies nas imagens!
Talvi Watia

61

Sou desenvolvedor líder em um site com mais de 15 milhões de usuários. Tivemos muito poucos problemas de dimensionamento porque planejamos isso com antecedência e dimensionamos cuidadosamente. Aqui estão algumas das estratégias que posso sugerir da minha experiência.

ESQUEMA Primeiramente, desnormalize seus esquemas. Isso significa que, em vez de ter várias tabelas relacionais, você deve optar por ter uma tabela grande. Em geral, as junções são um desperdício de recursos preciosos do banco de dados, porque fazer várias preparações e agrupamento queima as E / Ss do disco. Evite-os quando puder.

A desvantagem aqui é que você armazenará / extrairá dados redundantes, mas isso é aceitável porque os dados e a largura de banda intra-gaiola são muito baratos (discos maiores), enquanto várias E / Ss preparadas são ordens de magnitude mais caras (mais servidores) .

INDEXAÇÃO Certifique-se de que suas consultas utilizem pelo menos um índice. Cuidado, porém, que os índices custarão se você escrever ou atualizar com freqüência. Existem alguns truques experimentais para evitar isso.

Você pode tentar adicionar colunas adicionais não indexadas, que são paralelas às colunas indexadas. Em seguida, você pode ter um processo offline que grava as colunas não indexadas nas colunas indexadas em lotes. Dessa forma, você pode controlar melhor quando o mySQL precisará recalcular o índice.

Evite consultas calculadas como uma praga. Se você precisar calcular uma consulta, tente fazer isso uma vez no momento da gravação.

CACHING Eu recomendo o Memcached. Foi provado pelos maiores players da pilha PHP (Facebook) e é muito flexível. Existem dois métodos para fazer isso: um é o cache da camada de banco de dados, o outro é o cache da camada de lógica de negócios.

A opção da camada do banco de dados exigiria o armazenamento em cache do resultado das consultas recuperadas do banco de dados. Você pode fazer o hash da sua consulta SQL usando md5 () e usá-la como uma chave de pesquisa antes de acessar o banco de dados. A vantagem disso é que é muito fácil de implementar. A desvantagem (dependendo da implementação) é que você perde flexibilidade porque está tratando todos os caches da mesma forma em relação à expiração do cache.

Na loja em que trabalho, usamos o cache da camada de negócios, o que significa que cada classe concreta em nosso sistema controla seu próprio esquema de cache e o tempo limite do cache. Isso funcionou muito bem para nós, mas lembre-se de que os itens recuperados do banco de dados podem não ser os mesmos do cache, portanto, você precisará atualizar o cache e o banco de dados juntos.

SHARDING DE DADOS A replicação apenas leva você até agora. Mais cedo do que o esperado, suas gravações se tornarão um gargalo. Para compensar, certifique-se de oferecer suporte ao compartilhamento de dados o mais cedo possível. Você provavelmente vai querer se matar depois, se não o fizer.

É muito simples de implementar. Basicamente, você deseja separar a autoridade principal do armazenamento de dados. Use um banco de dados global para armazenar um mapeamento entre chaves primárias e IDs de cluster. Você consulta esse mapeamento para obter um cluster e, em seguida, consulta o cluster para obter os dados. Você pode armazenar em cache essa operação de pesquisa, que a tornará insignificante.

A desvantagem disso é que pode ser difícil reunir dados de vários shards. Mas você também pode planejar o seu caminho.

PROCESSAMENTO OFFLINE Não faça o usuário esperar pelo seu back-end, se não for necessário. Crie uma fila de tarefas e mova qualquer processamento que possa ser offline, fazendo-o separado da solicitação do usuário.


9
+1 Mãos para baixo, essa deve ser a resposta aceita. É interessante que tudo que eu já li sobre a criação de bancos de dados sempre diga "normalize todos os dados o máximo possível" sem mencionar o impacto no desempenho de fazer junções. Sempre achei intuitivamente que as junções (especialmente múltiplas) adicionavam muita sobrecarga, mas ainda não ouvi dizer isso explicitamente até agora. Eu gostaria de entender melhor o que você estava falando sobre controlar quando o MySQL calcula os índices, parece um hack muito interessante.
Evan Plaice

O compartilhamento de dados é essencial para bancos de dados que crescem demais. O Google (a empresa não é o mecanismo de pesquisa) tem muitas coisas interessantes a dizer sobre a implementação de esquemas de sharding. O processamento offline também é enorme quando se trata de limitar o número de gravações no banco de dados (e limitar o número de recálculos do índice da tabela). Já vi muitos blogs (e acho que até o Stack Overflow) usam essa técnica para seus sistemas de comentários / feedback gerados pelos usuários.
Evan Plaice

1
Obrigado pelos comentários. É surpreendente que alguns defendem a criação de perfil de código de camada intermediária quando a quantidade de tempo de execução do VAST é gasta em E / S de dados ou E / S de cliente / servidor. Uma otimização ubber complicada que economiza 20% de tempo de execução de um processo PHP que leva 40ms é inútil em comparação com economias simples de 5% de uma consulta de banco de dados 1s.
theInteligente

42

Eu trabalhei em alguns sites que recebem milhões / hits / mês apoiados por PHP e MySQL. Aqui estão alguns princípios básicos:

  1. Cache, cache, cache. O armazenamento em cache é uma das maneiras mais simples e eficazes de reduzir a carga no servidor da web e no banco de dados. Armazene em cache o conteúdo da página, consultas, computação cara, qualquer coisa que esteja vinculada a E / S. Memcache é absolutamente simples e eficaz.
  2. Use vários servidores quando estiver no limite máximo. Você pode ter vários servidores Web e vários servidores de banco de dados (com replicação).
  3. Reduza o número geral de solicitações para seus servidores da web. Isso implica o cache de JS, CSS e imagens usando cabeçalhos de expiração. Você também pode mover seu conteúdo estático para uma CDN, o que acelerará a experiência do usuário.
  4. Medida e referência. Execute o Nagios em suas máquinas de produção e teste de carga no servidor dev / qa. Você precisa saber quando o servidor pegará fogo, para que você possa evitá-lo.

Eu recomendo a leitura de Construindo sites escaláveis , que foi escrito por um dos engenheiros do Flickr e é uma ótima referência.

Confira também meu post sobre escalabilidade, que possui muitos links para apresentações sobre escalabilidade em vários idiomas e plataformas: http://www.ryandoherty.net/2008/07/13/unicorns-and-scalability/


1
+1 Há muitas informações boas aqui. Ultimamente, tenho pesquisado mais sobre esse assunto e sua resposta está alinhada com tudo o que li. Memcache, cache, CDN para conteúdo estático, reduzindo solicitações; tudo de bom. Eu também acrescentaria, geraria hashes em arquivos de conteúdo estático (se você estiver atrás de uma CDN / cache) no lado do servidor, para que os arquivos atualizados tenham uma assinatura exclusiva no cache. Além disso, combine arquivos de origem estática (css, javascript) em tempo real (e armazene-os em cache com hashes de nome de arquivo) para reduzir as solicitações. Além disso, gerar polegares dinamicamente (e armazená-los no cache)
Evan Solha

O Google criou um módulo apache chamado mod_pagespeed que pode lidar com todas as concatenações, minificação, renomeação de arquivos para incluir hash etc. para todo o conteúdo estático. Ele deve adicionar apenas um pouco de sobrecarga de processamento aos servidores inicialmente até que os caches (e CDN) sejam preenchidos com a maior parte do conteúdo. Além disso, por segurança, geralmente é uma má idéia colocar tabelas acessíveis ao público (usuários) no mesmo banco de dados que as tabelas que lidam com o back-end (se por algum motivo uma das tabelas tiver sido invadida).
Evan Plaice

39

Re: DOP / MySQLi / MySQLND

@ gary

Você não pode simplesmente dizer "não use o MySQLi", pois eles têm objetivos diferentes. O PDO é quase como uma camada de abstração (embora não seja realmente) e foi projetado para facilitar o uso de vários produtos de banco de dados, enquanto o MySQLi é específico para conexões do MySQL. É errado dizer que o PDO é a camada de acesso moderna no contexto da comparação com o MySQLi porque sua declaração implica que a progressão foi mysql -> mysqli -> PDO, o que não é o caso.

A escolha entre MySQLi e PDO é simples - se você precisar oferecer suporte a vários produtos de banco de dados, use o PDO. Se você está apenas usando o MySQL, pode escolher entre DOP e MySQLi.

Então, por que você escolheria o MySQLi ao invés do PDO? Ver abaixo...

@ross

Você está certo sobre o MySQLnd, que é a mais nova biblioteca de nível de idioma do MySQL, no entanto, não substitui o MySQLi. O MySQLi (como no PDO) permanece como você interage com o MySQL através do seu código PHP. Ambos usam o libmysql como o cliente C por trás do código PHP. O problema é que o libmysql está fora do mecanismo principal do PHP e é aí que entra o mysqlnd, ou seja, é um driver nativo que faz uso dos principais componentes internos do PHP para maximizar a eficiência, especificamente no que diz respeito ao uso da memória.

O MySQLnd está sendo desenvolvido pelo próprio MySQL e recentemente chegou à filial do PHP 5.3, que está em testes de RC, pronta para ser lançada ainda este ano. Você poderá usar o MySQLnd com o MySQLi ... mas não com o DOP. Isso dará ao MySQLi um aumento de desempenho em muitas áreas (não todas) e a tornará a melhor escolha para a interação do MySQL se você não precisar da abstração, como os recursos do PDO.

Dito isto, o MySQLnd agora está disponível no PHP 5.3 para DOP e, portanto, você pode obter as vantagens dos aprimoramentos de desempenho do ND para o DOP; no entanto, o DOP ainda é uma camada de banco de dados genérica e, portanto, dificilmente poderá se beneficiar tanto as melhorias no ND como o MySQLi pode .

Alguns benchmarks úteis podem ser encontrados aqui, embora sejam de 2006. Você também precisa estar ciente de coisas como esta opção .

Há muitas considerações que precisam ser levadas em consideração ao decidir entre MySQLi e PDO. Na realidade, isso não será importante até que você obtenha números de solicitação rediculamente altos e, nesse caso, faz mais sentido usar uma extensão que foi projetada especificamente para o MySQL, em vez de uma que abstraia as coisas e fornece um driver do MySQL. .

Não é uma questão simples de qual é o melhor, porque cada um tem vantagens e desvantagens. Você precisa ler os links que forneci e ter sua própria decisão, testá-lo e descobrir. Eu usei o PDO em projetos anteriores e é uma boa extensão, mas minha opção pelo desempenho puro seria o MySQLi com a nova opção MySQLND compilada (quando o PHP 5.3 for lançado).


6
Mudei do PDO para o mysqli e as consultas regulares começaram a ser executadas exatamente duas vezes mais rápido.
21468 serg

5
@erg: gostaria de postar alguns testes para confirmar isso?, porque duvido seriamente que simplesmente mudar do PDO para o mysqli daria a você um aumento de velocidade.
Stann

23

Geral

  • Não tente otimizar antes de começar a ver a carga do mundo real. Você pode adivinhar, mas se não, você perdeu seu tempo.
  • Use jmeter , xdebug ou outra ferramenta para avaliar o site.
  • Se o carregamento começar a ser um problema, o cache de objetos ou dados provavelmente estará envolvido; portanto, geralmente leia as opções de cache (memcached, opções de cache do MySQL)

Código

  • Faça o perfil do seu código para saber onde está o gargalo e se está no código ou no banco de dados

Bases de dados

  • Use o MYSQLi se a portabilidade para outros bancos de dados não for vital, caso contrário , a DOP
  • Se os benchmarks revelarem que o banco de dados é o problema, verifique as consultas antes de iniciar o cache. Use EXPLAIN para ver onde suas consultas estão ficando mais lentas.
  • Depois que as consultas são otimizadas e o banco de dados é armazenado em cache de alguma maneira, convém usar vários bancos de dados. A replicação para vários servidores ou o sharding (divisão dos dados em vários bancos de dados / servidores) pode ser apropriado, dependendo dos dados, das consultas e do tipo de comportamento de leitura / gravação.

Armazenamento em cache

  • Muita escrita foi feita no armazenamento em cache de códigos, objetos e dados. Procure artigos sobre APC , Zend Optimizer , memcached , QuickCache , JPCache . Faça isso antes de realmente precisar, e você estará menos preocupado em começar sem otimização.
  • O APC e o Zend Optimizer são caches de código de operação, eles aceleram o código PHP evitando a reparação e recompilação de código. Geralmente simples de instalar, vale a pena fazer cedo.
  • Memcached é um cache genérico, que você pode usar para armazenar em cache consultas, funções ou objetos PHP ou páginas inteiras. O código deve ser escrito especificamente para usá-lo, o que pode ser um processo envolvido se não houver pontos centrais para lidar com a criação, atualização e exclusão de objetos em cache.
  • QuickCache e JPCache são caches de arquivos, caso contrário, semelhantes ao Memcached. O conceito básico é simples, mas também requer código e é mais fácil com pontos centrais de criação, atualização e exclusão.

Diversos

  • Considere servidores da web alternativos para alta carga. Servidores como lighthttp e nginx podem lidar com grandes quantidades de tráfego em muito menos memória que o Apache , se você puder sacrificar o poder e a flexibilidade do Apache (ou se você simplesmente não precisar dessas coisas, o que geralmente não é necessário).
  • Lembre-se de que o hardware é surpreendentemente barato hoje em dia. Portanto, não se esqueça de custar o esforço de otimizar um grande bloco de código em vez de "vamos comprar um servidor monstro".
  • Considere adicionar as tags "MySQL" e "scaling" a esta pergunta

9

A APC é uma necessidade absoluta. Não apenas contribui para um ótimo sistema de cache, mas o ganho dos arquivos PHP armazenados em cache automaticamente é uma dádiva de Deus. Quanto à idéia de vários bancos de dados, não acho que você obteria muito com diferentes bancos de dados no mesmo servidor. Isso pode proporcionar um ganho de velocidade durante o tempo de consulta, mas duvido que o esforço necessário para implantar e manter o código para todos os três garanta que eles estejam sincronizados valha a pena.

Também recomendo executar o Xdebug para encontrar gargalos no seu programa. Isso fez da otimização uma brisa para mim.


9

Em primeiro lugar, como acho que Knuth disse, "a otimização prematura é a raiz de todo mal". Se você não precisa lidar com esses problemas no momento, não lembre-se de fornecer algo que funcione corretamente primeiro. Dito isto, se as otimizações não puderem esperar.

Tente criar um perfil de suas consultas ao banco de dados, descobrir o que é lento e o que acontece muito e criar uma estratégia de otimização a partir disso.

Eu investigaria o Memcached, pois é o que muitos sites de maior carregamento usam para armazenar em cache de maneira eficiente o conteúdo de todos os tipos, e a interface do objeto PHP a ele é bastante agradável.

Dividir bancos de dados entre servidores e usar algum tipo de técnica de balanceamento de carga (por exemplo, gerar um número aleatório entre 1 e # bancos de dados redundantes com os dados necessários - e usar esse número para determinar a qual servidor de banco de dados se conectar) também pode ser uma excelente maneira de aumentar eficiência.

Tudo isso funcionou muito bem no passado em alguns sites de carga bastante alta. Espero que isso ajude você a começar :-)


1
RequiredFullQuote: "Devemos esquecer sobre pequenas eficiências, digamos cerca de 97% do tempo: otimização prematura é a raiz de todo o mal"
Alister Bulman

RequiredReallyFullQuote: "Os programadores perdem muito tempo pensando ou se preocupando com a velocidade das partes não críticas de seus programas, e essas tentativas de eficiência realmente têm um forte impacto negativo quando a depuração e a manutenção são consideradas. Devemos esquecer as pequenas eficiências, digamos cerca de 97% do tempo: a otimização prematura é a raiz de todo mal. No entanto, não devemos desperdiçar nossas oportunidades nesses 3% críticos ".
cHao 21/05

6

Criar um perfil do seu aplicativo com algo como o Xdebug (como o tj9991 recomendado) definitivamente será obrigatório. Não faz muito sentido apenas otimizar as coisas cegamente. O Xdebug ajudará você a encontrar os gargalos reais em seu código, para que você possa gastar seu tempo de otimização com sabedoria e corrigir trechos de código que estão causando lentidão.

Se você estiver usando o Apache, outro utilitário que pode ajudar nos testes é o Siege . Isso ajudará você a prever como o servidor e o aplicativo reagirão a altas cargas, colocando-o de acordo com o ritmo.

Qualquer tipo de cache de opcode para PHP (como APC ou um dos muitos outros) também ajudará muito.


6

Eu administro um site com 7-8 milhões de visualizações de página por mês. Não muito, mas o suficiente para que nosso servidor sentisse a carga. A solução que escolhemos foi simples: o Memcache no nível do banco de dados. Essa solução funciona bem se a carga do banco de dados for o seu principal problema.

Começamos usando o Memcache para armazenar em cache objetos inteiros e os resultados do banco de dados mais usados. Funcionou, mas também introduziu bugs (poderíamos ter evitado alguns deles se tivéssemos sido mais cuidadosos).

Então, mudamos nossa abordagem. Criamos um wrapper de banco de dados (com exatamente os mesmos métodos do nosso banco de dados antigo, para facilitar a troca) e, em seguida, subclassificamos para fornecer métodos de acesso ao banco de dados em cache do memcached.

Agora tudo o que você precisa fazer é decidir se uma consulta pode usar resultados em cache (e possivelmente desatualizados) ou não. A maioria das consultas executadas pelos usuários agora é obtida diretamente do Memcache. As exceções são atualizações e inserções, o que para o site principal acontece apenas por causa do log. Essa medida bastante simples reduziu a carga do servidor em cerca de 80%.


6

Pelo que vale a pena, o armazenamento em cache é DIRT SIMPLE no PHP, mesmo sem um pacote de extensão / auxiliar como o memcached.

Tudo que você precisa fazer é criar um buffer de saída usando ob_start().

Crie uma função de cache global. Ligarob_start , passe a função como retorno de chamada. Na função, procure uma versão em cache da página. Se existir, sirva e termine.

Se não existir, o script continuará o processamento. Quando atingir o ob_end () correspondente, chamará a função que você especificou. Nesse momento, você apenas obtém o conteúdo do buffer de saída, os solta em um arquivo, salva o arquivo e finaliza.

Adicione alguma expiração / coleta de lixo.

E muitas pessoas não percebem que você pode aninhar ob_start()/ ob_end()ligar. Portanto, se você já estiver usando um buffer de saída para, digamos, analisar anúncios ou realçar sintaxe ou qualquer outra coisa, basta aninhar outra ob_start/ob_endchamada.


+1 porque parece uma ideia interessante. Eu não sei como ele funciona bem em termos de performance
Sylverdrag

+1 porque esta é uma ideia interessante. Esses retornos de chamada poderiam chamar minha classe de cache para mim!
Xeoncross

5

Obrigado pelo conselho sobre as extensões de cache do PHP - você poderia explicar os motivos para usar um sobre o outro? Ouvi ótimas coisas sobre memcached no IRC, mas nunca ouvi falar da APC - quais são suas opiniões sobre eles? Suponho que o uso de vários sistemas de cache seja bastante contra-eficaz.

Na verdade, muitos usam APC e memcached juntos ...


4

Parece que eu estava errado . O MySQLi ainda está sendo desenvolvido. Mas, de acordo com o artigo, o PDO_MySQL agora está sendo contribuído pela equipe do MySQL. Do artigo:

A Extensão Aprimorada do MySQL - mysqli - é o carro-chefe. Ele suporta todos os recursos do servidor MySQL, incluindo charsets, instruções preparadas e procedimentos armazenados. O driver oferece uma API híbrida: você pode usar um estilo de programação procedural ou orientado a objeto com base em sua preferência. O mysqli vem com o PHP 5 e superior. Observe que o fim da vida útil do PHP 4 é 08/08/2008.

O PHP Data Objects (PDO) é uma camada de abstração de acesso ao banco de dados. O PDO permite que você use as mesmas chamadas de API para vários bancos de dados. O PDO não oferece nenhum grau de abstração SQL. PDO_MYSQL é um driver MySQL para DOP. PDO_MYSQL vem com o PHP 5. A partir do PHP 5.3, os desenvolvedores do MySQL contribuem ativamente para isso. O benefício do PDO de uma API unificada tem o preço de que os recursos específicos do MySQL, por exemplo, várias instruções, não são totalmente suportados pela API unificada.

Por favor, pare de usar o primeiro driver MySQL para PHP já publicado: ext / mysql. Desde a introdução da extensão aprimorada do MySQL - mysqli - em 2004 com o PHP 5, não há razão para ainda usar o driver mais antigo existente. O ext / mysql não suporta Charsets, Instruções Preparadas e Procedimentos Armazenados. É limitado ao conjunto de recursos do MySQL 4.0. Observe que o Suporte Estendido ao MySQL 4.0 termina em 31/12/2008. Não se limite ao conjunto de recursos de software antigo! Atualize para o mysqli, veja também Converting_to_MySQLi. O mysql está no modo somente manutenção do nosso ponto de vista.

Para mim, parece que o artigo é tendencioso para o MySQLi. Suponho que sou tendencioso em relação à DOP. Eu realmente gosto de DOP sobre MySQLi. É direto para mim. A API está muito mais próxima de outros idiomas em que eu programei. As interfaces do banco de dados OO parecem funcionar melhor.

Não encontrei nenhum recurso específico do MySQL que não estivesse disponível através do PDO. Eu ficaria surpreso se alguma vez fizesse isso.


3

A DOP também é muito lenta e sua API é bastante complicada. Ninguém em sua mente sã deve usá-lo se a portabilidade não for uma preocupação. E vamos ser sinceros, em 99% de todos os aplicativos da web não é. Você apenas segue o MySQL ou o PostrgreSQL, ou o que quer que esteja trabalhando.

Quanto à questão do PHP e o que levar em consideração. Eu acho que a otimização prematura é a raiz de todo mal. ;) Faça seu aplicativo primeiro, tente mantê-lo limpo quando se trata de programação, faça uma pequena documentação e escreva testes de unidade. Com todas as opções acima, você não terá problemas para refatorar o código quando chegar a hora. Mas primeiro você quer fazer e empurre para ver como as pessoas reagem a isso.


2

Pdo Claro que é bom, mas não tem sido alguns controvérsia sobre isso de desempenho versus mysql e mysqli, embora pareça corrigido agora.

Você deve usar o pdo se visualizar a portabilidade, mas se não, o mysqli deve ser o caminho. Possui uma interface OO, instruções preparadas e a maior parte do que o pdo oferece (exceto, bem, portabilidade).

Além disso, se o desempenho for realmente necessário, prepare-se para o driver MysqLnd (nativo do mysql) no PHP 5.3, que será muito mais bem integrado ao php, com melhor desempenho e melhor uso da memória (e estatísticas para ajuste de desempenho).

Memcache é bom se você tiver servidores em cluster (e carga semelhante ao YouTube), mas eu testaria a APC primeiro também.


2

Muitas respostas boas já foram dadas, mas eu gostaria de apontar para um cache de código de operação alternativo chamado XCache . É criado por um colaborador poderoso.

Além disso, se você precisar balancear a carga do servidor de banco de dados no futuro, o MySQL Proxy poderá muito bem ajudá-lo a conseguir isso.

Ambas as ferramentas devem se conectar a um aplicativo existente com bastante facilidade, para que essa otimização possa ser feita quando você precisar, sem muito trabalho.


2

A primeira pergunta é quão grande você realmente espera que seja? E quanto você planeja investir em sua infraestrutura. Como você sente a necessidade de fazer a pergunta aqui, acho que você espera começar pequeno com um orçamento limitado.

O desempenho é irrelevante se o site não estiver disponível. E para disponibilidade, você precisa de escala horizontal. O mínimo que você pode fazer com sensatez é de 2 servidores, ambos rodando apache, php e mysql. Configure um DBMS como escravo do outro. Faça todas as gravações no mestre e todas as leituras no banco de dados local (o que quer que seja) - a menos que, por algum motivo, você precise ler novamente os dados que acabou de ler (use o mestre). Certifique-se de ter as máquinas instaladas para promover automaticamente o escravo e cercar o mestre. Use o DNS round-robin para os endereços do servidor da web para dar mais afinidade ao nó escravo.

Particionar seus dados em diferentes nós do banco de dados neste estágio é uma péssima idéia - no entanto, convém dividi-lo em diferentes bancos de dados no mesmo servidor (o que facilitará o particionamento entre os nós quando você ultrapassar o facebook).

Verifique se você possui as ferramentas de monitoramento e análise de dados para medir o desempenho de seus sites e identificar gargalos. A maioria dos problemas de desempenho pode ser corrigida escrevendo melhor SQL / corrigindo o esquema do banco de dados.

Manter o cache do modelo no banco de dados é uma idéia idiota - o banco de dados deve ser um repositório comum central para dados estruturados. Mantenha o cache do modelo no sistema de arquivos local dos servidores da Web - ele estará disponível mais rapidamente e não diminuirá o acesso ao banco de dados.

Use um cache de código operacional.

Gaste bastante tempo estudando seu site e seus logs para entender por que está indo tão devagar.

Envie o máximo de cache possível para o cliente.

Use mod_gzip para compactar tudo o que puder.

C.


2

Meu primeiro conselho é pensar sobre esse problema e mantê-lo em mente ao criar o site, mas não exagere . Muitas vezes, é difícil prever o sucesso de um novo site, e é melhor gastar seu tempo acordando cedo e otimizando-o mais tarde.

Em geral, o Simple é rápido . Modelos atrasam você. Bancos de dados atrasam você. Bibliotecas complexas tornam você lento. Estratificando modelos, recuperando-os de bancos de dados e analisando-os em uma biblioteca complexa -> os atrasos se multiplicam.

Depois de instalar e executar o site básico, faça testes para mostrar onde gastar seus esforços. É difícil ver onde segmentar. Frequentemente, para acelerar as coisas, você terá que desvendar a complexidade do código, o que torna maior e mais difícil a manutenção, portanto, você só deseja fazê-lo quando necessário.

Na minha experiência, o estabelecimento da conexão com o banco de dados era relativamente caro. Se você conseguir se safar, não conecte-se ao banco de dados para visitantes em geral nas páginas com mais tráfego, como a primeira página do site. Criar várias conexões com o banco de dados é loucura, com muito pouco benefício.


1

@ Gary

Não use o MySQLi - O PDO é a camada de acesso ao banco de dados OO 'moderna'. O recurso mais importante a ser usado são os espaços reservados nas suas consultas. É inteligente o suficiente para usar as preparações do servidor e outras otimizações para você também.

No momento, estou analisando a DOP e parece que você está certo - no entanto, eu sei que o MySQL está desenvolvendo a extensão MySQLd para PHP - acho que para ter sucesso no MySQL ou no MySQLi - o que você acha disso?


@ Ryan , Eric , tj9991

Obrigado pelo conselho sobre as extensões de cache do PHP - você poderia explicar os motivos para usar um sobre o outro? Ouvi ótimas coisas sobre memcached no IRC, mas nunca ouvi falar da APC - quais são suas opiniões sobre eles? Suponho que o uso de vários sistemas de cache seja bastante contra-eficaz.

Definitivamente, estarei escolhendo alguns testadores de perfil - muito obrigado por suas recomendações sobre eles.


1

Não me vejo mudando do MySQL tão cedo - então acho que não preciso dos recursos de abstração do PDO. Obrigado por esses artigos DavidM, eles me ajudaram muito.


1

Veja mod_cache , um cache de saída para o servidor da web Apache, semelhante ao cache de saída no ASP.NET.

Sim, posso ver que ainda é experimental, mas será final algum dia.


1

Não acredito que ninguém já tenha mencionado isso: Modularização e Abstração. Se você acha que seu site terá que crescer para muitas máquinas, você deve projetá-lo para que ele possa! Isso significa coisas estúpidas, como não suponha que o banco de dados esteja no host local. Isso também significa coisas que serão um incômodo no começo, como escrever uma camada de abstração de banco de dados (como DOP, mas muito mais leve porque ela faz apenas o que você precisa).

E isso significa coisas como trabalhar com uma estrutura. Você precisará de camadas no seu código para poder obter desempenho posteriormente, refatorando a camada de abstração de dados, por exemplo, ensinando que alguns objetos estão em um banco de dados diferente - e o código não precisa saber ou se importar .

Por fim, tenha cuidado com operações que consomem muita memória, por exemplo, cópia desnecessária de cadeias. Se você puder manter o uso da memória do PHP baixo, obterá mais desempenho do seu servidor da web e isso é algo que aumentará quando você usar uma solução com balanceamento de carga.


1

Se você estiver trabalhando com grandes quantidades de dados e o cache não estiver cortando, consulte o Sphinx. Tivemos ótimos resultados com o uso do SphinxSearch, não apenas para uma melhor pesquisa de texto, mas também como uma substituição de recuperação de dados para o MySQL ao lidar com tabelas maiores. Se você usa o SphinxSE (plug-in MySQL), ele supera nossos ganhos de desempenho que obtivemos com o cache várias vezes, e a implementação de aplicativos é um sinch.


1

Os pontos destacados sobre o cache são imediatos; é a parte menos complicada e mais importante da construção de um aplicativo eficiente. Gostaria de acrescentar que, embora o memcached seja ótimo, a APC é cerca de cinco vezes mais rápida se o aplicativo estiver em um único servidor.

A publicação "Comparação de desempenho de cache" no blog de desempenho do MySQL tem alguns benchmarks interessantes sobre o assunto - http://www.mysqlperformanceblog.com/2006/08/09/cache-performance-comparison/ .

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.