PHP, clusters et sessions

    13:05 5 03 2006

Un des principaux problèmes que l’on peut rencontrer lorsque l’on utilise une architecture LAMP dans le cadre d’un site à fort trafic est l’utilisation des sessions sur un cluster de serveurs. En effet, par défaut, chaque serveur gère ses propres sessions sur son disque, l’utilisateur se verra donc attribuer une session différente à chaque fois qu’il sera redirigé par le répartiteur de charge sur un serveur différent du cluster. Plusieurs solutions plus ou moins efficaces permettent de résoudre ce problème. Sans être un expert de ce genre de problématiques, j’ai pu rencontrer plusieurs cas lors de mes différentes missions qui comportent toutes des avantages et des inconvénients.

La première consiste à lier un utilisateur à un serveur donné du cluster. Pour cela, lors de la première page affichée, le système de répartition de charge envoie un cookie à l’utilisateur afin de garder une trace du serveur vers lequel il a été redirigé. Lors des requêtes suivantes, l’utilisateur sera toujours redirigé vers le même serveur et conservera donc sa session. Cette solution bien que très facile à mettre en oeuvre pose plusieurs problèmes.
Premièrement, elle ne fonctionne bien sûr pas si l’utilisateur a désactivé les cookies. En même temps, les sessions ne devraient pas non plus fonctionner sans cookies à moins d’activer le use_trans_sid mais chacun sait que, par défaut, cela entraîne d’importantes failles de sécurité.
Le deuxième vient de la haute disponibilité. En effet, si le serveur sur lequel l’utilisateur a sa session tombe, il sera redirigé vers un autre serveur par le système de répartition de charge et perdra donc toutes les données de sa session courante ce qui peut être très problématique dans le cadre d’un site de vente en ligne par exemple.

Une autre solution va consister à redéfinir le handler (gestionnaire) de sessions afin de le rediriger vers un espace de stockage mutualisé pour les différents serveurs du cluster. Deux grandes possibilités sont généralement utilisées :
–le partage NFS – cette solution consiste à utiliser un serveur accessible en partage réseau et de stocker les sessions de tous les serveurs dessus. Elle est efficace pour de petits clusters mais, à ce que j’ai pu voir, les montées en charge entraînent rapidement des problèmes de lecture sur disque et donc des ralentissements importants de l’application.
– le stockage des sessions en base de données – le principe est très similaire sauf que les sessions sont stockées en base de données. Pour que cette solution soit efficace, il est primordial de dédier ce serveur de base de données uniquement au stockage des sessions. Une telle solution est généralement moins rapide que les sessions natives à cause du temps nécessaire à établir la connexion avec la base de données.

La dernière solution rencontrée est la solution propriétaire proposée par Zend au travers de sa Zend Paltform. Celle-ci dispose d’un module de cluster de sessions qui vient remplacer les sessions natives de PHP et permet aux différents serveurs du cluster de partager leurs sessions. De ce que j’ai pu voir, cette solution est plutôt efficace et stable, le partage des sessions n’induit pas spécialement de différences de temps de réponse avec les sessions natives. Elle est également très facile à mettre en oeuvre, il suffit d’installer la PlatForm, tout est géré automatiquement. Solution la plus professionnelle, elle a malheureusement aussi ses inconvénients.
D’abord le coût de licence de la PlatForm. Celui-ci n’est pas très élevé en regard des services qu’elle fournit mais il s’agit tout de même d’une somme non négligeable. Cette solution très complète de pilotage d’architecture PHP ne peut donc convenir qu’à des projets commerciaux d’une certaine envergure et ne peut pas être utilisée dans le cadre de projets communautaires ou à faibles revenus.
Ensuite, le système de cluster de session n’offre pas de redondance des données (hic!). Pour le moment, les sessions ne sont toujours stockées que sur leur serveur d’origine et partagées au moment de leur appel, donc si un serveur tombe, les sessions qui sont dessus ne sont plus disponibles. D’après une conversation que j’ai eu récemment avec Zeev, des fonctionnalités de redondance devraient rapidement être introduites dans les prochaines versions de la Platform ce qui permettra de résoudre ce problème. Quoi qu’il en soit, il apparaît que cette solution est pour le moment la plus efficace et je pense qu’on devrait rapidement la retrouver sur de nombreux systèmes.

Pour finir, je dirais simplement qu’il est peut être temps que la communauté se penche serieusement sur cette problématique. Si l’on souhaite que PHP s’impose en environnement professionnel, il faut lui en donner les moyens. A ceux qui me diront « Bah t’as qu’à le faire! », je répondrais simplement « J’aimerais bien, mais je n’en ai ni le temps, ni les compétences » :D


Actions

Informations

3 réponses à “PHP, clusters et sessions”

6 03 2006
Thanh (18:32:52) :

Merci à toi pour ce petit topo :)

15 07 2006
Calimero (17:46:01) :

Pour s’imposer dans le monde professionnel, je doute que les quelques centaines d’euros d’un Zend sont un problème.

Ensuite, il y a des solutions du genre msession/mcache:
http://www.mohawksoft.org/?q=node/8

Pas encore eu le temps de tester, mais ca semble intéressant !

9 10 2006
dudu (21:56:33) :

j’ai pu tester un port win32 de memcached.
Ca pourrait vraiment servir de stockage de session moyennant un session handler specifique.

sinon, c’est vrai que c’est un probleme récurrent.