Refatorando o Wordpress para melhorar o desempenho da memória [fechado]

63

Eu dei uma olhada no consumo de memória do Wordpress. No meu site, parece que, para cada página atingida, 20 MB de RAM são alocados, apenas para preparar um ambiente confortável para a execução de todos os plugins.

Não há um único local para otimizar, nenhum bandido que consome a maior parte da memória. O consumo está espalhado por muitos módulos php.

Como podemos fazer com que o Wordpress inicialize seu ambiente na memória apenas uma vez e depois reutilize-o várias vezes para cada ocorrência? Eu não quero que o PHP lento coma 20 MB a cada clique do usuário - mesmo em um servidor com muita memória, leva segundos para que todo o trabalho seja feito. Basicamente, você precisaria de blocos de memória somente leitura que possam ser reutilizados.

Além disso ... por que 20MB? Alguém pode fornecer informações sobre isso?

Edit: Aqui está a saída WinCacheGrind no Wordpress em execução na minha máquina de desenvolvimento (muito mais rápido que a hospedagem compartilhada). Como você pode ver, são necessários mais de um segundo para produzir o HTML da página principal. Retarde isso com hospedagem compartilhada e você terá uma receita para problemas. Eu escolhi o método que leva a maior parte do tempo. Como você otimizaria isso?

Edit: Aqui estão as estatísticas da consulta desta fantástica ferramenta de criação de funções functions.php .

Carga: 12 consultas - 532ms - 19,1MB - 43 ocorrências em cache / 53
Consulta: 15 consultas - 563ms - 19,0MB - 72 ocorrências em cache / 86
Exibição: 21 consultas - 705ms - 19,2MB - 234 ocorrências de cache / 257

Edit: Você quer ver algo garantido para te assustar? Insira estas linhas no final do index.php:


echo "<pre>\n";
print_r(get_defined_vars());
echo "</pre>\n";

Tentei contar quantas vezes o corpo do post atual está armazenado na memória. Eu contei 20 instâncias. Então eu percebi que o PHP tem contagem de referência, então a quantidade de cópias reduzida para apenas três: duas parecem estar no WP_Query, uma no cache do objeto. Estou investigando mais.

É por isso que acho que o WordPress precisa de refatoração visando os problemas de memória. Você não pode mais culpar o consumo de memória pela simples complexidade do que faz. Simplesmente faz um monte de coisas erradas .

Edit: Depois de um dia tentando descobrir isso, aqui estão as minhas conclusões:

1) 88% de toda a memória vem de exigir ou incluir ou incluir um tipo de chamada:

2) O arquivo php inclui acontece principalmente durante a primeira parte do atendimento de uma solicitação (sem surpresa), que também é onde toda a memória é consumida:

3) É bastante interessante plotar todas as funções que estão sendo executadas durante a solicitação. Existem mais de 12000 chamadas no total. Eu os instalei para torná-lo mais visível (o eixo Level é basicamente a profundidade da pilha):

4) O único caminho a seguir em que consigo pensar é em minimizar a quantidade de arquivos .php incluídos. Se eu dividir as funções por arquivo de onde elas vieram, você poderá ver que muitos arquivos são atingidos uma ou duas vezes, no máximo. Precisamos de uma maneira de pular aqueles quando não são necessários. Por exemplo, meu plug-in de backup de banco de dados remoto é carregado e registrado, apenas para nunca ser usado. Aqui está o gráfico acima dividido pelo nome do arquivo:

Estou oferecendo uma recompensa que vale toda a minha reputação :) por refatorações que levariam a reduzir a pegada de memória dos meus blogs em 30% ou mais.

Edit: Eu instalei o WP 3.1, aqui está a comparação com a versão antiga.

Azul é WP 3.1, vermelho é 3.0.4. O novo WP é mais rápido, mas também consome mais memória.

Aqui está uma lista por arquivo de inclusão.

Isso me permite perceber quanta memória é consumida pelo "All In One SEO pack" - uma avenida seria usar apenas uma fração da funcionalidade do plug-in para obter o que eu quero. Além disso, meus próprios plugins parecem muito ruins.

