CCK et Performance

Á OWS, nous sommes de grands amateurs de la flexibilité qu'amène CCK, mais nous n'étions pas totalement sur de nous lorsqu'il a fallu décider de l'utiliser ou pas dans un projet nécessitant 5 à 10 champs supplémentaires par type de contenu, évidement avec un fort traffic pour pimenter un peu la chose. Pour pouvoir prendre une décision éclairée, plutôt qu'un raisonnement purement théorique, nous avons décidé de mesurer concrètement ce qu'il en était, en vérifiant l'influence du nombre de champs CCK sur le temps de chargement.

La méthodologie

Les tests ont été effectués il y a déja quelques temps, sur un Drupal 6.9 et CCK 2. Le serveur est un petit AMD64 3000+ doté de 2Go de RAM, faisant tourner un Apache 2.2 et PHP 5.2. Pour mesurer le nombre de requêtes traités par seconde par le serveur, l'outil ab a été utilisé. Les performances dans chacune des situations ont été mesurées 5 fois, les deux valeurs extrêmes ont été écartées et la valeur retenue a été la moyenne des trois restantes. La page mesurée est la page d'accueil du site, affichant le teaser d'un unique node. Dans le cas où des champs CCK sont ajoutés, ils ont été paramétrés pour s'afficher dans le teaser du node pour inclure la partie rendue dans le temps de calcul. Les configurations suivantes ont été testées:

  • Module CCK désactivé.
  • Module CCK activé, mais aucun champ crée.
  • Module CCK activé, 1 champ
  • Module CCK activé, 2 champs
  • Module CCK activé, 3 champs
  • Module CCK activé, 5 champs
  • Module CCK activé, 10 champs

Pour ce test, seul des champs simples seront utilisés, c'est à dire que seul les modules Number et Text de CCK ont été activés et seront utilisés dans les types de champ crées. Il semble vraissemblable que les dégradations des performances augmenteraient en utilisant des champs CCK plus complexe. Ces tests ont en parallèle été conduit dans trois cas de test différents: sans aucun module d'opcode caching d'installer sur la machine, avec APC et avec eAccelerator. L'idée n'était pas tant de comparer ces deux derniers que de voir l'impact relatif du nombre de champ CCK par rapport à ces derniers.

Les résultats bruts

Sans cache

Le point à l'abscisse -1 correspond au cas où le module CCK n'est pas activé.

  • La ligne jaune représente le cas où aucun module de cache d'opcode n'est activé.
  • La ligne bleue représente le cas où le module APC a été activé dans le php.ini.
  • La ligne rouge représente le cas où le module eAccelerator a été activé dans le php.ini.

Avec cache

Deuxième situation testée: avec le cache Drupal en mode standard. Le nombre de mesure a été içi diminué, la théorie disant que le nombre de champ CCK ne devrait avoir aucun impact réel sur les performances. Ces données permettent toutefois de confronter la théorie à la réalité d'une part, et de comparer aisément les cas avec/sans cache sur le même serveur.

Le point à l'abscisse -1 correspond au cas où le module CCK n'est pas activé.

  • La ligne jaune représente le cas où aucun module de cache d'opcode n'est activé.
  • La ligne bleue représente le cas où le module APC a été activé dans le php.ini.
  • La ligne rouge représente le cas où le module eAccelerator a été activé dans le php.ini.

Analyses

Après les jolis graphiques (merci Flot et jQuery d'ailleurs !), place à l'analyse de ces résultats. Regardons ce qui se passe lorsque le cache est désactivé, là où l'impact est réellement visible. Globalement sur les trois courbes, on voit bien se distinguer deux phases: tout d'abord, un cout fixe en performance à l'activation du module, lié au fait que PHP doit analyser plus de code avant de pouvoir envoyer sa réponse au client, puis une dégradation linéaire en fonction du nombre de champ. Dans le détail:

Sans opcode
L'activation du module CCK seule fait chuter les performances de 8%. Chaque champ supplémentaire coûte un peu plus d'1% de performances.
APC
L'activation du module CCK seule fait chuter les performances de 24%. Chaque champ supplémentaire coûte un peu plus d'1% de performances.
eAccelerator
L'activation du module CCK seule fait chuter les performances de 11%. Chaque champ supplémentaire coûte un peu plus de 2% de performances.

On note, comme on pouvait s'y attendre, que les cas avec opcode caching s'en sorte beaucoup mieux d'un point de vue performance brute que PHP tout seul. On pourrait par contre penser qu'ils rendent négligeable le coup d'analyse de fichiers supplémentaires, la pratique montre qu'il n'en est rien: le coup induit par l'activation seule du module CCK y a un impact majeur. La situation avec cache confirme globalement la théorie en montrant une relative régularité dans les résultats, ce qui semble cohérent avec le fait que Drupal ne devrait charger l'ensemble du code qu'à la première requête, et fournir la réponse aux requetes suivantes directement depuis son cache. L'interet majeur de graphe réside à mon sens dans la constation suivante: PHP sans aucun opcode, mais en faisant sortir la page du cache Drupal est 3 fois plus performant que le plus performant des opcodes caching avec le module CCK désactivé. Bien entendu, en ayant une situation idéale où le cache Drupal est combiné à de l'opcode caching, les résultats sont encore plus impressionnant.

Conclusions

Qu'avons-nous tiré à OWS comme conclusion de cette étude ? Et bien, en réalité, plusieurs choses:

  1. Le plus gros impact de CCK ne se joue pas tant au niveau du nombre de champ qu'à l'activation du module. En conséquence, s'il est nécessaire d'activer ce dernier pour un besoin du client, autant ensuite l'utiliser partout.
  2. A l'inverse, faire la chasse aux modules activés inutilement est une très bonne idée pour gagner un peu de performances. Moins PHP aura de code à analyser pour satisfaire la requête, plus cette dernière pourra être effectuée rapidement.
  3. Dans le même ordre d'idée, la séparation de fonctions utilisées uniquement dans certains contextes spécifiques, intégrés dans le core depuis Drupal 6 est une très bonne idée: cela limite encore la taille des fichiers à analyser inconditionnellement. (CCK le fait, et il est probable que l'impact de l'activation du module sur /admin est bien moindre que ce qui a été mesuré içi, où les situations mesurées impliquaient le chargement et le rendu d'un node)

Pour finir, oui, l'ensemble des champs additionnels de notre gros projet auquel ceci constituait une étude préalable seront finalement bien des champs CCK, et bien évidement, au final, le nombre de champs dépasse le 10 par type de contenu ;-)