Tester les performances de PHP (ou pourquoi HHVM c’est bien)

closeCet article a été publié il y a 9 ans 1 mois 20 jours, il est donc possible qu’il ne soit plus à jour. Les informations proposées sont donc peut-être expirées.

Un autre article dans la lignée de ceux m’amenant vers une infrastructure à même d’absorber le trafic toujours plus important du blog. En attendant la prochaine version de Debian qui s’accompagne de PHP 5.6, j’ai commencé à faire des tests à la maison sur les gains potentiels d’un passage à PHP 5.5, et, par curiosité, à HHVM. Test synthétique, test pratique, comparaison… Et un point de plus d’amélioré dans mon infrastructure.

Prérequis, préparation

Avant toute chose, j’ai fait une sauvegarde de ma machine virtuelle. Si quelque chose pète, je peux toujours revenir à l’état précédent comme ça. Vu que les tests se sont étalés sur plusieurs jours, j’ai évité les snapshots. Mais c’est l’idée, même si je ne le rappelle pas toujours : toujours sauvegarder avant de fusiller un truc, toujours.

Ensuite, ma VM sous Debian Wheezy a été « installée » avec le script de nicorlargo, qui compile nginx et installe php-fpm depuis les dépots Dotdeb. Vous avez compris l’idée : je pars du principe que vous utilisez PHP-FPM, qui est utilisable même avec Apache (d’ailleurs j’avais zappé l’utilisation de mpm-worker, corrigé depuis–une autre piste d’optimisation pour ceux qui ne veulent pas d’nginx ?). C’est d’une part plus performant, et surtout ça sera pratique quand on introduira HHVM dans l’équation.

Le test théorique

Pour faire mes mesures, j’ai utilisé un petit script, un peu ancien (2012), mais qui fait le taf à priori. Il s’appelle PHP Benchmark Script, il est gratuit, et on le récupère simplement à cette adresse. C’est une archive contenant le script bench.php qu’il suffit de mettre à la racine de votre serveur web/vhost et de lancer, au bout de quelques secondes il affiche les résultats du test au format texte. C’est un test un peu théorique, mais c’est reproductible, ce qu’on cherche justement.

Le test « monde réel »

Depuis mon ordinateur portable, je contacte la copie du blog à l’aide de l’utilitaire ab. Un nom qui signifie Apache Benchmark, qui fait partie du paquet apache2-utils sous Debian; un paquet apache-tools est dispo dans AUR pour Manjaro (attention, compilation un poil longue, et surtout verbeuse).

Le test est donc le suivant :

Ça fait quoi ? 100 requêtes, une seule à la fois, sur la page d’accueil du blog. Vous pouvez adapter, ou faire le même test avec de plus gros paramètres, pour vérifier la tenue de charge. Je serais donc de toute façon « limité » à l’upload de ma connexion.

Ajout du dépot « kivabien » et installation

En effet, même si vous utilisez déjà les dépôts dotdeb (qui fournissent en plus la dernière version stable d’nginx si vous êtes frileux de la compilation), les paquets relatifs à PHP 5.5 sont séparés, les dépôts standards se cantonnant à la « branche » 5.4 :

Donc, on crée un nouveau fichier dans le dossier /etc/apt/sources.list.d/, qu’on appellera php55-dotdeb.list (attention à l’extension, sinon le fichier sera ignoré–oui je me suis fait avoir), et dans lequel on mettra ceci :

Si vous n’avez pas déjà les dépôts standards d’installés, je conseille d’ajouter les deux lignes les concernant :

Une fois fait, on sauvegarde, et on récupère les clés de signatures histoire de s’éviter quelques messages d’erreur, et surtout valider la provenance des paquets. Sans ces signatures, un « malfrat » pourrait détourner le trafic du dépôt, pour vous diriger vers une copie contenant des paquets infectés.

Bref, récupération des clés :

Tout est prêt, on peut maintenant mettre à jour la liste de paquets, et on installe :

Hein ? Pourquoi ? En fait, il faut savoir que la politique de Debian en matière de mises à jour de paquets est assez stricte : l’instruction update ne s’occupera de mettre à jour que les paquets déjà présents sur la machine, si leur état reste le même. Si une mise à jour demande à supprimer et/ou installer un ou plusieurs autres paquets (dépendances), alors la mise à jour ne sera pas appliquée.

Fort heureusement, il est possible de valider la mise à jour avec l’instruction dist-upgrade :

