Des caches Drupal! (et un peu APC aussi)

Share and options

Bonjour à tous, comme convenu dans mon premier article, qui était un étalage de benchmark peu revelant significatifs (je finis toujours par retrouver le mot français, déformation professionnelle vous me direz), voici un article concernant les optimisations basiques obligatoires à effectuer pour des sites Drupal. Ces techniques sont issues de presque 3 ans d'expérience avec le framework, mais surtout du travail conjoint de plusieurs personnes, notamment Régis (notre admin système, PHP warrior qui plus est).

Cet article traitera brièvement des options APC, puis s'étendra sur la mise en place de backend de cache multiples sur Drupal 7, comment faire, lesquels choisir, et comment en mesurer l'impact. Je ne m'attarderais pas sur l'optimization du serveur SQL qui est un métier à part entière. De plus le débat ne m'intéresse pas puisque la communauté Drupal préfère toujours utiliser MySQL alors que PostgreSQL est bien supérieur, à tous les niveaux.

Mise à jour du 11/01/2011 : Merci à gagarine de m'avoir signalé que l'option apc.optimization à été supprimée depuis la version 3.0.13 d'APC.

1. La bonne utilisation d'APC

Je ne vais pas vous dire comment installer APC, c'est votre fardeau. À chacun son système d'exploitation, si c'est Linux, à chacun sa distribution, et pour beaucoup d'admin sys, à chacun sa façon de compiler les outils. Par conséquent faire un millionième tutorial sur le sujet ne serait que perte de temps pour vous.

1.1. Un OPCode cache, mais pourquoi faire?

Et bien tout simple parce que... l'utilisation d'un OPCode cache divise par 2 le temps d'execution de vos scripts PHP, a peu près. Pour tous ceux qui sont sceptiques, benchez vous même.

Pour la petite histoire, PHP est language intêrprété. Oui monsieur. En gros ça veut dire que l'intêrpréteur, la machine virtuelle, le bousin (appellez le comme vous voulez) relit tous les fichiers PHP à chaque execution, les parse, les compile, et ensuite les execute.

Ce que fait l'OPCode cache ? Il relit tous les fichiers PHP, les parse, les compile, mais pas à chaque execution!. En gros, il compile votre code, met en mémoire ce qu'on appelle pour ce langage l'OPCode (ce qui correspond au bytecode, entendre code executable par l'interpreteur sans phase de parsing préliminaire). Une fois cet OPCode compilé, il le garde en RAM ad vitam eternam jusqu'à ce qu'il n'en ait plus de disponible. Chaque hit ne nécessite donc plus cette phase de lecture du fichier, parsing, puis compilation qui prennent quasiment la moitié du temps d'execution.

1.2. Quelles options sympas pourriez vous me proposez, cher monsieur?

Pour commencer, voici un petit florilège des meilleures :

apc.enabled
Si vous ne mettez pas 1 ici, APC ne sera pas activé.
apc.include_once_override
Cette option va simplement remplacer la routine d'origine de l'interprêteur PHP par la sienne, effectuant moins d'appels systèmes couteux. Cette option est stable, et obligatoire sur tout site en production. Mettez- y la valeur 1
apc.canonicalize
Cette option est encore plus importante que la précédente. Elle va, comment son nom l'indique, convertir tous les chemins de fichier que PHP va manipuler en chemins canoniques (aussi appellés absolus). Ceci permet entre autre d'éviter les liens symboliques, la recherche dans de multiples include_path et autre joyeusetés que peut vous réserver votre système d'exploitation. Je vous interdit de ne pas mettre 1 à cette option.
apc.rfc1867
Cette dernière n'est pas une optimization en soit, mais elle permet d'avoir les jolies progressbar lors de l'upload d'un fichier dans les champs de type fichier. Cette implémentation de la RFC 1867 remplace l'extension PEAR PHP uploadprogress.

1.3. Le mode production bourrin©

Et la meilleure de toutes (elle gagne énormément de temps à l'execution) 

apc.stat
Cette option est par défaut à 0. Pour tout site en developement, surtout ne la changez pas! La commande stat d'un système de fichier récupère les informations d'un fichier particulier, dont la date de dernière modification. Sur la pluspart des système d'exploitations dignes de ce nom, cette commande est optimisée et le résultat est maintenu en cache. Cependant son appel reste très couteux. Lorsque vous désactivez cette option, APC n'essayera plus (vraiment, plus jamais) de savoir si un fichier à été modifié avant d'utiliser son OPCode cache. Sur un site en production, cette option est indispensablement à la valeur 0 et je vous interdis de laisser un serveur en production avec la valeur 1. Sur un site en developpement ne la désactivez surtout pas, sinon vous ne verrez plus les changements que vous effectuerez sur vos fichiers.

Il est important de comprendre que de plus en plus de framework PHP (le plus souvent ceux orientés objets, tel le Zend Framework) vont découper leurs APIs en de très nombreux fichiers. Le chargement de chacun d'entre eux est réellement très couteux, puisqu'il s'agit d'une lecture de fichier sur le disque dur. Drupal n'est pas fortement orienté objet, mais ses développeurs mettent un point d'honneur à découper le code sous forme de fichiers le plus petits possibles. Si vous laissez PHP nu sans OPCode cache, ou si ce dernier effectue un appel à la commande stat lors de chaque inclusion de fichier, le système de fichier peut potentiellement devenir lui même un goulot d'étrangement. Je vous rappelle qu'un disque dur est mécanique et non pas magique, même s'ils sont aujourd'hui très rapides, les opérations d'entrée / sortie dessus sont très couteuses.

1.4. Et pour les masochistes, les options expérimentales

apc.optimization
J'avoue que celle-ci me fait avoir des érect... me plaît énormément, en effet, elle permet d'activer certaines options d'optimization du bytecode. Pour information, tous les compilateurs passent par des phases d'optimisation agressives, mais PHP étant un intérprêteur, ces optimisations se revelèraient probablement plus couteuses à faire, car il faudrait les refaire lors de chaque execution. APC fait le pari d'optimiser le code, cependant, cette option est très expérimentale. Mettez 0 si vous êtes frileux ou n'importe quelle valeur numérique supérieure à 0 si vous êtes joueur.

Pour information, j'ai testé avec différentes valeurs, allant de 3 à 9 (ces valeurs ne sont absolument pas documentés dans la documentation officielle). Avec 3, j'ai obtenue une légère augmentation des performances (un seau d'eau dans la mer), mais constante. Avec 9 j'ai eu des résultats très variables. Mais je pense qu'Apache était l'élément perturbateur, pas APC. Je n'ai pas eu d'effets de bord désagréables en testant cette option, mais je vous la déconseille pour un environnement de production, le ratio risque / gain semble être trop faible.

Mise à jour du 11/01/2011 : De plus, cette option à été supprimée d'APC depuis la version 3.0.13, donc elle sera inutile pour la majeure partie des gens. Ceci veut donc dire que vous feriez mieux d'ignorer ce paragraphe :)

2. Je veux du cache! Je veux du cache!

Le roi dit nous voulons!. Et puis, j'ai envie de dormir, je vais essayer de rédiger la partie promise sur la gestion des cache Drupal demain. Je ne promets rien, juste une chose, cette partie sera elle même consistente.

En attendant, allez donc potasser la documentation d'APC quelque part par ici, cette documentation, ainsi que des benchmarks intensifs doivent rester vos seuls guides.

Allez, à bientôt!