Tous les HowTo

« Back

sessions-php-en-cluster

Cet article aborde la problématique de gestion d’identifiant de session PHP dans un cluster de serveurs web.  Il décrit le mécanisme de génération d’ID de session PHP, ainsi que les différents moyens permettant de partage de sessions entre plusieurs serveurs.

Unicité des ID de session et possibilité de « collision » d’ID

Le code de génération de session se trouve dans le fichier « sessions.c » de PHP.
Les ID de session sont crées par la fonction : php_session_create_id dont voici la partie principale du code.

 Fichier ext/sessions/sessions.c

gettimeofday(&tv, NULL);
PHP_MD5Init(&context);
sprintf(buf, "%ld%ld%0.8f", tv.tv_sec, tv.tv_usec, php_combined_lcg(TSRMLS_C) * 10);
PHP_MD5Update(&context, buf, strlen(buf));

 Fichier ext/standard/lcg.c

/*
* combinedLCG() returns a pseudo random number in the range of (0, 1).
* The function combines two CGs with periods of
* 2^31 - 85 and 2^31 - 249. The period of this function
* is equal to the product of both primes.
*/
PHPAPI double php_combined_lcg(TSRMLS_D)

 On voit  qu’un ID de session est un hash MD5 calculé à partir des paramètres suivants :

le temps courant en secondes et microsecondes

le résultat d’une fonction pseudo aléatoire php_combined_lcg

Deux requêtes arrivant simultanément (à la microseconde près) sur deux serveurs distincts doivent normalement se voir affecter des ID de session différents grâce à l’utilisation de la fonction pseudo aléatoire php_combined_lcg qui génère deux nombres aléatoires différents.

Conclusion

Il ne doit donc pas y avoir de collision entre les ID de sessions générées par deux serveurs en parallèle.

Pour rendre les ID de session encore plus aléatoires, il est possible d’utiliser une source d’entropie externe de type /dev/urandom

Pour cela, modifier le fichier php.ini avec les paramètres suivants :

session.entropy_length = 16
session.entropy_file = /dev/urandom

Partage des ID de session entre serveurs

Les serveurs Web exécutant PHP étant en équilibrage de charge par « round robin DNS », il est nécessaire de partager les sessions PHP entre les différents serveurs.

Pour plus d’infos sur les différentes solutions, voir : http://www.zend.com/whitepapers/platform/Zend_Platform_Session_Clustering.pdf

Stockage sur un filesystem partagé par NFS

C’est la technique souvent utilisée.  Les sessions sont partagées sous forme de fichiers stockés dans un répertoire commun (point de montage NFS).

Cette technique présente plusieurs inconvénients :

-       Selon les versions de NFS utilisées, le mécanisme de verrouillage de fichier (file locking) semble se révéler dans certains cas inefficace, pouvant entraîner des incohérences ou corruptions  de données.

-       Le Stockage et l’accès à de très nombreux fichiers « a plat » dans un même répertoire UNIX peut selon le type de filesystem utilisé se révéler très peut performant.

Recommandations :

Utiliser un filesystem de type ReiserFS pour stocker les sessions (ou tout autre type de filesystem permettant de stocker efficacement de très nombreux petits fichiers dans un même répertoire)

Si l’on constate des anomalies de fonctionnement, c’est qu’il y a peut être des problèmes d’accès concurrents aux fichiers de sessions avec NFS.  Il est alors conseiller d’utiliser la méthode suivante : stockage des sessions en SGBD.

Stockage en base de données

Pour éviter les problèmes éventuels liés au stockage via NFS, une solution  alternative consiste à stocker les sessions en base de données.

On peut pour cela utiliser une base de données MySQL dédiée.

Recommandations :

Dans ce cas, il ne faut surtout pas utiliser le moteur de stockage MyISAM (verrouillage des enregistrements au niveau table), mais utiliser le moteur InnoDB (verrouillage au niveau record).

Utilisation d’un gestionnaire externe de session

Si les performances des deux premières solutions ne s’avèrent pas satisfaisantes, une troisième solution consiste à utiliser un démon Unix spécialisé pour stocker les sessions.

Plusieurs solutions de ce type sont disponibles :

 

Solutions OpenSource

Sharedance
http://sharedance.pureftpd.org/project/sharedance
« Sharedance is a high-performance server that centralize ephemeral key/data pairs on remote hosts, without the overhead and the complexity of an SQL database.
It was mainly designed to share caches and sessions between a pool of web servers. Access to a sharedance server is trivial through a simple PHP API and it is compatible with the expectations of PHP 4 and PHP 5 session handlers. »

Mcache
http://www.mohawksoft.org/
« 
The mcache server is a system that is designed to maintain this ephemeral session information for multiple web servers and applications.»

MemCached
http://www.danga.com/memcached/
« memcached is a high-performance, distributed memory object caching system, generic in nature, but intended for use in speeding up dynamic web applications by alleviating database load. »

 

Solution commerciale

Zend Platform
http://www.zend.com/products/zend_platform