Refactoring Wordpress pour améliorer les performances de la mémoire [fermé]


63

J'ai examiné de près la consommation de mémoire Wordpress. Sur mon site, il semble que pour chaque page consultée, 20 Mo de RAM soient alloués, histoire de préparer un environnement confortable pour l'exécution de tous les plug-ins. Je l'ai tracé ainsi:

Il n'y a pas de point unique à optimiser, pas de méchant qui mange la plus grande partie de la mémoire. La consommation est répartie sur de nombreux modules php.

Comment faire en sorte que Wordpress initialise son environnement en mémoire une seule fois, puis le réutilise plusieurs fois pour chaque résultat? Je ne veux pas que PHP lent consomme 20 Mo à chaque clic d'utilisateur - même sur un serveur avec beaucoup de mémoire, il faut quelques secondes pour que tout ce travail soit effectué. Vous auriez essentiellement besoin de morceaux de mémoire en lecture seule pouvant être réutilisés.

Aussi ... pourquoi 20MB? Quelqu'un peut-il donner un aperçu de cela?

Edit: Voici la sortie WinCacheGrind sur le Wordpress en cours d’exécution sur ma machine de développement (beaucoup plus rapide que l’hébergement partagé). Comme vous pouvez le constater, il faut une seconde de travail pour produire le code HTML de la page principale. Ralentissez en hébergeant un hébergement partagé et vous aurez la recette du problème. J'ai choisi la méthode qui prend le plus de temps. Comment vous y prendriez-vous pour l'optimiser?

Edit: Voici les statistiques de requête de cet outil de profiling functions.php fantastique .

Chargement: 12 requêtes - 532ms - 19.1MB - 43 résultats de cache / 53
Requête: 15 requêtes - 563ms - 19.0Mo - 72 résultats de cache / 86
Afficher: 21 requêtes - 705ms - 19.2Mo - 234 résultats de cache / 257

Edit: Voulez-vous voir quelque chose qui va vous faire paniquer? Insérer ces lignes à la fin de index.php:


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

J'ai essayé de compter combien de fois le corps de la publication actuelle est enregistré dans la mémoire. J'ai compté 20 instances. Ensuite, j'ai réalisé que PHP avait un comptage de références, alors le nombre de copies a été réduit à trois: deux semblent être dans WP_Query, un dans le cache d'objets. J'enquête plus loin.

C'est pourquoi je pense que WordPress a besoin d'un refactoring ciblant les problèmes de mémoire. Vous ne pouvez plus imputer sa consommation de mémoire à la complexité de son travail. Il fait simplement un tas de choses fausses .

Edit: Après une journée passée à essayer de comprendre cela, voici mes conclusions:

1) 88% de la mémoire totale provient d'appels de type require, include ou include_once:

2) Les fichiers php inclus se produisent principalement pendant la première partie du traitement d'une requête (ce qui n'est pas surprenant), c'est également l'endroit où toute la mémoire est consommée:

3) Il est assez intéressant de tracer toutes les fonctions en cours d'exécution lors d'une requête. Il y a plus de 12 000 appels au total. Je les ai secoués pour les rendre plus visibles (l'axe Level est essentiellement la profondeur de l'empilement):

4) Le seul moyen d'avancer auquel je puisse penser est de minimiser le nombre de fichiers .php inclus. Si je divise les fonctions par fichier, vous pouvez voir que de nombreux fichiers sont consultés une ou deux fois au plus. Nous avons besoin d'un moyen de les éviter quand ils ne sont pas nécessaires. Par exemple, mon plug-in de sauvegarde de base de données distante est chargé et enregistré, juste pour ne jamais être utilisé du tout. Voici le tracé ci-dessus divisé par nom de fichier:

J'offre une prime qui vaut toute ma réputation :) pour des modifications qui conduiraient à une réduction de 30% ou plus de la mémoire de mes blogs.

Edit: J'ai installé WP 3.1, voici une comparaison avec l'ancienne version.

Le bleu est WP 3.1, le rouge est 3.0.4. Le nouveau WP est plus rapide, mais consomme également plus de mémoire.

Voici une liste par fichier d'inclusion.

Cela me permet de réaliser à quel point "All In One SEO Pack" consomme de la mémoire - une solution serait d'utiliser une fraction des fonctionnalités du plugin pour obtenir ce que je veux. En outre, mes propres plugins semblent être assez mauvais.