Et voilà : apc sera retiré (car PHP 5.5 utilise Zend OpCache, intégré), et plusieurs nouveaux paquets sont nécessaires. J’ai validé, et l’installation s’est à priori passée sans encombres.

Alors, ça donne quoi ?

Alors, j’ai lancé dix fois le test théorique, d’abord en PHP 5.4, ensuite dix fois en PHP 5.5, et compilé les résultats dans un petit graphe :

PHP 5.4 contre PHP 5.5

bench.php, résultat en secondes, le plus bas est le meilleur

Le gain n’est pas flagrant, mais tout de même : on constate bien une légère baisse, si on était aux alentours/proche des 5.7 secondes, on est plus près des 5.6 secondes, sur une machine sans charge.

Dans le « monde » réel, pareil, j’ai lancé dix fois le test pour chaque version de PHP, je n’ai gardé que le temps total de test, et compilé de la même façon dans un zoli graphe :

php-abbench-54-55

Apache Benchmark : résultat en secondes, le plus bas est le meilleur

Déception. Je m’attendais à du mieux, mais mieux que ça tout de même. Maintenant, vu le peu de différences dans le test théorique, les résultats pratiques sont finalement assez logiques, sans pouvoir les expliquer.

J’aurais pu penser à une limitation de la machine virtuelle elle-même (Core 2 Duo E6600, 512Mo de RAM), ou de l’upload de ma connexion ADSL, minable (988kbps ATM d’après la page d’info de la Freebox). Jusqu’à ce que je me penche sur un autre projet…

HHVM, ou l’arme nucléaire selon Facebook

HipHop Virtual Machine de son petit nom, est une machine virtuelle d’exécution de PHP créée et rendue open-source par Facebook. De l’extérieur, on l’utilise de la même manière que PHP-FPM, Je n’aurais donc que très peu de modifications à faire pour m’en servir.

Son installation est des plus simples sous Debian, ils proposent un dépôt qui permet de disposer de la dernière version stable (ainsi que des éventuelles mises à jour de sécurité). J’ai suivi la procédure décrite sur le dépôt Github pour l’installation (en root) :

Quelques instants après, il est installé. Avant de le lancer, j’édite le fichier de configuration d’hhvm, /etc/hhvm/server.ini :

Comme le port 9000, renseigné par défaut, est déjà utilisé par FPM, que je ne vais pas supprimer trop vite, j’utilise plutôt le port 8000. Ensuite, je modifie mon vhost pour faire pointer les appels fastcgi vers le bon port (extrait) :

Une fois que c’est fait, je démarre HHVM et je redémarre Nginx :

J’ai ensuite relancé ma batterie de tests (bench.php, dix fois, et ab dix fois aussi). Les résultats sont édifiants, comparés à ceux de PHP 5.5 :

PHP 5.5 contre HHVM

bench.php : PHP 5.5 contre HHVM

Apache Benchmark: PHP 5.5 contre HHVM

Apache Benchmark : PHP 5.5 contre HHVM

Une vraie claque. Alors que je pensais presque que ma VM était bridée de tous les côtés (avec Virtualbox et mon ADSL, tout est possible), HHVM m’a prouvé le contraire. J’ai beau cracher sur le réseau social lui-même et tous les problèmes sociétaux et sociaux qu’il implique, les développeurs ont vraiment fait un boulot remarquable. Pour les amateurs de pourcentages, passer de PHP 5.4 à PHP 5.5 fait gagner presque 17% de performances dans mon cas, mais basculer de PHP 5.4 à HHVM augmente de presque 100% !

Attention, HHVM n’est pas PHP

Enfin presque (titre de paragraphe putassier assumé). HHVM a d’abord été conçu pour « sur-optimiser » PHP, mais d’abord pour les besoins de Facebook. Il ne couvre donc pas l’intégralité du jeu d’instructions du langage, même si depuis l’ouverture de son code, les applications compatibles parfois sans modifications sont plus nombreuses. WordPress en fait partie depuis la version 3.9. Mais si vous pensez l’utiliser chez vous, il faudra faire des tests approfondis pour « valider » votre application dessus. J’ai pu utiliser Leed, mon lecteur de flux, ainsi que ma collection de films (dont je vous parlerais un jour, promis), sans modifications aucune. Et malgré ma connexion anémique, la copie du blog semble bien réactive.

Y’a encore plein de pistes pour gagner du temps

