Les technologies Clusters

Par Philippe PRADOS - 2010
www.prados.fr
Plusieurs architectures et technologies permettent d'utiliser des ensembles de serveurs, comme un seul. Ces dernières utilisent un vocabulaire spécifique :
- Haute-disponibilité: C'est un concept permettant de garantir un taux de disponibilité spécifié. Les mécanismes mis en place doivent être capables de détecter une défaillance et d'y remédier dans les délais impartis.
- Tolérance aux pannes : C'est la capacité à détecter une panne et à réagir sans impact pour le système d'information.
- Répartition de la charge : C'est la capacité de répartir les traitements sur plusieurs composants (logiciels et hardwares) afin d'améliorer les performances.
- Ferme : Une ferme (Farm) de serveur est un ensemble de machines, pouvant être identiques ou différentes, mises à disposition de plusieurs applications. Les affectations peuvent être statiques ou dynamiques afin de réguler la charge. Parfois, des plans de charges permettent une optimisation des ressources dans le temps.
- Grappe : Une grappe (Cluster) est un ensemble de machines vues comme une seule, par un composant applicatif donné. Ainsi, une application peut mettre en œuvre des composants applicatifs déployés sur différentes grappes.
- Cloud : C'est un ensemble de machines physiques et virtuelles, dont la mise à disposition pour les applications est presque instantanée et s'effectue via une interface Web.
Objectifs des architectures « Ferme » et « Grappe »
Les applications Internet ou Intranet doivent résister à une défaillance d'un de ses composants tout en garantissant une tenue à la charge. Une approche consiste à dupliquer les ressources. Chaque composant est doublé ou triplé et des mécanismes logiciels ou hardwares sont mis en place pour détecter les défaillances. Si un problème est identifié, le paramétrage des autres composants est adapté pour contourner la difficulté.
Il faut noter que ces architectures n'ont pas toujours vocation à améliorer les performances. Souvent, elles les dégradent, même si les accès en lecture sont parfois plus rapides. Il est donc essentiel de choisir l'architecture qui permet de répondre aux contraintes de l'application.
Critères de choix de l'architecture et des technologies
Pour mettre en place une architecture à base de fermes ou de grappes, il est indispensable d'avoir une vision claire des contraintes et des exigences des composants applicatifs. Chaque technique apporte des solutions, mais également des limites. Les choix seront pertinents si, et seulement si, ils permettent de respecter toutes les exigences des composants applicatifs.
Contraintes de Haute disponibilité
Le premier sujet à traiter consiste à identifier le délai toléré d'indisponibilité du service. Cela impose un délai pour la reprise d'activité. Plus le délai est court, plus le coût associé est important.
Pour mesurer la disponibilité d'un système, on utilise souvent un pourcentage composé de « 9 » :
- 99% : le service est indisponible moins de 3,65 jours par an ;
- 99,9%, moins de 8,75 heures par an ;
- 99,99%, moins de 52 minutes par an ;
- 99,999%, moins de 5,2 minutes par an (appelé « 5 neufs », c'est le niveau requis dans le monde des Télécommunications) ;
- 99,9999%, moins de 54,8 secondes par an ;
- 99,99999%, moins de 3,1 secondes par an.
Note : Il existe un lien direct entre le taux de disponibilité et le coût du système à mettre en place. L'ajout d'un « 9 » implique souvent un surcoût non négligeable.
Des contraintes complémentaires permettent d'affiner le choix des techniques à mettre en place. Elles sont du type :
- temps d'arrêt du service minimum, mais non transparent pour l'utilisateur (re-connexion nécessaire) ;
- le système doit pouvoir reprendre sur un site éloigné pour faire face à un problème d'indisponibilité globale d'un site ;
- le système doit répondre avec un temps maximum défini ;
- ...
Une difficulté majeure consiste à définir les procédures de mise à jour ou d'application de correctifs lorsque le niveau de disponibilité est élevé.
Il est également nécessaire de savoir quel budget le projet est prêt à investir pour avoir une réserve de ressources à disposition. Combien de serveurs sont réservés pour traiter une indisponibilité ? Qu'elle est alors le risque maximum toléré par l'architecture ? Au-delà, les contraintes de disponibilité ne seront plus tenues. Cela peut correspondre à avoir une plateforme identique à la production, pour le cas où l'intégralité de cette dernière tomberait en panne.
Ensuite, il est important de connaître les contraintes imposées par le projet pour la reprise des traitements en cas de défaillance. Ces contraintes peuvent être variables, entraînant des surcoûts plus ou moins importants.
En cas de défaillance d'un composant applicatif, il n'est pas possible de savoir si le traitement en cours n'a pas commencé, est en cours ou est terminé. Devant cet état, plusieurs stratégies peuvent être mises en place. Elles dépendent de chaque traitement individuellement.
En cas d'erreur, il est parfois possible d'interroger le système une fois corrigée, pour découvrir son état et décider de rejouer le traitement interrompu si nécessaire.
Si le traitement est effectué dans une transaction, cette dernière sera appliquée entièrement ou pas du tout, mais il n'est pas possible d'identifier la situation sans interroger à nouveau la base de données. Le système est stable, mais la dernière requête a-t-elle été effectuée ?
Souvent, il n'est pas possible d'analyser l'état du système pour savoir s'il faut ou non rejouer le traitement. Dans ce cas, une approche consiste à systématiquement répéter le processus, charge à ce dernier de savoir si cela est vraiment nécessaire. Un tel processus pouvant être rejoué sans contrainte est dit « idempotent ».
Par exemple, un tel mécanisme est parfois mis en place lors de la validation d'une transaction sur le Web. En effet, si un utilisateur soumet deux fois de suite sa confirmation d'achat, il ne faut pas lui livrer deux fois les mêmes produits, ni lui signaler que sa requête a déjà été effectuée. Seul le résultat de la deuxième soumission lui est visible. Le processus mémorise les dernières requêtes effectuées pendant quelques minutes. Si entre-temps, une requête identique arrive, alors il retourne le même résultat que la dernière fois, mais n'effectue pas le traitement. Sinon, il l'effectue et mémorise la requête et le résultat dans un cache, pendant quelques minutes. Cette technique permet d'obtenir une idempotence temporelle des requêtes en modification. Il faut noter que toutes les requêtes en lecture sont indompotentes.
Il faut cependant souvent faire des sacrifices sur certains états, à condition que l'impact sur la stabilité du système d'informations soit nul ou léger. C'est notamment généralement le cas des sessions utilisateurs. Si un utilisateur mémorise certaines informations avant de confirmer sa transaction, il est tolérable de lui demander de recommencer en cas de défaillance du serveur sur lequel il travaille. En revanche, comme mentionné précédemment dans l'exemple du panier d'un site internet, dans certains cas les pertes d'états ne sont pas acceptables.
Plus généralement, rendre toute défaillance invisible pour l'utilisateur est une tâche ardue qui oblige à utiliser des technologies complexes, coûteuses et difficiles à qualifier.
Montée en charge
Il est important d'identifier la charge attendue par chaque composant applicatif. Les contraintes liées à la charge peuvent être exprimées de plusieurs manières en fonction des connaissances disponibles au moment de la conception ou d'objectifs de résultats à atteindre. Les contraintes liées à la charge peuvent s'exprimer sous les formes suivantes :
- nombre d'accès concurrents ;
- quantité de ressources nécessaire par utilisateur ;
- nombre de transactions par seconde ;
- volume attendu des pics de charge ;
- etc.
Les pics de charge peuvent être traités par un excès de ressources à titre préventif ou par une allocation dynamique de ressources à certaines périodes (capacity planning).
Il existe deux axes d'amélioration de la prise en compte d'une montée en charge :
- horizontale : cette stratégie consiste à être capable d'ajouter de nouveaux serveurs pour l'absorption d'un accroissement de charge ;
- verticale : cette stratégie consiste à augmenter la puissance de l'infrastructure déployée.
Enfin, lorsque sont épuisées toutes les possibilités d'absorption, un mécanisme de débordement peut être mis en place pour préserver le fonctionnement du système. Par exemple, un serveur de débordement peut être chargé envoyer uniquement un message d'erreur, signalant l'indisponibilité temporaire du service.
Type de données (risques sur les données)
Des technologies peuvent être mises en place pour gérer le risque d'une défaillance des supports de données. Ce risque impacte essentiellement les données manipulées par les applications. Suivant leurs caractéristiques, les stratégies seront différentes.
Les données peuvent être pérennes, c'est à dire qu'elles existent sur un support physique que ce soit une base de données, un disque RAID, un backup, un log, etc. La mise en place de mécanismes de réplication permet de retrouver les données en cas de défaillance.
Pour des raisons de performances, les données pérennes peuvent éventuellement s'appuyer sur un cache. En cas de modification, tous les caches sur tous les serveurs doivent alors être prévenus. L'impact d'une notification peut entraîner l'invalidation de la donnée dans tous les caches ou sa mise à jour. Cela complexifie l'architecture et a un impact non nul sur le trafic réseau.
Les données peuvent également être partitionables, c'est-à-dire que la localisation physique des données peut varier suivant différents critères (par utilisateur, géographie, fuseau horaire, etc.)
Enfin, les données peuvent être transitoires, c'est-à-dire que leurs états peuvent être perdus sans impact majeur pour le système d'informations. Comme évoqué ci-dessus, un panier lors d'un achat sur un site de commerce n'est pas transitoire, car il ne doit pas disparaître lors d'une défaillance. Par contre, la page courante et ses champs de formulaire peuvent être perdus.
Ces différentes catégories de données permettent des nuances dans les choix technologiques.
Facilité de paramétrage
Dans une grappe, plusieurs serveurs sont candidats pour répondre aux sollicitations des utilisateurs. Il est donc nécessaire de maintenir la liste des nœuds constituant la grappe et de la propager sur chacun des nœuds. En effet, la communication dans une grappe s'effectue généralement en point-à-point et chaque nœud doit donc avoir connaissance des autres.
Il faut noter que des techniques permettent de mettre à jour dynamiquement la liste des nœuds d'une grappe et de la propager à l'ensemble des nœuds. Cela permet de faciliter l'installation et l'évolution de la plateforme. Cette facilité de paramétrage pourra avoir une influence sur les choix d'architectures, mais en aucun cas, ne doit être un critère prépondérant.
Principes architecturaux
Il est important de comprendre que les mécanismes de gestion des grappes peuvent être mis en place dans différentes couches, de l'OS au back-end en passant par le middleware. Ils peuvent également se combiner et avoir des stratégies différentes.
De nombreux sujets doivent être traités pour chaque mise en place de ce type d'architecture. Les critères peuvent être différents suivant les risques identifiés et les données manipulées.
Haute disponibilité
La mise en place d'une architecture hautement disponible consiste à redonder tous les composants, à détecter toutes les défaillances et à réagir en conséquence.
Lors de la découverte d'un dysfonctionnement, en plus d'isoler la ressource, des contre- mesures peuvent être mises en place pour essayer de rétablir la situation. Cela peut aller jusqu'à la coupure du courant d'un serveur pour le redémarrer. Il est également possible d'injecter de nouvelles ressources mises en réserve à cette fin.
S'il ne reste plus suffisamment de ressources disponibles pour tenir la charge, une partie du trafic peut être détournée vers un serveur de délestage s'excusant de l'indisponibilité du service. Des algorithmes doivent adapter la distribution des requêtes aux composants valides.
Pour détecter la remise en service d'une ressource en erreur, il faut continuer à l'interroger, avec une périodicité moins rapide. Cette vérification doit confirmer la mise en service complète du composant. Souvent, une mise en service prématurée (lors du redémarrage du service) risque d'invalider à nouveau la ressource. Un ping applicatif est généralement la meilleure approche pour s'assurer du démarrage effectif du serveur, avant sa réintégration dans la grappe.
Parfois, l'erreur est trop grave ou l'échec trop ancien pour espérer une reprise d'activité. La ressource est alors définitivement abandonnée. Elle peut reprendre du service lors d'un redémarrage complet du système d'information ou à la demande explicite d'un administrateur.
Si un site complet est en échec (inondation, incendie, tremblement de terre), il peut être nécessaire de déporter tous les traitements vers un site de secours géographiquement éloigné. Comme dans ce cas, les réplications de données sont généralement asynchrones (suite à des contraintes de performance), il y a un risque de perdre une petite partie des informations lors de la bascule.
Les mécanismes de haute disponibilité s'appuient sur la connaissance de l'état des membres d'une grappe. Une défaillance dans cette connaissance et les techniques de replis ne sont pas appliquées ou sont appliquées aléatoirement. Il est important de bien les identifier et de les qualifier avant de mettre en cause les différentes approches. Par exemple, les mécanismes peuvent croire à tort, qu'un système est sain et ne pas s'activer. Il est également possible que les mécanismes de replis se mettent en place simultanément sur différents nœuds, entraînant la création de plusieurs sous-grappes isolées.
Les sondes
L'analyse de l'état du système s'effectue généralement à base de sondes, dont le résultat permet d'appliquer des règles de distribution des traitements ou de contournement des flux. Il existe deux mécanismes principaux pour les sondes :
- par scrutation (polling) : consiste à exécuter une requête à intervalles réguliers pour :
- s'assurer du fonctionnement d'un composant avec parfois une mesure de temps de réponse ;
- collecter une information d'identification ou de santé maintenue au niveau de la cible.
- par capture d'événements : la sonde est prévue pour capturer un événement et le faire remonter au moment où il apparaît. On peut citer par exemple, la détection de la présence d'un nouveau serveur JBoss AS qui apparaît dans une grappe ou la journalisation d'un message de niveau "ERROR" dans le journal d'un serveur, la détection d'une erreur réseau, etc.
La première catégorie de sonde permet d'indiquer si un système fonctionne ou non. Cela s'effectue souvent à l'aide d'un simple ping régulier, par l'écoute d'un battement de cœur réseau (broadcast) ou d'une requête HTTP.
La meilleure approche pour vérifier l'intégrité de l'application consiste à lui demander de le faire. Par exemple, une requête HTTP spécifique permet de vérifier la connexion à la base de donnée, l'espace disque disponible ou toutes informations permettant d'avoir une certaine confiance dans l'état du composant applicatif. Le traitement ne doit cependant pas être trop gourmand en ressource, car il doit être effectué très régulièrement.
C'est à l'application d'indiquer l'URL à utiliser pour les requêtes HTTP de diagnostic. Cette URL doit être calculée pour communiquer spécifiquement avec chaque membre de la grappe, et non via les mécanismes de répartition ou de virtualisation, car elle doit être accessible, sans tolérance aux pannes. Il faut vérifier que cela est bien pris en compte par les outils de répartition de charge.
Les sondes qui consistent à identifier le client d'une requête à partir d'informations directes ou indirectes, permettent une répartition de la charge et limitent les impacts lorsqu'il est nécessaire de sacrifier quelques sessions. Cette identification peut être une adresse IP, un en-tête HTTP, un token SSL, une connexion IP, le nom de l'utilisateur, etc.
Activité des nœuds
Les différents serveurs peuvent avoir également deux états : actif ou passif. Un serveur est dit « actif » s'il s'occupe de traiter les requêtes de l'application. Un serveur est dit « passif » s'il ne traite pas les requêtes mais est prêt à intervenir en cas de défaillance d'un serveur actif. Dans les faits, le serveur passif s'appuie sur des sondes à l'écoute du serveur actif pour décider de prendre la main si nécessaire. Parfois, cette analyse est faite en amont, par le répartiteur de charge.
Souvent, les architectes estiment qu'avoir un serveur passif est un gâchis de ressource. Les apparences semblent leurs donner raison. Mais la réalité est différente. En effet, dans le cas de deux serveurs actifs, il faut qu'un seul des deux puisse encaisser la charge des deux lors d'une défaillance. Donc, chaque serveur ne peut, en mode nominal, être chargé qu'a 50%. Deux serveurs à 50% est équivalent à un serveur à 100% et un autre à 0%. Donc deux serveurs actifs est identique à un serveur actif et un serveur inactif. Néanmoins, la partie passive d'un serveur peut être amoindrie si on considère une grappe de plus de deux serveurs.
Les serveurs passifs peuvent être en nombre inférieur à celui des serveurs actifs. Dans ce cas, ils sont présents en tant que réserve de ressources. Sur des architectures avec beaucoup de serveurs, cette approche permet des économies substantielles. Un serveur devient actif en modifiant dynamiquement un paramètre d'un composant en amont. Cela peut être une modification d'un paramètre du routeur par une annonce ARP, une évolution d'une règle du répartiteur de charge, une annonce de sa présence, etc.
Les architectures actifs/passives sont utilisées lorsque la charge du composant n'est pas très importante. Ainsi, le composant actif sera toujours capable de traiter la charge. Il n'est donc pas nécessaire d'avoir plusieurs composants actifs simultanément. On retrouve ces architectures dans les répartiteurs de charges IP, les adresses IP virtuelles, le dépôt de messages dans des files, etc. Elles peuvent également être mises en place lorsque le prix à payer pour la synchronisation des nœuds actifs est trop important (en termes de charge réseau essentiellement). Il est également important de quantifier le temps nécessaire à l'activation d'un nœud passif, en conformité avec la qualité de service.
Homogénéité des nœuds
Dans une grappe, tous les serveurs sont identiques. Ils ont été installés avec les mêmes applications, les mêmes paramètres, etc. Seule l'adresse MAC est différente, ce qui entraîne une adresse IP différente. Ainsi, les risques sont identiques pour chaque serveur.
Parfois, certains serveurs jouent un rôle particulier, avec un service supplémentaire. Dans ce cas, le serveur présente un risque plus important qu'il faut traiter spécifiquement.
Par exemple, dans ces architectures, il existe souvent une notion de « Singleton cluster ». Il s'agit d'un objet de référence, utilisé par tous les serveurs, mais devant être unique à l'architecture. Il sert à générer des identifiants, maintenir des états partagés, etc. Pour éviter une faiblesse sur ces objets, les technologies élisent un serveur de référence. Ce dernier est épaulé par un autre serveur pouvant prendre le relais en cas de crash du serveur de référence. Il s'agit en fait d'une sorte de grappe dynamique, limitée à la gestion des « singletons ». Ainsi, du point de vue du déploiement, tous les membres de la grappe sont considérés comme identiques, même si ponctuellement, certains sont plus sensibles que d'autres, car ils entraînent des délais supplémentaires pour une reprise d'activité.
Il est préférable de privilégier l'homogénéité des serveurs d'une grappe. Sinon, l'architecture se rapproche d'une ferme de serveurs.
Répartition de la charge
La répartition de charge permet de distribuer les traitements sur plusieurs nœuds ou composants applicatifs. Il existe plusieurs catégories d'algorithmes de répartition qui peuvent parfois se combiner. Les algorithmes sont les suivant :
- Round-robin : c'est l'algorithme le plus simple et considéré le plus souvent comme le plus juste. Il consiste à envoyer les requêtes à chacun des nœuds, les uns après les autres. Il faut s'assurer que la répartition ne défavorise pas trop un serveur qui, de part le scénario applicatif, se verrait toujours attribuer les requêtes les plus lourdes. Il n'est pas tenu compte de la charge du nœud destinataire.
- Aléatoire : c'est aussi un algorithme simple à mettre en œuvre. Les requêtes sont distribuées aléatoirement sur les nœuds. Il n'est pas possible de garantir une distribution juste vers les nœuds. Il n'est pas tenu compte de la charge du nœud destinataire.
- Pondéré : parfois, les serveurs ont des capacités différentes ou sont répartis géographiquement. Cela a un impact sur le temps d'exécution d'une même requête. Pour tenir compte de ces disparités, des algorithmes proposent de pondérer la distribution suivant des valeurs arbitraires associées à chaque serveur. Seul le rapport entre ces valeurs est important.
- Avec boucle de retour : pour améliorer les algorithmes classiques, la pondération peut être effectuée sur une analyse de la charge. Celle-ci peut être déduite en fonction du nombre de requêtes, du temps moyen de réponse, du temps de la dernière réponse, du premier serveur se déclarant comme disponible, du nombre de connexions actives, etc.
- Avec affinité de session : enfin, il est également possible d'attribuer toutes les requêtes d'un même utilisateur à un serveur particulier. Cela permet de bénéficier de son contexte, sans devoir le dupliquer sur tous les serveurs. En général, cette approche est appliquée lorsqu'il est envisageable de sacrifier toutes les requêtes d'un serveur et uniquement celle-ci. Pour maintenir l'association d'un utilisateur avec un serveur, il est nécessaire d'injecter un drapeau dans la réponse (entête HTTP, Sticky bit, Cookie, ré-écriture d'URL, etc.) ou de s'appuyer sur son adresse IP si elle est disponible.
Partage de données
Comme les données doivent être accessibles par différents serveurs, elles sont partagées. Plusieurs stratégies peuvent être mises en place, entraînant des contraintes plus ou moins fortes.
Éviter le partage des données
Pour les applications Web, l'idéal est de ne pas partager de données en s'appuyant sur le navigateur de l'utilisateur. Les données sont mémorisées dans des cookies ou des champs cachés. Cela présente un risque de sécurité car toutes ces informations sont alors manipulables par l'utilisateur. Il faut alors les chiffrer avant de les confier à l'utilisateur.
Une autre approche pour éviter le partage de données consiste à dupliquer les traitements sur chaque serveur. Cela est pertinent pour la tolérance aux pannes de certaines bases de données. Les requêtes en écriture sont effectuées sur chaque serveur, les requêtes en lecture sur un seul. Cela peut générer des désynchronisations si les requêtes utilisent des données qui ont des valeurs différentes entre les serveurs exécutées en parallèle, comme un générateur aléatoire ou l'heure en microseconde. Il faut également utiliser des technologies de commit à deux phases pour garantir qu'une défaillance d'un composant entraîne une désynchronisation des serveurs, à la moindre petite erreur réseau par exemple.
Localisation du partage
Le premier type de partage se limite à la mémoire d'un ou des serveurs. Dans une architecture multi-cœurs, où un serveur possède plusieurs microprocesseurs ou des processeurs multi-cœurs, les données en mémoire ne sont pas immédiatement visibles par tous les processeurs. Des caches sont présents pour chaque cœur, optimisant la lecture et l'écriture des données dans la mémoire partagée. Il est donc important, lors du développement, d'en avoir conscience pour signaler précisément lorsqu'il est nécessaire de vider le cache afin que les autres cœurs puissent avoir conscience des modifications.
D'autres technologies permettent une communication entre tous les serveurs pour maintenir un cache réparti. Les données sont dupliquées entre les serveurs. Lorsqu'une modification est nécessaire, le serveur doit obtenir un accès exclusif sur la ressource avant de la modifier. Ensuite, il doit la libérer. Cela entraîne la réplication des modifications vers les autres serveurs.
Si l'impact sur les performances n'est pas trop important, les données peuvent être partagées sur une mémoire de masse (fichier, base de données). Cette mémoire de masse doit dans ce cas, également utiliser des technologies de haute disponibilité (RAIDx, Base de données HA, SAN, RAS, etc.)
Des technologies comme rsync permettent de synchroniser des disques de façon incrémentale. Un disque maitre duplique ces données vers des disques esclaves. L'algorithme utilisé est capable d'identifier tous les deltas sans devoir comparer chaque secteur, un à un.
Scope
Il est parfois possible de limiter les duplications des donnés dans les caches afin de réduire les trafics réseaux et la quantité de mémoire nécessaire sur chaque serveur. Un partitionnement des données peut être une solution pour améliorer les performances. Les critères doivent être choisis avec discernement, à l'aide d'informations applicatives (identifiant utilisateur, zone géographique, etc.) ou simplement fondées sur un nombre de réplication maximum, répartie aléatoirement entre tous les serveurs.
Réplication
Lors d'une réplication d'une donnée, celle-ci peut s'effectuer de manière synchrone, bloquant toutes évolutions tant que la réplication n'est pas terminée, ou de manière asynchrone. Cette dernière approche présente le risque d'une dé-synchronisation des données, mais améliore notablement les performances. Elle est souvent utilisée lorsqu'une grappe de serveurs de secours est géographiquement éloignée, en conformité avec le plan de reprise d'activité.
Parfois, un mixte des deux approches est utilisé. Une réplication synchronisée est effectuée pour garantir d'avoir au moins n réplicats, puis une réplication asynchrone propage les données vers les autres composants.
Pour optimiser les réplications des informations entre les nœuds, des réseaux spécialisés très rapide sont parfois exploités (Fiber channel). Cela permet un partage en mémoire plutôt que sur disque.
Granularité
Lors de la réplication d'un objet, il est parfois possible de n'envoyer qu'une partie de ce dernier, ou d'envoyer simultanément plusieurs modifications concernant plusieurs objets. Cela contribue à optimiser la réplication de gros objets et réduit la latence réseau.
Généralement, la réplication est complète, réduisant les risques de bugs et garantissant la consistance des objets. Il faut alors que les données aient une taille raisonnable.
Mise à niveau
Lorsqu'un nœud est à nouveau valide, il peut être nécessaire de propager les évolutions qu'il a ignorées avant de le déclarer bon au service. Différentes approches permettent cette mise à niveau. Elles dépendent du type de partage des données. Soit par une demande de l'intégralité de l'état aux autres membres de la grappe (impacte parfois important sur le réseau et sur les nœuds), soit par une reconstruction « paresseuse » des données, au fil de l'eau.
Facilité de paramétrage
Maintenir la liste de tous les membres d'une grappe et la propager sur chacun est source d'erreur. Des techniques permettent une découverte dynamique de tous les membres d'une grappe par les applications.
La première approche consiste à interroger un référentiel, généralement le serveur DNS. Ce dernier peut associer plusieurs adresses IP à un nom de domaine. Une simple requête permet alors d'en avoir la liste. Mais, cela oblige à avoir un nom symbolique pour la grappe, et entraîne un paramétrage spécifique de l'annuaire DNS. Comme la liste est généralement récupérée au démarrage du système d'information, il est impossible d'ajouter un nouveau serveur en cours d'exécution.
Une autre approche consiste à envoyer un paquet réseau en broadcast (destiné à toutes les cartes présentes dans le sous-réseau). Cette annonce peut alors être capturée pour découvrir tous les nœuds, voir de nouveaux nœuds pendant le fonctionnement du système.
Parfois, une liste limitée de serveur permet au processus de découverte de démarrer et d'en découvrir d'autres.
Cet article synthétise les différentes approches utilisées par les technologies de répartition de charge et de tolérance aux pannes. Chaque technologie doit pouvoir se retrouver dans un des scénarios proposés.