Je voudrais essayer le chargement conditionnel, par exemple, comment.php (j'autorise les commentaires sur mon blog) et plusieurs autres. J'ai supprimé tout le code obsolète. J'ai réduit kses.php pour ne charger que ses tables globales à la demande. J'ai simplifié l10n (je ne fais pas de localisation), rendant ses fonctions renvoyer les chaînes immédiatement, sans recherches. Je suis encore loin des 30% que j'ai arbitrairement établis.

Edit: J'ai téléchargé et activé APC avec les paramètres par défaut (32 Mo de cache opcode). Voici la comparaison:

Vous pouvez voir que le chargement du code s’est considérablement accéléré et que le code prend moins de place en mémoire (probablement parce que nous ne traitons que des opcodes, pas de la source originale). La consommation de mémoire est cependant encore assez élevée.


Pourriez-vous télécharger le fichier cachegrind lui-même quelque part? Notez juste que je ne me souviens pas si quelque chose qui vaut la peine d'être gardé est inclus, si c'est - alors ne le faites pas.
Rarst


1
Hm, je suis d'accord avec votre conclusion - rien ne saute vraiment, demandant à être réparé. J'ai vidé le nouveau profil sur ma pile de tests locale (3.1, MS, Twenty Ten, données de test de l'unité thématique) et obtenu 1,5 s (la différence semble provenir d'un menu personnalisé - la chose est lente). Donc, je suppose que rien ne peut être corrigé = que la recherche en cache est réelle.
Rarst

@Rarst Merci beaucoup pour votre aide. Je pense qu'il y a des choses à corriger, mais cela nécessiterait de changer l'architecture de Wordpress pour adopter une philosophie complètement différente, et c'est trop de travail.
Roman Zenka

Réponses:


25

Ne vaut pas la peine. WordPress ne consomme pas beaucoup de mémoire simplement parce que. Il consomme beaucoup de mémoire car il exécute beaucoup de fonctionnalités sous le capot.

Il est beaucoup plus facile et efficace de mettre en cache les résultats (page générée) avec le plugin cache statique et de les diffuser. De cette façon, la plupart des visiteurs ne toucheront même pas WP.


2
J'utilise déjà une mémoire cache, mais il me reste quelques pages véritablement dynamiques (un panier, par exemple). Et lorsque les étoiles ne sont pas correctement alignées, l’utilisateur peut attendre 20 secondes - c’est-à-dire accordé sur GoDaddy, mais même si ce n’est pas le cas, je pense qu’il faudrait au moins 3 secondes. Je ne peux tout simplement pas fournir le genre d'expérience très vivante que les gens connaissent de Google.
Roman Zenka

8
@ Roman Zenka, si vous avez des besoins de performances spécifiques, vous ferez mieux de rechercher des solutions spécifiques, plutôt que d’espérer que WordPress deviendra comme par magie super rapide et que les ressources seront légères. Les premières choses que je suggère d’examiner sont le cache opcode et la mise en cache statique fragmentée ... Mais avant cela, vous devez analyser le résultat et déterminer non seulement où la mémoire est utilisée, mais également où le temps est dépensé. WordPress est un environnement, pas un goulot d'étranglement en soi. Le goulot d'étranglement est dans ce que vous le faites faire.
Rarst

@Rarst J'ai effectivement comparé l'utilisation du processeur et je ne peux pas pointer du doigt un endroit spécifique à l'origine du problème. Semblable à la mémoire - il semble être répandu partout. Cependant, mon analyse comparative peut ne pas être effectuée de manière optimale - j'utilise le profileur XDebug et Cachegrind - il est par exemple assez difficile de dissocier la latence en raison des appels à la base de données. Je serais reconnaissant pour les pointeurs pour de meilleures techniques de profilage.
Roman Zenka

La capture d'écran @Rarst Profiling a été ajoutée.
Roman Zenka

4
Les serveurs de GoDaddy pourraient également être lents. Ils sont connus pour ne pas avoir le meilleur matériel informatique et « préféreraient payer pour des publicités télévisées que pour mettre à niveau leurs serveurs »
Zack

23

Et c’est la raison pour laquelle je pense que WordPress a sérieusement besoin d’une réécriture. Vous ne pouvez plus imputer sa consommation de mémoire à la complexité de son travail. Il fait simplement les choses mal.

Quelle conclusion naïve. Lisez des choses que vous ne devriez jamais faire, première partie .

Merci pour les parcelles d'utilisation de la mémoire, cependant.

Beaucoup plus tard, Edit : Autommatic a publié une bibliothèque appelée prefork qui semble faire ce que vous demandez: charger le code WordPress dans la RAM une seule fois.


C'est vrai, c'est naïf. J'aurais peut-être dû dire «refactor» au lieu de «réécrire», alors ça sonne beaucoup mieux. Poster mis à jour.
Roman Zenka

2
Ok, bien, si vous avez des suggestions spécifiques (en particulier des correctifs), n'hésitez
scribu le

Je travaille dessus maintenant. J'essaie de tracer une carte d'objets dans la mémoire, afin de voir combien est utilisé par quoi. Y at-il un outil qui prendrait un dump de mémoire et le tracer?
Roman Zenka

5
@scribu - +1 pour le lien vers le message de Joel!
MikeSchinkel

1
Ok, gardez juste à l'esprit que WP_Object_Cache peut être remplacé par une implémentation memcached, etc.
scribu

17

À partir de WordPress 3.2, PHP 5.2 sera la configuration minimale requise. Je pense qu'avec ce qui se passe sous notre ceinture, des fragments du noyau peuvent commencer à être restructurés et à utiliser des classes avec chargement automatique. Cela nous éviterait de charger des morceaux de code, à moins qu'ils ne soient réellement nécessaires. Par exemple, s'il n'y a pas d'intégration ou de galerie dans une page, nous pourrions peut-être éviter de charger une grande partie du code multimédia.

Cependant, même s'ils décidaient de suivre cette voie, je m'attendrais à ce que ce soit une lente évolution (comme la plupart des autres changements imprévus qui se sont produits). Cela nécessiterait de mélanger l'emplacement de beaucoup de fichiers et de codes, ce qui risquerait de faire basculer la compatibilité en arrière pour certains plug-ins.

Une partie du problème (si on peut vraiment l'appeler ainsi) réside dans le fait que sans ce type de chargement conditionnel, le cadre de base ne peut pas savoir à l'avance quelle fonctionnalité il aura besoin ou non pour générer l'affichage du contenu. Donc, beaucoup de fonctions doivent être chargées au cas où elles seraient nécessaires.


@Dougal Campbell J'ai commencé une prime sur cette question, pour voir si nous pouvions pirater au moins cette instance de WordPress assez mal pour obtenir une amélioration de la consommation de mémoire d'au moins 30% maintenant, relativement sans douleur. Cela pourrait inspirer une partie du développement futur.
Roman Zenka

Le chargement conditionnel, tout en réduisant potentiellement la consommation de mémoire, nuit à la vitesse en cas de mise en cache de l'opcode . Nous avons tendance à favoriser la vitesse.
Scribu

Plus de réflexions sur le chargement automatique: stackoverflow.com/questions/4788452/…
scribu

@scribu Lorsque vous parlez de "chargement conditionnel", parlez-vous de chargement automatique ou de chargement de code basé sur une condition? Combien ça fait mal la vitesse?
Roman Zenka

1
Je vous remercie! Comme je l'ai dit, je ne sais pas si le noyau de WP va un jour emprunter cette voie (la refactorisation nécessaire pourrait être trop extrême). Mais j'ai été très impressionné par les efforts que vous avez déployés pour analyser cela et les graphiques que vous avez produits. Continuez votre bon travail!
Dougal Campbell

16

Comment faire en sorte que Wordpress initialise son environnement en mémoire une seule fois, puis le réutilise plusieurs fois pour chaque résultat?

C'est ce qu'on appelle la mise en cache opcode.

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


1
Je vais essayer APC et voir ce qui se passe. Lorsque j'ai initialement posé cette question, je voulais dire plus que la mise en cache des opcodes - je voulais dire réutiliser tout l'environnement créé par WordPress - code + données. Memcached vous aidera à obtenir les données plus rapidement, mais vous continuerez à les cloner dans la mémoire du serveur. Il semble maintenant que la mise en cache des opcodes permettrait de gérer environ 90% de la consommation totale de mémoire.
Roman Zenka

Si vous disposez des ressources pour certaines expériences, vous pouvez également essayer de configurer un environnement FastCGI. Je serais très intéressé par certaines comparaisons entre mod_php et fonctionnant sous FastCGI.
Dougal Campbell

5

vous ne réussirez probablement pas à réduire autant l’utilisation de la RAM. Mais si vous utilisez mod_php, vous voudrez peut-être passer à la mod_fcgidplace.

Bien que mod_php soit légèrement plus lent, il charge php même s'il n'en a pas besoin, par exemple pour servir des images, des fichiers statiques ou même la mise en cache. Si vous avez beaucoup de demandes, c'est beaucoup de bélier.

utiliser fcgid réduira beaucoup cela.

de plus, l'utilisation d'un cache statique (comme le cache w3total) évitera l'appel de php, ce qui est un avantage considérable: moins d'utilisation de RAM, moins de connexions à la base de données.


4

Ha. Je travaille sur une application web maintenant que je ferme intention de surcharger les données et l' utilisation au - delà de ce que mon compte d' hébergement mutualisé peut gérer, alors j'ai décidé - alors qu'il aurait été super facile à construire dans WP - pour essayer de travailler à partir BackPress comme un cadre et construisez seulement ce dont j'avais besoin pour mes cas d'utilisation spécifiques.

Ainsi, j'ai pu réduire mon environnement principal des centaines de fichiers PHP dans WP à une vingtaine environ de mes besoins réels, tout en pouvant exploiter toutes les bases de données, HTTP, gestion des utilisateurs, formatage et cron. fonctions que j'aime dans WordPress.

Le problème est que cela demande beaucoup de travail et que je ne ferais jamais confiance à mon travail pour rien au-delà de mon usage personnel. Si vous souhaitez utiliser l’environnement WP complet, tenez-le tel quel. C'est aussi bon que cela grâce à des centaines de développeurs qui l'ont peaufiné au cours de plusieurs années. Comme tout le monde l’a dit, vous irez beaucoup plus loin en trouvant un meilleur plan d’hébergement et en recherchant des techniques de mise en cache que vous ne le ferez probablement en piratant le noyau.


1
Je conviens que WP a été affiné depuis longtemps. Mais je ne pense pas qu'il a été mis au point pour travailler sur un hébergement de mauvaise qualité, avec un mélange particulier de plugins. Je suis curieux de voir jusqu'où puis-je le pousser. Même si les modifications ne font pas partie du noyau, il est bon d’avoir un moyen documenté de piratage du noyau si vous pensez le devoir.
Roman Zenka

3

Oui, WordPress charge tout en premier, puis fait ce que nous lui demandons de faire. Je peux rappeler quelque part que nous pouvons créer un pool virtuel dans la RAM où nous pouvons mettre des fichiers. J'ai eu l'idée de mettre tout le WordPress en mémoire (<10 Mo) et nous pourrions économiser beaucoup d'E / S, ce qui seul devrait donner un coup d'accélérateur. Mais je n'ai jamais eu la chance de l'essayer et de plus, je ne suis pas vraiment compétent dans la poursuite de ce genre de chose. Mais ça a l'air d'essayer.


Et je suis d'accord avec Rarst pour utiliser un plugin cache statique afin qu'aucun traitement ne soit effectué du tout. Mais cela peut aussi être utilisé avec une bonne dynamique. :)
Ashfame

J'aime cette idée. Je ne sais pas dans quelle mesure ce problème est dû aux latences d'E / S et à PHP, qui mâche lentement les données. Connaissez-vous un moyen de le savoir?
Roman Zenka

Désolé, c'est juste une idée dans ma tête. Peut-être que les performances ne sont pas tellement affectées par les performances, car les données sont généralement lues à partir d'un disque dur sous forme de blocs; par conséquent, de nombreuses autres données requises ont peut-être déjà été extraites. Je ne suis pas trop sûr.
Ashfame

3

quelques suggestions de base:

  1. w3 total cache plugin pour la mise en cache ..
  2. obtenez memcache installé et activé, activez également à partir des paramètres de cache total de w3 (le cache opcode est une bonne option aussi, mais cela ne se passe pas bien avec le plugin de cache total de w3)
  3. minimiser les requêtes pour diriger les liens dans les fichiers de thème.
  4. Désactivez tous les plugins inutilisés et supprimez-les.
  5. optimiser la base de données.

Je gère un site wordpress bien connu avec un trafic énorme tous les jours .. je ne suis pas sur dédié même, faisant très bien pour moi :)

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.