Load Balancing – Haute Dispo – Clustering. Un triptyque parfois confus…

 
Il m’arrive souvent chez les clients de rencontrer la même confusion autour de ce triptyque, ce qui peut mener à de sérieux problèmes, surtout quand le client se base sur l’idée que « dans le doute on prend toutes les options, c’est forcément mieux ! ». C’est faux !

Une explication de chacune de ces notions s’impose.

Découpage et positionnement des fonctionnalités

 
 
 
 
Architecture applicative standard

Architecture applicative standard


Load Balancing ou répartition de charge
Cette tâche est acquittée par le load balancer ou répartiteur de charge. Il s’agit du point d’entrée de l’architecture applicative (on peut trouver avant firewall, reverseproxy, …) et il permet de répartir les requêtes sur différentes « branches » identiques entre elles, donc la charge, entre les services répliqués. On peut définir l’algorithme de la répartition (roundrobin, stickysession, …), la pondération sur chaque backend (serveur récupérant les requêtes distribuées par le balancer), la politique de vérification de l’état des backends (nombre de requêtes en erreur, intervalle de vérification, …), … De nombreuses options sont disponibles de manière générale et en fonction des balancers en particulier.

Il est à noter que le balancer peut être hard ou soft. Je constate souvent que les clients préfèrent acheter un balancer hard, probablement pensant que c’est un gage de fiabilité et de performances. Effectivement le balancer hard dispose d’une infrastructure matérielle conçue spécialement pour cette tâche et permet donc des performances un peu meilleure. Il dispose également d’un paramétrage plus poussé (donc plus de possibilités, mais plus complexe à prendre en main). Cependant, dans quasiment tous les cas que j’ai rencontré, un balancer soft aurait amplement suffit, autant en termes de performances que d’options… Le balancer est un dispatcher (intelligent tout de même) et ne consomme donc pas (ou peu) de CPU, de mémoire, … Il n’est donc pas gourmand et fait juste la tâche pour laquelle il a été conçu. Le balancer soft que j’utilise en général est HAProxy, et pour l’instant je n’ai pas à m’en plaindre. Facile à configurer, il supporte une montée en charge importante comme un grand (cf. « Conception d’une infrastructure sur AWS : best practices ! ») ! Bien sûr, d’autres balancer soft (et gratuits bien entendu ^^) existent et chacun trouvera son bonheur, n’hésitez pas à installer et comparer.

Il est intéressant de mettre en place du balancing à partir du moment où la population cible d’utilisateurs n’est pas figée ou bien qu’elle ne peut être supportée par un seul serveur.

Il faut en revanche bien penser qu’à partir du moment ou l’architecture aura plusieurs branches identiques de services, le déploiement devra être effectué de manière iso et de préférence (si vous ne le faites pas c’est à vos risques et périls) automatisée sur les X backends.

Il faut également penser à minima en termes distribué et intégrer la notion du partage des sources de données, chaque branche de l’architecture devant avoir accès à une ou des sources de données centralisées et partagées : partage de fichiers, cache réseau, …

Cela a un coût supplémentaire en termes de machines, de mise en place d’un déploiement automatisé et de réflexion distribuée, mais le bénéfice est toujours là et la configuration relativement simple.

Haute Dispo
La haute disponibilité s’appuie tout d’abord sur le load balancing. C’est le second niveau que l’on peut apporter à l’architecture. La haute dispo, pour être efficace, doit être mise en place à tous les niveaux de l’architecture, 2 formules étant disponibles : 

• Soit plusieurs services qui fonctionnent en parallèle et répondent aux différentes requêtes dispatchées, si l’un d’entre eux tombe, les autres sont à même de supporter la charge supplémentaire induite et de répondre convenablement. C’est ce que l’on trouve au niveau des serveurs HTTP ou applicatifs.

• Soit une machine attend en backup, et si elle (ou un système externe) détecte (Heartbeat, …) la perte de la machine principale, elle prend le relai (IP failover, …). C’est ce que l’on trouve au niveau du balancer ou de la base.

Au niveau de la base, le fonctionnement est un peu plus complexe, car contrairement au balancer qui n’héberge pas de données applicatives, la base doit assurer la mise à disposition des données à la « date du crash – n » avec « n » le plus petit possible. Les données sont donc répliquées sur le backup en quasi temps réel. Il est aussi possible d’utiliser la base de backup (ou slave) en lecture afin de diminuer la charge sur la base principale (master). La base est donc un sujet plus complexe.

