Home > PHP > Cache d’opcode: Alternative Php Cache (APC)

Cache d’opcode: Alternative Php Cache (APC)

Pour accélerer les performances d’un site internet, il existe de nombreuses pistes à suivre. Outre les recommandations d’optimisation de Yahoo, qui concernent surtout l’architecture d’une application Web, on peut aussi s’attaquer à des couches plus transparentes (et souvent complètement ignorées par les développeurs), comme l’étape de “compilation” du script en exécutable. Nous allons voir comment APC (Alternative Php Cache) peut nous aider rapidement à accélérer des scripts php.

L’opcode ?

Oui, l’opcode. C’est le code généré par votre serveur Web (qui a dit Apache ?) à partir de vos scripts PHP, après leur interprétation et leur compilation. Ce code est exécutable, et sa génération prend un certain temps. A chaque exécution d’un script, le serveur régénère cet opcode, perdant ainsi un temps précieux: quand votre script n’a pas été modifié, cette étape est totalement inutile. On peut l’éviter en mémorisant l’opcode grâce à un cache d’opcode
Attention, il ne faut pas confondre les caches d’opcode et les caches HTML: un cache HTML servira à envoyer directement la sortie d’un script au client, sans traitement. Le cache d’opcode, lui, laisse place à l’exécution proprement dite du script dans des conditions normales: les données provenant d’une base de données MySQL, par exemple, seront rapatriées comme à l’accoutumée. On ne perd donc aucune réactivité au niveau de l’application, tout en améliorant ses temps de réponse.

APC ? (Alternative Php Cache)

Oui, APC. APC est un projet libre, implémenté comme une extension Zend. Cela permet de le compiler dans PHP ou de l’intégrer plus tard, comme un module classique. Le principal avantage d’APC (et des autres caches d’opcode) est qu’il n’y a aucun besoin en terme de modification des scripts: il suffit d’installer et d’activer le module pour que celui-ci accélère vos scripts PHP. De ce côté là, donc, rien de spécial à ajouter.
APC permet, par un script d’administration, de suivre quels opcodes sont mis en cache, le nombre de hits économisés, ainsi que les données utilisateur. Très pratique, la colonne “miss” vous indique combien de scripts ont été appelés sans profiter de l’accélération d’APC (Cela peut arriver car vous pouvez mettre des filtres en place pour ne stocker que certains répertoires, ou limiter la taille en mémoire occupée par l’ensemble des scripts “compilés”, par exemple…)

Le cache de données utilisateur

Mais là où réside, selon moi, la vraie puissance d’APC, est dans son cache de données utilisateur. En effet, imaginons le cas où nous avons une requête SQL assez lourde, suivie d’un traitement assez conséquent: sur la page d’accueil d’un forum (lien-copinage), on souhaite afficher les derniers connectés et le nombre de messages qu’ils ont posté. En théorie, à chaque affichage de la page, on va réexécuter la requête, et donc assassiner bêtement le serveur SQL.
On pourrait stocker les données dans une Session PHP ? Oui, mais d’une, les sessions ne sont pas faites pour ça, et de deux, on exécuterait quand même la requête SQL et le traitement associé pour chaque nouveau connecté.
La meilleure solution reste alors d’utiliser le cache de données d’APC. On va pour cela se servir de la fonction apc_store, qui prend 3 paramètres :
bool apc_store ( string $key , mixed $var [, int $ttl ] )

  • $key est le nom que l’on souhaite donner à la variable dans le “magasin” (store) d’APC. Je vous conseille de la préfixer du nom du site concerné si vous hébergez plusieurs sites sur le même serveur ; les variables sont accessibles à tous les scripts (attention donc à ce que vous faites dans le cas d’un hébergement partagé… ne stockez de préférence aucune donnée “sensible” à moins de savoir précisément ce que vous faites).
  • $var est la valeur à stocker, qui peut être un nombre, une chaîne, un tableau, ou même un objet complet (Attention, dans ce dernier cas, à bien inclure la déclaration de classe de l’objet avant d’essayer de le récupérer…).
  • $ttl est le “Time To Live” de la variable, c’est à dire le temps en secondes avant qu’APC ne l’efface de son store.

Par exemple, dans le cadre de notre forum, on aurait quelque chose comme :

  1. apc_store(‘forum_derniers_connectes’,$derniersConnectes,60);

Ce qui signifie qu’on stocke, tel quel, le tableau (array) $dernierConnectes, sous le nom forum_derniers_connectes, pour une durée de 60 secondes.

Pour accéder à la variable, on dispose de la fonction apc_fetch, qui prend le $key de la variable en paramètre, et renvoie soit la valeur stockée, soit FALSE en cas d’échec. On peut donc faire :

  1. if (!$derniersConnectes = apc_fetch(‘forum_derniers_connectes’)) {
  2. // forum_derniers_connectes n’est pas présent dans le cache: il faut le calculer
  3. $derniersConnectes = get_derniers_connectes(); // boum, on exécute
  4. apc_store(‘forum_derniers_connectes’,$derniersConnectes,60);
  5. }

C’est tout ! Si APC trouve la variable, il renseigne $derniersConnectes. Dans le cas contraire, on rapatrie les infos et on les stocke pour 60 secondes. La requête-de-la-mort ne sera plus exécutée qu’une fois par minute.

Bénéfices

Le bénéfice est donc double: on économise à la fois sur le temps d’exécution des scripts en ne les compilant qu’au besoin grâce au cache d’opcode (d’environ 50% selon les auteurs, sachant que cela dépendra de la complexité du script… on gagnera beaucoup plus sur des algorithmes récursifs, notamment), mais aussi sur le temps de processing de certaines ressources grâce au cache de données, qui est utilisé ici pour des requêtes SQL mais qui pourrait aussi bien l’être pour la lecture du fichier de configuration de votre application, par exemple (en stockant, au choix, un tableau associatif ou un objet $config), ou de n’importe quelle variable qui n’a pas vraiment besoin d’être mise à jour en temps réel.

Liens utiles

Manuel APC sur php.net (en français)

Ce post vous a été utile ? Re-Twittez le ! ReTwittez ce post

PHP , , , ,

  1. No comments yet.
  1. No trackbacks yet.