Eu gostaria de tentar o carregamento condicional em, por exemplo, comment.php (não aceito comentários no meu blog) e vários outros. Eu apaguei todo o código obsoleto. Eu reduzi o kses.php para carregar apenas suas tabelas globais sob demanda. Simplifiquei l10n (não localizo), fazendo com que suas funções retornem as strings imediatamente, sem pesquisas. Ainda estou longe da marca de 30% que estabeleci arbitrariamente.

Editar: baixei e habilitei o APC com configurações padrão (32 MB de cache de código de operação). Aqui está a comparação:

Você pode ver que o carregamento do código acelerou enormemente, e o código também ocupa menos espaço na memória (provavelmente porque lidamos apenas com códigos de operação, não com a fonte original). O consumo de memória ainda é bastante alto.

Roman Zenka
fonte
Você poderia fazer o upload do arquivo cachegrind em algum lugar? Apenas observe que não me lembro se algo que vale a pena manter em sigilo está incluído, se for - então não.
Rarst
@Rarst Deve ficar bem. foxloft.com/files/mbala/cachegrind.out
Roman Zenka
11
hm, eu concordo com a sua conclusão - nada realmente salta, pedindo para ser consertado. Eu joguei um perfil novo na minha pilha de testes local (3.1, MS, Twenty Ten, dados de testes de unidades temáticas) e obtive 1,5s (a maior parte da diferença parece ser por causa do menu personalizado - a coisa é slooow). Portanto, acho que não há nada para corrigir = pesquisa sobre cache.
Rarst
@Rarst Muito obrigado pela sua ajuda. Eu acho que há coisas para corrigir, mas seria necessário mudar a arquitetura do Wordpress para uma filosofia completamente diferente, e isso é muito trabalho.
Roman Zenka

Respostas:

25

Não vale a pena. O WordPress não consome muita memória apenas porque. Consome muita memória porque executa muitas funcionalidades sob o capô.

É muito mais fácil e eficiente armazenar em cache os resultados (página gerada) com o plug-in de cache estático e atendê-lo. Dessa forma, a maioria dos visitantes nem sequer acessa o próprio WP.

Rarst
fonte
2
Eu já estou usando um cache, mas ainda tenho algumas páginas que são genuinamente dinâmicas por natureza (por exemplo, um carrinho de compras). E quando as estrelas não são alinhadas corretamente, o usuário pode esperar 20 segundos - isto é, concedido no GoDaddy, mas mesmo se não for, acho que levaria pelo menos 3 segundos. Simplesmente não posso fornecer o tipo de experiência realmente ágil que as pessoas estão acostumadas no Google.
Roman Zenka
8
@Roman Zenka, se você tiver necessidades específicas de desempenho, é melhor procurar soluções específicas, em vez de esperar que o próprio WordPress se torne magicamente super rápido e leve em recursos. As primeiras coisas que sugiro examinar são o cache do código de operação e o cache estático de fragmentos ... Mas antes disso, você precisa fazer um benchmark e determinar não apenas para onde está indo a memória, mas também para onde o tempo é gasto. WordPress é ambiente, não um gargalo por si só. Gargalo está no que você faz.
Rarst
@Rarst Na verdade, fiz o benchmark do uso da CPU e não consigo apontar o dedo para nenhum lugar específico que cause o problema. Semelhante à memória - parece estar espalhada por todo o lugar. No entanto, meus testes comparativos podem não ser feitos da melhor maneira possível - eu uso o XDebug Profiler e o Cachegrind - por exemplo, é bastante difícil separar a latência devido às chamadas do banco de dados. Eu ficaria grato por dicas de melhores técnicas de criação de perfil.
Roman Zenka
A captura de tela do @Rarst Profiling foi adicionada.
Roman Zenka
4
Também pode ser lento os servidores do GoDaddy. Eles são conhecidos por não ter o maior hardware e que " em vez pagar por anúncios de televisão do que atualizar seus servidores "
Zack
23

E é por isso que acho que o WordPress precisa ser reescrito. Você não pode mais culpar o consumo de memória pela simples complexidade do que faz. Simplesmente faz coisas erradas.