Je n’ai abordé que la mise à jour d’un des composants de ma « pile » d’hébergement. Sur la machine virtuelle de test j’ai déjà nginx, que je n’ai pas encore déployé sur le serveur « de prod ». J’ai aussi la possibilité d’avancer du côté de PHP 5.6, puisqu’après tout c’est la version qui sera incluse dans Jessie, pour couvrir les applications qui pourraient poser problème avec HHVM. Mais je ne compte pas non plus basculer la version de Debian « day one », histoire de laisser à d’autres les joies de la souffrance de tout casser (en particulier avec Systemd). Et PHP 7 se fait salement attendre, la version actuelle, si elle apportera son lot d’améliorations, est dans l’état toujours moins performante qu’HHVM. À moins, avec Nginx aux commandes, d’utiliser les deux : PHP 5.6 avec PHP-FPM pour les vhosts « génériques », et HHVM pour les applications « critiques », comme le blog, et peut-être l’instance Piwik.

Et tout ça sans même aborder le cas de la base de données, qui n’utilise pas encore MariaDB sur le serveur de prod. Et puis aussi, je n’ai aucune solution de cache global, comme Varnish. Encore un point que je dois creuser, avant que je devienne une star et donc qu’il ne soit trop tard ?

12 Commentaires
Le plus ancien
Le plus récent
Commentaires en ligne
Afficher tous les commentaires
Nicolas Simond
01/03/2015 10:13

Hello,

Perso j’ajouterais juste une ‘tite modification à ta configuration de HHVM histoire d’utiliser les sockets Unix :

; hhvm specific

; hhvm.server.port = 8000
hhvm.server.file_socket = /var/run/hhvm/server.sock

Et dans le vHost Nginx :
# fastcgi_pass 127.0.0.1:8000;
fastcgi_pass unix:/var/run/hhvm/server.sock;

Un petit coup de restart :
service hhvm start && service nginx restart

Et maintenant ça fait une installation digne de HHVM qui ne sera pas bridée par le TCP 🙂

Nicolas Simond
01/03/2015 11:50
Répondre à  Seboss666

Je viens de voir ton article sur la bascule mais ma question est la suivante. Tu règle ton php-fpm sur quel mode ? Sur static tout est trop limité, sur dynamic c’est pas mal mais ça bouffe beaucoup de mémoire. Par contre le mode on-demand avec les sockets là ça déchire sur petites et grosses charges 🙂 Il faut par contre le coupler avec Nginx. Quand j’utilisait encore apache ça tournait beaucoup moins bien, je pense qu’Apache supporte moins bien la gestion des sockets unix.

Julien HOMMET
01/03/2015 13:17

C’est super cette chose qu’est HHVM !
Donc pour avoir un blog sous WordPress aux petits oignons, il faudrait ce genre de config :
> Debian 7.8 – nginx – HHVM – PHP 5.6 – MariaDB – Varnish – WP 4.1.1 (nooon sans dec) – Piwik (pour les stats, sauf si on est utilisateur de Google Analytics)
Clairement, je vais piquer l’idée et tester ça prochainement… : Reproduire l’architecture « type » d’un serveur web mutualisé contre le serveur web de roxxor que tu nous fais miroiter 🙂

Merci pour le retour ! =)

Nicolas Simond
01/03/2015 21:43
Répondre à  Julien HOMMET

Salut 🙂

Pour moi Varnish est en trop. Nginx sais très bien faire le serveur de cache avec une intégration memcached 😉
Ah part ça c’est exactement les composants de mon infra et ça tourne niquel avec 20 wordpress dessus, HHVM pour le blog et des PHP-FPM 5.6 séparés pour les autres sites le tout avec sockets unix 🙂

Puis bon, pour contrebalancer un peu HHVM c’est pas à mettre dans toutes les mains. C’est puissant OK mais ça n’a pas 1/10ème des fonctionnalités de PHP-FPM et ça n’a donc pas la même flexibilité.

Julien HOMMET
03/03/2015 18:59
Répondre à  Nicolas Simond

Merci pour les infos complémentaires Nicolas 😉
Il faut réellement que je m’intéresse à ces outils… :-p

trackback

[…] avoir lu l’article de l’ami Seboss666, et plus récemment celui de Freddy de memo-linux, j’ai été tenté de tester HHVM pour […]

trackback

[…] avoir lu l’article de l’ami Seboss666, et plus récemment celui de Freddy de memo-linux, j’ai été tenté de tester HHVM pour […]