Concernant les services fonctionnant en parallèle, il est important qu’à chaque niveau, la requête puisse être redirigée sur un autre service équivalent en cas de défaillance. Le balancer n’ayant pas la même visibilité que le serveur HTTP sur la disponibilité du serveur applicatif, le serveur HTTP doit donc faire du dispatching passif. Dans le cas où il n’y a pas de serveur applicatif, parce que le site est en PHP par exemple, la mise en place est d’autant plus simple : pas besoin de dispatching à ce niveau et de questions métaphysiques… Mais ce cas est bien moins amusant ! ^^

Dans le cas d’une architecture avec serveurs applicatifs, il convient de répondre à un certain nombre de questions/remarques que l’on m’a posées plus d’une fois, en particulier sur le dispatching au niveau du serveur HTTP et son utilité :

« Le serveur web est-il capable de détecter une défaillance du serveur applicatif ? »
Oui. Si le serveur http dispose d’un module de dispatching, comme Apache par exemple, il est plus que probable qu’il soit capable de détecter la défaillance de son backend (le serveur applicatif) et de rediriger les requêtes sur les autres (fonction du paramétrage retenu sur le nombre d’essais et le délai avant déclaration du backend HS). J’ai surtout travaillé avec Apache, mais pense que c’est la base de tout fonctionnement de serveur web… Peut-être y a-t-il un exemple pour me faire mentir ? Il est à noter tout de même que Apache peut détecter le statut du serveur applicatif, mais pas de la ou des applications ! Si l’application provoque des erreurs internes sur le serveur applicatif ou ne renvoie pas les réponses escomptées, cela rentre dans le cadre d’un monitoring de l’application (fonctionnel et technique) via une interface et des outils spécifiques.

« Alors pourquoi ne pas mettre un Apache (en l’occurrence) en balancer ? »
Parce que ce n’est pas son rôle premier et il n’a pas toutes les fonctionnalités d’un HAProxy, par exemple, et surtout parce qu’il effectue un certain nombre de traitements liés à sa fonctionnalité de serveur web qui n’ont rien à faire sur un répartiteur de charge dont le fonctionnement doit être minimaliste afin d’encaisser toute la montée en charge en un point.

« Mais en activant le dispatching Apache, il est difficile de suivre les log d’une transaction pour un utilisateur donné au niveau du serveur applicatif »
C’est là qu’intervient le « sticky session ». Si le site se limite à des serveurs web, pour un site PHP par exemple, le « sticky session » doit être positionné au niveau du HAProxy. Dans le cas d’un site utilisant des serveurs applicatifs, le « sticky session » doit être positionné au niveau des serveurs Web. En effet, le « sticky session » doit être positionné un cran avant la brique gérant la session. Le « sticky session » est tout simplement un flag positionné dans un cookie (de session par exemple) et qui permet pour un utilisateur donné de savoir sur quel serveur il a été redirigé lors de ses requêtes précédentes et donc de pouvoir le rediriger à nouveau dessus afin qu’il récupère sa session. Si « son » serveur est HS, il est alors redirigé vers un autre et sa session recréée, à vide (c’est là qu’intervient le clustering, mais on verra ça plus tard ^^).

« Faire de la répartition de charge au niveau du serveur Apache n’annule-t-elle pas celle du balancer ? »
De manière générale : Non. En général, car il faut prendre en compte les différents algorithmes de répartition, mais vu qu’en général c’est du roundrobin… Y’a pas de souci. Je parle au niveau de Apache de dispatching passif. Si on effectue une répartition par requête sans pondération au niveau de Apache, cela n’annule en rien la répartition de charge du balancer (même si il y avait de la pondération au niveau du balancer). Tout simplement la charge est répartie au niveau des Apache, qui eux même dispatchent les requêtes qu’ils reçoivent équitablement au niveau des serveurs applicatifs.

« Et si on veut quand même conserver un lien « un pour un » entre Apache et le serveur applicatif ? »
Et bien optez au niveau du Apache pour du « hot standby ». En fait, tant que le ou les serveurs du pool défini répondent, les requêtes sont redirigé vers lui ou eux, et si plus aucun ne répond, dans notre cas si le serveur ne répond plus, alors on passe sur le serveur de backup (« hot standby ») qui peut être l’un des autres serveurs applicatifs. Dès que le serveur principal ou un des serveurs principaux revient, il récupère de suite le trafic.

La haute disponibilité s’appuie donc sur le load balancing et est déjà un peu plus complexe à mettre en place. Il faut bien penser à redonder chaque élément de l’architecture avec des services en parallèle ou des backup. Si vous voulez vraiment de la haute disponibilité, pensez également à brancher les serveurs sur des alimentations électriques séparées (ne riez pas, c’est du vécu…) et à prendre en compte votre réseau électrique de manière générale. Il y a plusieurs niveaux de haute disponibilité et c’est à chacun de définir son compromis.