Que conclusão ingênua. Leia coisas que você nunca deve fazer, Parte I .

Obrigado pelos gráficos de uso de memória, no entanto.

Muito mais tarde, editar: A Autommatic lançou uma biblioteca chamada prefork que parece fazer o que você está pedindo: carregar o código do WordPress na RAM apenas uma vez.

scribu
fonte
É verdade que é ingênuo. Talvez eu devesse ter dito "refatorar" em vez de "reescrever", então parece muito melhor. Postagem atualizada.
Roman Zenka
2
Ok, bem, se você tiver sugestões específicas (especialmente patches), você está livre para publicá-las em trac: core.trac.wordpress.org
scribu
Estou trabalhando nisso agora. Estou tentando plotar um mapa de objetos na memória, para poder ver quanto é usado pelo quê. Existe uma ferramenta que pegaria um despejo de memória e o plotasse?
Roman Zenka
5
@scribu - +1 no link para a publicação de Joel!
MikeSchinkel
11
Ok, lembre-se de que o WP_Object_Cache pode ser substituído por uma implementação de memcached, etc. #
scribu
17

A partir do WordPress 3.2, o PHP 5.2 será o requisito mínimo. Penso que, com isso, nossos bits podem começar a ser reestruturados e usar classes com carregamento automático. Isso evitaria o carregamento de alguns trechos de código, a menos que fossem realmente necessários. Por exemplo, se não houver incorporações ou galerias em uma visualização de página, poderemos evitar o carregamento de muito código de mídia.

No entanto, mesmo que eles decidam seguir esse caminho, eu esperaria que fosse uma evolução lenta (como muitas das outras mudanças ocultas que ocorreram). Isso exigiria a troca de localizações de muitos arquivos e códigos, o que poderia quebrar o compatibilidade de alguns plugins.

Parte do problema (se é que realmente pode ser chamado assim) é que, sem esse tipo de carregamento condicional, a estrutura principal não pode saber antecipadamente qual funcionalidade precisará ou não para gerar a exibição do conteúdo. Portanto, muitas funções precisam ser carregadas, caso sejam necessárias.

Dougal Campbell
fonte
@Dougal Campbell Comecei uma recompensa nessa questão, para ver se podemos hackear pelo menos essa instância do WordPress, ruim o suficiente para obter pelo menos 30% de melhoria no consumo de memória agora, de forma relativamente indolor. Isso poderia inspirar parte do desenvolvimento futuro.
Roman Zenka
O carregamento condicional, enquanto reduz potencialmente o consumo de memória, aumenta a velocidade quando o cache do código de operação está envolvido. Nós tendemos a favorecer a velocidade.
scribu 27/02
Mais pensamentos sobre o carregamento automático: stackoverflow.com/questions/4788452/…
scribu
@scribu Quando você diz "carregamento condicional", está falando sobre carregamento automático ou realmente carregando código com base em uma condição? Quanto dói a velocidade?
Roman Zenka
11
Obrigado! Como eu disse, não sei se o núcleo do WP seguirá esse caminho (a refatoração necessária pode ser muito extrema). Mas fiquei muito impressionado com o esforço que você fez para analisar isso e com os gráficos que você produziu. Mantenha o bom trabalho!
precisa
16

Como podemos fazer com que o Wordpress inicialize seu ambiente na memória apenas uma vez e depois reutilize-o várias vezes para cada ocorrência?

É chamado de cache de código de operação.

http://en.wikipedia.org/wiki/PHP_accelerator

Otto
fonte
11
Vou tentar a APC e ver o que acontece. Quando eu originalmente fiz essa pergunta, eu quis dizer mais do que apenas o cache de opcode - eu quis dizer reutilizar todo o ambiente que o WordPress constrói - código + dados. O Memcached ajudará a obter os dados mais rapidamente, mas você ainda estará clonando os dados na memória do servidor. Agora parece que o cache do opcode poderia potencialmente cuidar de ~ 90% de todo o consumo de memória.
Roman Zenka
Se você tiver os recursos para algumas experiências, tente também configurar um ambiente FastCGI. Eu ficaria muito interessado em algumas comparações entre mod_php e executando sob FastCGI.
Dougal Campbell 28/02
5

