Julien MATHEVET Alexandre BOISSY GSID 4 Rapport Load Balancing et migration Printemps 2001
SOMMAIRE INTRODUCTION... 3 SYNTHESE CONCERNANT LE LOAD BALANCING ET LA MIGRATION... 4 POURQUOI FAIRE DU LOAD BALANCING?... 4 PROBLEMATIQUES DU LOAD BALANCING... 4 Nécessité d une entité de supervision... 4 Comment mesurer la charge?... 5 Répartition de charge statique ou dynamique?... 5 Comment choisir un serveur cible?... 6 L'IMPLANTATION CORBA... 7 CE QUE NOUS AVONS CHOISI D IMPLANTER... 7 Choix retenus... 7 COMMENT NOUS L AVONS IMPLANTE... 7 Au niveau CORBA... 7 Au niveau Java... 8 CONCLUSION... 9 2
INTRODUCTION L'évolution des débits et des services qui leur sont associés nécessite un besoin croissant en terme de ressources matérielles et de fiabilité. Les architectures distribuées apportent dans le cadre de telles applications une solution performante grâce aux mécanismes de load balancing et de migration. Le load balancing ou répartition de charge, dans le cas des architectures client/serveur, permet de répartir la charge induite par les requêtes du client sur un groupe de serveur et ce, de manière transparente pour l utilisateur. La migration quant à elle est plutôt orientée vers la tolérance aux pannes. Nous allons présenter les questions soulevées par le load balancing et la migration ainsi que les différents types d architectures possibles. Nous présenterons ensuite l implantation de la migration que nous avons effectué en CORBA. 3
Synthèse concernant le load balancing et la migration Pourquoi faire du load balancing? Pour accroître facilement la puissance de traitement : le load balancing induit la notion de scalabilité c est à dire de dimensionnement. Ainsi, il suffit d affecter de nouvelles machines au groupe de l application répartie pour en augmenter la capacité de traitement en maintenant une compatibilité maximale. Les notions de flexibilité et de compatibilité découlent de la possibilité de rajouter des machines hétérogènes sans avoir à apporter de modifications au système existant ni à interrompre le service. Pour accroître la fiabilité : L un des principaux avantages des architectures distribuées est qu elles restent fonctionnelles même lorsque l un ou plusieurs de leurs nœuds sont défaillants. Ceux-ci sont alors simplement éliminés de la liste des serveurs disponibles et le système se reconfigure pour faire face au surcroît de charge. Pour s affranchir de certaines limites : Dans le cas d applications réseaux où les accès concurrents sont nombreux, le recours à une application répartie permet de repousser certaines limites induites par le système d exploitation (nombre de connections TCP simultanées, nombre de thread concurrents, ). Problématiques du load balancing Nécessité d une entité de supervision La répartition de charge fait appel a un groupe d entités capables de traiter une requête de manière identique, reste à savoir qui gère cette répartition. Pour cela, le client passe généralement par un intermédiaire appelé trader qui peut soit : Disposer d une interface similaire à celle d un serveur. Dans ce cas, le client à l impression de dialoguer avec un serveur alors que sa requête sera transmise à une autre machine ; le load balancing est alors effectué de manière transparente pour le client. Vérifier de la disponibilité du service demandé et transmettre la référence du serveur susceptible de répondre dans les meilleurs délais. Dans ce cas, le client doit être spécifiquement programmé pour exploiter le load balancing. Il peut y avoir un unique trader mais la logique du load balancing voudrait que l on en ait plusieurs. En effet, dans le premier cas, la notion de tolérance aux fautes devient illusoire puisque la chute du trader entraîne une inaccessibilité du système. 4
Comment mesurer la charge? Lorsque l on cherche à répartir une charge sur un groupe de serveurs capables d effectuer un même traitement, la question est : comment mesurer la charge? Quels sont les critères pertinents? En effet, on pourrait penser que la charge est reflétée par un taux d utilisation processeur, le nombre de processus en file d attente ou encore par le nombre de connexions TCP mais, ne faut-il pas aussi prendre en compte l état du segment de réseau sur lequel se trouve le serveur (par le biais d un ping par exemple)? Une fois que l on a sélectionné les critères pertinents, reste à savoir comment on récupère l information. Il existe plusieurs possibilités : Le serveur informe de son niveau de charge à intervalles de temps réguliers. Le serveur est interrogé à intervalles de temps réguliers. Le serveur informe qu un seuil de charge préalablement fixé a été dépassé. La dernière solution a pour avantage de ne pas trop surcharger le réseau néanmoins elle n'assure pas le même niveau de réactivité que celui obtenu dans le cas d'interrogations régulières. En effet, un ordinateur n'envoyant pas de message peut tout simplement être en panne. Il faut donc coupler cette solution à une autre technique (interrogation cyclique mais de période importante). De toute manière, quels que soient les critères retenus et les traitements qui leur sont associés, on remarque que le simple fait de vouloir mesurer et répartir la charge crée une charge supplémentaire. Il faut quantifier ce surcoût pour choisir la stratégie de load balancing la mieux adaptée. Répartition de charge statique ou dynamique? La répartition de charge peut intervenir à deux niveaux. Soit de manière statique en se limitant à la sélection d un serveur cible pour traiter la demande. Dans ce cas il faut déterminer à quel niveau la répartition s effectue sachant que plus on décompose le traitement et plus la répartition est efficace mais plus le trader est chargé. Ainsi, on peut affecter un serveur différent pour chaque opération, chaque transaction ou encore pour toute la durée d une connexion client. Soit de manière dynamique. L équilibrage de charge est assuré par la possibilité de faire migrer des processus en cours de d exécution d un serveur à l autre. Un autre problème survient alors : comment sauvegarder et restaurer le contexte d exécution d une tache partiellement traitée? 5
Comment choisir un serveur cible? Une fois la charge de chaque serveur déterminée, il faut savoir comment sélectionner un serveur cible parmi le groupe. Si l on cherche à minimiser la surcharge induite par le load balancing, on se tournera vers des algorithmes de sélection aléatoire. Le serveur devant traiter la demande sera choisi de manière au hasard dans la liste des serveurs disponibles avec un éventuel test de charge pour confirmer la décision. On peut aussi utiliser la technique du round robin. Chaque serveur se voit confier une requête à tour de rôle de manière cyclique avec un éventuel test de charge pour confirmer la décision. Ces deux stratégies sont simples à mettre en œuvre et économes en terme de ressources réseaux mais elles ne permettent pas une réelle équité dans la répartition. En effet, on peut rapidement montrer leurs limites si l on suppose que les serveurs du groupe ne sont pas de puissance équivalente ou encore que les demandes des clients n induisent pas la même charge. On peut corriger partiellement cela en augmentant la granulosité de la sélection c est à dire en appliquant l algorithme aux taches les plus élémentaires possibles (pour chaque requête plutôt que pour chaque connexion d un client). Au prix d une légère surcharge, on peut mettre en place des stratégies de load balancing plus efficaces. Elles exploiteront au mieux les indicateurs de charge et pourront aussi bien agir de manière prédictive ou de manière curative (migration). On obtient alors une répartition optimale de la charge au prix d une réflexion plus approfondie. Voici une liste non exhaustive des problèmes pouvant survenir : La surcharge subite des serveurs peu chargés Un serveur peu chargé peut soudain se retrouver noyer sous un flot de requêtes. Pour éviter cela, il faudra mettre en place des calculs permettant de vérifier que la charge du serveur destinataire ne dépassera pas celle du serveur migrateur ou plus simplement qu elle n atteindra pas un niveau de charge trop élevé. La migration perpétuelle Un serveur connaissant des variations de charges importantes pourrait se retrouver entre deux instants rapprochés soit receveur soit migrateur potentiel. Cela entraînerait le déclenchement à répétition de migrations avec un risque de paralysie du système. Pour résoudre ce problème, il faudrait être en mesure de différentier une surcharge transitoire d une panne imminente. En raison des variations des paramètres réseaux (latence, congestion, ) ou de cycle d interrogation trop espacé, il se peut que les indicateurs de charge détenus par le superviseur ne soient pas à jour. L algorithme décisionnel du superviseur peut également être trop lent et donc inefficace. Comment sauvegarder et restaurer les variables d un processus en cours d exécution que l on veut migrer? 6
l'implantation CORBA Ce que nous avons choisi d implanter L implantation des mécanismes reposera sur l exemple des Forums abordé en TP. Nous noterons cependant que celui-ci ne constitue pas le meilleur exemple d application répartie car dans notre cas, si un forum est rattaché à un serveur, la notion de répartition de charge disparaît si tous les clients postent sur le même forum. Nous avons choisi de nous concentrer sur la migration dans une optique de tolérance aux pannes. Il s agit de simuler l envoi de messages sur plusieurs forums sachant qu un forum ne dépend que d un serveur. Au début tout se déroule normalement puis nous simulerons une défaillance sur l un des serveurs pour mettre en évidence le mécanisme de migration. Choix retenus Nous avons choisi de créer un trader pour la gestion des requêtes clients et un superviseur dont le rôle est de gérer la migration. Ces deux entités sont indépendantes des serveurs et peuvent éventuellement être délocalisés sur une machine quelconque du réseau. Les clients passent par le trader pour poster chaque message. Le trader regarde alors la liste des forums enregistrés et renvoie une autorisation au client. Le client contacte ensuite directement l objet forum concerné par le biais du serveur de noms. L information de charge est transmise par les serveurs au superviseur à intervalles de temps réguliers. Le superviseur effectue régulièrement un bilan de charge et détermine s il existe des serveurs trop chargés. Si oui, il contacte d abord le trader pour lui dire de refuser les nouvelles requêtes à destination des serveurs malades puis il recherche un receveur potentiel. S il le trouve, il le contacte et lui ordonne d initier la migration. Comment nous l avons implanté Au niveau CORBA Voici un récapitulatif des fonctionnalités de CORBA que nous avons utilisées : Adaptateur d objet : POA Service de nommage : Serveur de nom standard Approche par héritage Les deux premiers points répondent aux exigences de portabilité de notre application sachant que nous n avons pas profité des spécificités offertes par le POA. Le choix de l approche par héritage repose sur le critère temps. 7
Au niveau Java La mesure de la charge a été simulée par l intermédiaire d un thread qui appelle sur le superviseur, une méthode incrémentant un compteur. Un autre thread (appelé moniteur) s exécutant sur le superviseur contrôle le niveau de charge des différents serveurs et détermine en fonctions des seuils prédéfinis si des migrations doivent avoir lieu. Le moniteur est déclenché toutes les dix secondes. Ce chiffre résulte d un compromis entre le problème de la réactivité (détection des pannes au plus tôt) et le problème des fausses alertes (migration déclenché sur un serveur momentanément surchargé). Le moniteur choisi une cible pour la migration parmi les serveurs les moins chargés (ceux disposant de la valeur de compteur la plus élevée) ; un serveur cible ne peut être sélectionner qu une fois par bilan de charge. La migration se déroule suivant cet algorithme : 1. Le moniteur transmet séquentiellement au superviseur les couples (migrateur/receveur). 2. Le superviseur contacte le trader et lui indique que la migration de tous les forums rattachés au migrateur est en cours. Les requêtes client sont alors rejetées jusqu à la fin de l opération. 3. Le superviseur contacte le migrateur en lui demandant de stocker les propriétés de chaque forum (titre, thème, modérateur et liste des messages) au niveau de la forum factory. 4. Chaque Forum est enregistré au niveau du serveur de nom si bien que l on ne peut avoir qu une référence par forum. La forum factory commence par délier le forum du serveur de nom et déclenche la création d un nouveau forum sur le receveur en lui passant en paramètres les propriétés sauvegardées précédemment. Une fois la création effectuée, le forum situé sur le migrateur est supprimé et le nouveau forum est enregistré auprès du serveur de nom sous la même référence que le forum détruit. 5. Enfin, le receveur indique au trader que la migration a réussi et que le forum est à nouveau disponible. 8
CONCLUSION Après l analyse détaillée des différentes stratégies existantes concernant le load balancing, ce projet nous a permis de mettre en œuvre de manière simple la migration de processus pour établir une tolérance aux pannes. Nous avons pu réaliser l utilité de tels mécanismes et plus généralement les avantages apportés par les architectures distribuées. La spécification CORBA n intègre pas de base les mécanismes de répartition de charge et de migration mais elle offre tous les outils nécessaires à sa mise en place. Notre simulation est fonctionnelle néanmoins les contraintes temporelles initialement fixées, nous ont obliger à restreindre notre cahier des charges. Ainsi nous aurions souhaiter : Effectuer une mesure de charge moyennée pour lisser les variations rapides de charge de chaque serveur et différencier les pics de charges des prémices d une défaillance. On pourrait en effet imaginer conserver un historique des indices de charges. Agir de manière préventive plutôt que curative en fixant deux seuils de charge sur les serveurs, le premier déclenchera une migration partielle des services, l autre déclenchera la migration totale. Appliquer les stratégies de décision plus évoluées pour la sélection des serveurs cibles (prévision de la charge induite). Implanter un mécanisme multi-threadé pour effectuer les migrations. Dans l état actuel de notre programme, le superviseur effectue les migrations de manière séquentielle ; si l une d elle vient à échouer, le superviseur reste bloqué et n effectue pas les migrations suivantes. La solution consiste à créer un thread par couple migrateur/receveur et d utiliser un mécanisme de callback pour s assurer du bon déroulement de la migration. 9