De même que pour le balancing, la haute disponibilité ne fera pas de mal à l’architecture. C’est « juste » plus coûteux en termes de réflexion, de configuration et de ressources.

Clustering
Le clustering est le dernier niveau de la haute disponibilité. C’est à ce niveau qu’il faut surtout réfléchir à la notion de compromis ! En effet, le clustering est coûteux à différents niveaux et risqué si mal maîtrisé.

Il faut aussi faire attention au terme cluster qui regroupe des notions variées et est employé de manière générale pour un regroupement de machines, quelques soient leurs inter dépendances. Dans notre cas, nous parlerons de clustering pour la réplication de sessions au niveau des serveurs applicatifs.

Tout d’abord le clustering se met en place afin de pouvoir répliquer les informations de sessions, donc volatiles, afin que n’importe quel serveur puisse reconstruire la session de l’utilisateur. Il est utilisé pour des sites ne pouvant tolérer de rupture de service dans les « occasions » suivantes :

• si une des machines utilisant les sessions crashe, afin de reconstruire la dite session sur une autre machine,

• afin de pouvoir effectuer des maintenances ou des mises à jour de version de l’application sans rupture de service.

J’ai vu pas mal de clients très embêtés par leur clustering parce que leur application était lente, parce que ça consommait des ressources effrayantes, … parce que leurs serveurs applicatifs ne démarraient même plus à cause de la surcharge de trafic généré (ne riez toujours pas, c’est du vécu…) !!!

En effet, le clustering est basé sur la réplication des informations de sessions entre les différents serveurs applicatifs et s’effectue en multicast, c’est-à-dire qu’à chaque modification des informations de la session d’un utilisateur, le serveur applicatif l’annonce sur le réseau à destination des autres serveurs écoutant sur l’adresse de multicast. Le paramétrage des nœuds du cluster, du ttl (time to live) des trames, l’étanchéité des sous-réseau, … doivent être impeccables, sous peine d’avoir de terribles latences. De plus, il faut garder un œil vigilent sur les développements applicatifs afin de limiter de façon drastique les informations qui auront leur place en session.

Il ne faut pas partir en se disant « on réplique les sessions, de toute façon ça ne fera pas de mal… Qui peut le plus, peut le moins…» ! Si c’est mal configuré, et c’est souvent le cas, le résultat est médiocre et au final après moult temps et argent gâchés, la fonctionnalité est retirée. Il faut l’utiliser à bon escient, et si le besoin est réel, la mettre en place rigoureusement après s’être correctement documenté…

De plus, la fonctionnalité peut bien souvent être contournée, par exemple pour un site marchand, j’ai déjà entendu : « si notre client perd son caddie, c’est critique ! ». Le besoin est tout d’abord à relativiser car le cas où un serveur applicatif est HS est (et doit être) un évènement rare (sauf courte période de maintenance la nuit par exemple). De plus, pourquoi ne pas stocker ses informations en base de données ou dans une source de données centralisée (cache réseau, …) afin de pouvoir gérer ce genre de données et y accéder ailleurs si besoin.

Concernant les mises à niveau logicielles, il est préférable, à mon avis, d’accepter une rupture de service de quelques minutes via une méthodologie et un scripting rigoureux et d’avoir un site efficace le reste du temps, qu’un site qui fonctionne en permanence mais avec un temps de réponse moyen, voire pire…

Conclusion
Je n’ai fait que brosser le sujet qui demande réflexion quand on rentre dans les détails. Il y a beaucoup de notions à connaître que l’on acquiert avec l’expérience. Mais les grandes lignes sont là.

Comme dans tout projet, il faut d’abord définir ses besoins et à partir de là, envisager les solutions à mettre en place et en accepter les compromis. Ce n’est pas parce que vous ne mettrez pas de répartition de charge, de haute dispo ou de clustering que votre architecture et au final votre application ne fonctionneront pas ou encore pire… seront « has been » (oui ça c’est terrible, c’est mal les vieux concepts… Pourtant ça marche souvent très bien et c’est même efficace parfois…) ! Vous avez juste un serveur HTTP et un serveur applicatif parce que votre charge est modérée et avez prévu un PRA (Plan de Reprise d’Activité) rigoureux et efficace via scripting ! Bingo ! Vous aurez un downtime de 5-10 minutes en cas de problème, mais à côté de ça votre application répond bien pour un coût d’infra minimaliste.

Il faut juste adapter les possibilités architecturelles à vos besoins et ne pas créer de dépenses inutiles. La compréhension de chaque option à disposition est la clé de vos choix.

Frédéric FAURE

 

3 commentaires pour Load Balancing – Haute Dispo – Clustering. Un triptyque parfois confus…

Répondre

 

 

 

Vous pouvez utiliser ces balises HTML

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>