Les sites WEB se doivent d'être rapide. Dans le cas contraire, le développeur va chercher à optimiser son application et il peut être tenté par des systèmes de cache. Mais quel système de cache choisir ? Sont-il vraiment efficaces ?
Lieu de stockage
Le principal critère de sélection d'un mécanisme de cache est son type de stockage. En voici 3 :
- Système de fichiers
- Mémoire partagée
- Base de données
Pour chaque type, il existe plusieurs logiciels ou
techniques permettant de réaliser le stockage. Pour le système de fichiers, on trouve différents formats de fichier. Pour la mémoire partagée, on trouve : APC, Xdebug, Memcached. Et pour les bases de données, on trouve : Sqlite, Mysql, etc ...
Implémentation en PHP
Pour chaque méthode de stockage et pour obtenir un mécanisme de cache, il est nécessaire d'encapsuler les primitives PHP. On trouve de nombreuses API réalisant ce travail.
A l'heure actuelle, Le Zend Framework fournit une couche d'abstraction pour la majorité des méthodes de stockage citées ci-avant. C'est donc un bon moyen de tester la pertinence et la rapidité des différents types de stockage.
Il est difficile d'évaluer l'impact des différentes implémentations en PHP d'un moteur de cache. Il n'est donc pas question ici de les comparer.
Code à tester
Pour évaluer les performances des différentes méthodes de stockage, on va utiliser 2 séries.
Série 1 : 1 * 100000
La première série stocke en cache une seule information d'une taille importante. Par exemple avec le Zend_Framework, on aura le code suivant
:
$cache = Zend_Cache::factory('Core', $backend, $frontendOptions, $backendOptions); if (!($data = $cache->load($id))) { $data = ''; for ($i = 0; $i < 100000; $i++) { $data .= '. '; } $cache->save($data); echo '<h1>SAVED</h1>'; } else echo '<h1>CACHED</h1>'; echo '<div>'.$data.'</div>';
Série 2 : 1000 * 100
La deuxième série stocke en cache plusieurs informations de petite taille mais pour un volume total identique à la première série. Par exemple avec le Zend_Framework, on aura le code suivant :
$cache = Zend_Cache::factory('Core', 'APC', $frontendOptions, $backendOptions); $c = false; $datas = ''; for ($j = 0; $j < 1000; $j++) { $id = 'ID'.$j; if (!($data = $cache->load($id))) { $data = ''; for ($i = 0; $i < 100; $i++) { $data .= '. '; } $cache->save($data, $id); $c = true; } $datas .= $data; } if ($c) echo '<h1>SAVED</h1>'; else echo '<h1>CACHED</h1>'; echo '<div>'.$datas.'</div>';
Banc d'essais
Pour évaluer les performances, on utilisera en parallèle : ab, httperf
et siege. Ces 3 logiciels permettent de simuler une charge importante sur un serveur WEB tout en mesurant les temps de réponses.
Chacun de ces logiciels est lancé séquentiellement 4 fois, à chaque fois on calcul le nombre moyen de requêtes par seconde.
La comparaison portera sur :
- Zend_Cache, backend : FILE
- Zend_Cache, backend : APC
- Zend_Cache, backend : SQLITE
- Pxxo 5.4
- Pxxo 5.4.1
Résultats
Les chiffres sont obtenus en faisant la médiane des 4 moyennes du nombre de requête par seconde. Le tout étant arrondi par défaut.
Série 1 : 1 * 10000 (sans APC)
ab | httperf | siege | |
---|---|---|---|
php (sans cache) | 20 | 11 | 22 |
pxxo (5.4.1) | 208 | 111 | 216 |
pxxo (5.4) | 265 | 136 | 127 |
zend_cache (apc) | - | - | - |
zend_cache (file) | 153 | 84 | 156 |
zend_cache (sqlite) | 129 | 69 | 134 |
Série 1 : 1 * 100000 (avec APC)
ab | httperf | siege | |
---|---|---|---|
php (sans cache) | 22 | 11 | 21 |
pxxo (5.4.1) | 464 | 210 | 424 |
pxxo (5.4) | 436 | 202 | 402 |
zend_cache (apc) | 361 | 178 | 344 |
zend_cache (file) | 295 | 144 | 278 |
zend_cache (sqlite) | 136 | 109 | 208 |
Série 2 : 1000 * 100 (sans APC)
ab | httperf | siege | |
---|---|---|---|
php (sans cache) | 21 | 10 | 21 |
pxxo (5.4.1) | 8 | 5 | 9 |
pxxo (5.4) | 6 | 3 | 6 |
zend_cache (apc) | - | - | - |
zend_cache (file) | 3 | 1 | 3 |
zend_cache (sqlite) | 6 | 3 | 6 |
Série 2 : 1000 * 100 (avec APC)
ab | httperf | siege | |
---|---|---|---|
php (sans cache) | 22 | 11 | 21 |
pxxo (5.4.1) | 45 | 22 | 44 |
pxxo (5.4) | 8 | 4 | 8 |
zend_cache (apc) | 29 | 15 | 29 |
zend_cache (file) | 3 | 1 | 3 |
zend_cache (sqlite) | 6 | 3 | 6 |
Conclusion
Comme d'habitude, tout va dépendre de votre contexte. Cependant, on
peut tirer quelques enseignements de ce ban d'essai.
- Tout d'abord, il est efficace d'utiliser un système de mise en cache pour éviter un traitement long. Mais, plus on va utiliser le système de mise en cache, moins il devient intéressant de l'utiliser.
- Ensuite, ce test confirme que c'est toujours mieux d'utiliser APC ou du moins de l'activer. Cependant, APC n'est pas toujours disponible et il convient de trouver une solution de rechange.
- Si le besoin de mise en cache se limite à une seule information, vous pouvez utiliser Zend_Cache avec un stockage sous forme de fichiers (FILE). L'utilisation du backend APC vous apporte un peu plus mais ce n'est même pas obligatoire.
- Plus vous souhaitez utiliser le stockage en cache, moins vous devez
utiliser le stockage par fichier et plus l'utilisation d'APC devient
obligatoire. Sans APC, SQLITE est une bonne solution de repli.
Le cas Pxxo
Pxxo utilise intensément la mise en cache. Depuis l'origine, le but était de pouvoir limiter le nombre de traitement d'un appel sur
l'autre et le tout de manière presque transparente pour le développeur.
Pxxo, jusqu'à la version 5.4, a toujours utilisé des mécanismes de cache tierces (Cache_Lite de PEAR au début puis Zend_Cache ensuite).
Maintenant, Pxxo utilise son propre mécanisme. Le but était d'améliorer les performances en mode non APC. Cette petite étude permet de confirmer que le but est atteint.
Aucun commentaire:
Enregistrer un commentaire