Redis depuis PHP

Voici un petit récapitulatif des différents moyens d'utiliser une base de données Redis depuis PHP sous Linux

L'ensemble des tests ont été réalisés sous Fedora 25 mais devrait fonctionner avec RHEL, CentOS ou une autre distribution.

Solution testées:

 

Pour chaque solution, j'ai utilisé 3 jeux d'essai (lancé une dizaine de fois pour avoir une valeur moyenne)

  • connexion et incrément d'une valeur, uniquement pour mesurer le coût de la connexion
  • connexion et set / get de 10000 valeurs numériques
  • connexion et set / strlen de ~2700 valeurs importantes (l'ensemble des pages de man 1)

1. Extension redis

Composants nécessaires :

  • Extension redis
  • Paquets RPM: php-pecl-redis

Exemple de code :

<?php
$time = microtime(true);
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
printf("Value = %d\\n", $redis->incr("foo"));
$time = microtime(true)-$time;
printf("Done in %.6f\\n", $time);
Code complet utilisé pour les tests : redis.txt.

 

Résultats :

  • Connexion : 0.000299
  • Set / get : 0.277000
  • Set / strlen : 0.110900

C'est la solution la plus connue est la plus utilisée, j'ai malheureusement de gros doute sur la qualité du code actuel de l'extension.

2. Bibliothèque Predis

Composants nécessaires:

  • Bibliothèque Predis
  • Paquets RPM: php-nrk-Predis

Exemple de code :

<?php
require 'Predis/Autoloader.php';
Predis\\Autoloader::register();
$time = microtime(true);
$redis = new Predis\\Client(['host' => '127.0.0.1', 'port' => 6379]);
printf("Value = %d\\n", $redis->incr("foo"));
$time = microtime(true)-$time;
printf("Done in %.6f\\n", $time);

Code complet utilisé pour les tests predis.txt (en décommentant l'appel au constructeur).

Résultats :

  • Connexion : 0.001890
  • Set / get : 0.375500
  • Set / strlen : 11.445000

Rien d'étonnant à ce qu'une implémentation pure PHP soit nettement plus lente. C'est évidement le chargement de la bibliothèque qui pénalise la connexion, ensuite l'exécution de requêtes simples (get/set) reste très acceptable.

3. Extension phpiredis

Composants nécessaires:

  • Extension phpiredis
  • Paquets RPM: php-phpiredis, hiredis

Exemple de code :

<?php
$time = microtime(true);
$redis = phpiredis_connect('127.0.0.1', 6379);
printf("Value = %d\\n", phpiredis_command($redis, "INCR foo"));
$time = microtime(true)-$time;
printf("Done in %.6f\\n", $time);

Code complet utilisé pour les tests : phpiredis.txt.

Résultats :

  • Connexion : 0.000241
  • Set / get : 0.288100
  • Set / strlen : 0.105000

Les résultats sont comparables à ceux de l'extension redis.

Il est dommage que cette extension, pourtant ancienne, soit toujours en phase de développement (beta). Le code très simple (~1000 lignes contre ~20000 pour redis), et utiliser la bibliothèque hiredis me semble beaucoup plus sain et maintenable à long terme.

4. Bibliothèque Predis avec l'extension phpiredis

Composants nécessaires:

  • Bibliothèque Predis
  • Extension phpiredis
  • Paquets RPM: php-nrk-Predis, php-phpiredis, hiredis

Exemple de code :

<?php
require 'Predis/Autoloader.php';
Predis\\Autoloader::register();
$time = microtime(true);
$redis = new Predis\\Client(['host' => '127.0.0.1', 'port' => 6379], ['connections' => ['tcp' => 'Predis\\\\Connection\\\\PhpiredisSocketConnection']]);
printf("Value = %d\\n", $redis->incr("foo"));
$time = microtime(true)-$time;
printf("Done in %.6f\\n", $time);

Code complet utilisé pour les tests predis.txt.

Résultats :

  • Connexion : 0.001795
  • Set / get : 0.378900
  • Set / strlen : 0.145300

Comme indiqué dans la documentation, la bibliothèque Predis est largement optimisée en utilisant l'extension phpiredis pour les données importantes. Les résultats des tests sont donc très acceptables.

5. Conclusion

À vous de faire votre choix à la lecture des résultats.

J'aurais tendance à privilégier l'extension phpiredis lorsque la vitesse est une priorité absolue, et la bibliothèque Predis pour la beauté du code. Ce couple suivant une rationalisation aussi suivi par d'autres projets (e.g. mongo => mongodb) ou l'extension est réduite au minimum en utilisant une bibliothèque dédiée (ici hiredis) et se charge uniquement de la partie bas niveau, là où les perfornances sont nécessaires, la bibliothèque fournissant la partie haut niveau au développeur.

Je prévois d'aider l'auteur de l'extension phpiredis pour qu'une version soit publié, et si possible sur la forge PECL afin de lui donner la visiblité qu'elle me semble mériter. Alors je soumettrais probablement une revue pour les dépôts officiels de Fedora/EPEL.

 

Vus : 665
Publié par Remi Collet : 73