você provavelmente não conseguirá reduzir tanto o uso de memória RAM. Mas se você estiver usando mod_php, poderá mod_fcgidoptar por mudar .

enquanto mod_php é um pouco mais lento, carrega php mesmo quando não é necessário, como servir imagens, arquivos estáticos ou até mesmo cache. Se você tem muitos pedidos, isso é muito ram.

Usar o fcgid reduzirá muito isso.

Além disso, o uso de um cache estático (como o cache w3total) evitará chamar php , o que é uma grande vantagem: menos uso de memória ram, menos conexões de banco de dados.

boyska
fonte
4

Ha. Estou trabalhando em um aplicativo Web agora que pretendo sobrecarregar os dados e o uso além do que minha conta de hospedagem compartilhada pode suportar, então eu decidi - embora fosse super fácil de criar no WP - tentar trabalhar a partir do BackPress como uma estrutura e crie apenas o necessário para meus casos de uso específicos.

Portanto, consegui reduzir meu ambiente principal das centenas de arquivos PHP no WP para apenas os vinte necessários, enquanto ainda conseguia aproveitar todo o db, HTTP, gerenciamento de usuários, formatação e cron funções que eu amo no WordPress.

O problema é que é muito trabalhoso, e eu nunca confiaria no meu hackjob por algo além do meu uso pessoal. Se você deseja usar o ambiente WP completo, aceite-o como está. É tão bom quanto é por causa de centenas de desenvolvedores ajustando-o ao longo de vários anos. Como todo mundo aqui disse, você vai muito mais longe, encontrando um melhor plano de hospedagem e pesquisando técnicas de cache do que provavelmente invadindo o núcleo.

maçãs douradas
fonte
11
Concordo que o WP foi ajustado por um longo tempo. Mas não acho que tenha sido aperfeiçoado para trabalhar com hospedagem ruim, com uma mistura específica de plugins. Estou curioso para ver até onde posso empurrá-lo. Mesmo que as alterações não entrem no núcleo, é bom ter uma maneira documentada de invadir o núcleo, se você achar que deve.
Roman Zenka
3

Sim, o WordPress carrega tudo primeiro e depois faz o que pedimos. Lembro-me de algum lugar em que podemos criar um pool virtual na RAM, onde podemos colocar arquivos. Tive a ideia de colocar todo o WordPress na memória (<10 MB) e, em seguida, podemos economizar muita E / S, o que por si só deve aumentar a velocidade. Mas nunca tive a chance de experimentá-lo e, além disso, não sou realmente tão proficiente em buscar algo assim. Mas parece que vale a pena tentar.

Ashfame
fonte
E eu concordo com a Rarst em usar um plug-in de cache estático para que nenhum processamento seja feito. Mas isso também pode ser usado com boa dinâmica. :)
Ashfame 25/02
Eu gosto daquela ideia. Não tenho certeza de quanto desse problema é devido às latências de E / S e quanto é devido ao PHP mastigar lentamente os dados. Você sabe como saber?
Roman Zenka
Desculpe, é apenas uma ideia na minha cabeça. Pode não afetar tanto o desempenho, como geralmente os dados são lidos do disco rígido como blocos, portanto, muitos outros dados necessários podem já ter sido buscados. Eu não tenho tanta certeza.
Ashfame 6/03/11
3

algumas sugestões básicas:

  1. plugin de cache total w3 para armazenamento em cache ..
  2. instale e habilite o memcache, também ative as configurações de cache total do w3 (o cache do opcode também é uma boa opção, mas não vai bem com o plugin de cache total do w3)
  3. minimizar consultas para direcionar links em arquivos de temas.
  4. Desative todos os plugins extras não utilizados e remova-os.
  5. otimizar banco de dados.

Eu estou executando um site wordpress bem conhecido com enorme tráfego diariamente .. não estou dedicado mesmo, fazendo muito bem para mim :)

Ayaz Malik
fonte