La tolérance aux fautes adaptable pour les systèmes à composants

Transcription

La tolérance aux fautes adaptable pour les systèmes à composants
La tolérance aux fautes adaptable pour les
systèmes à composants : application à un gestionnaire de données
Phuong-Quynh Duong* — Elizabeth Pérez Cortés** — Christine
Collet*
* Laboratoire LSR/IMAG
681, rue de la Passerelle
38400 Saint Martin d’Hères, FRANCE
{phuong-quynh.duong, christine.collet}@imag.fr
** Depto. de Ingeniería Eléctrica UAMI
Av. San Rafael Atlixco 186 Col. Vicentina 09340, México DF
[email protected]
RÉSUMÉ. Ce papier présente notre approche pour la définition d’un framework qui autorise
l’adaptation de la tolérance aux fautes aux systèmes à composants. Nous considérons que le
processus permettant de fournir la tolérance aux fautes adaptable peut se faire en deux étapes :
la personnalisation et la régulation dynamique. Le travail présenté dans ce papier concerne la
personnalisation de la tolérance aux fautes. Nous avons défini la notion de niveau de tolérance
aux fautes pour un système. À partir du niveau souhaité, nous avons identifié l’ensemble des
éléments devant être intégrés dans le système cible. Pour illuster notre approche nous considérons un gestionnaire de données à composants auquel on associe deux niveaux différents de
tolérance aux fautes.
ABSTRACT. This paper presents the approach of defining a framework for adaptable fault tolerance in component-based systems. We have divided the process of providing adaptable fault
tolerance into two stages: customization and adaptivity. The paper focuses on the first stage:
fault tolerance customization. We defined the notion of fault tolerance level for a given system.
From a required level, we identified the set of needed elements to be integrated into the target
system. A component-based persistence object manager with two different required levels of
fault tolerance has been chosen as target system to illustrate our approach.
Services base de données, Architectures à base de composants, Tolérance aux
fautes, Niveau de tolérance aux fautes.
MOTS-CLÉS :
KEYWORDS:
level.
Database services, Component-based architecture, Fault tolerance, Fault tolerance
1. Introduction
L’utilisation croissante des systèmes informatiques dans le quotidien augmente de
manière proportionnelle les contraintes de sûreté de fonctionnement qu’ils doivent
respecter. Plus ils sont utilisés, plus une défaillance a de l’impact [AVI 97]. En outre,
ces systèmes sont de plus en plus complexes, évoluent dans un environnement réparti,
avec des éléments mobiles, gèrent des données multimédia, etc. De ce fait, ils ne sont
plus construits de manière monolithique mais à partir d’un ensemble de composants
chacun prenant en charge des tâches précises. Des efforts sont menés dans le but de
construire ces composants. Ainsi des composants dédiés au contrôle de concurrence,
à la désignation, à la persistance, etc. existent actuellement [Gar 02a, DRA 02]. L’approche système à composants a des propriétés permettant l’adaptabilité : le système
intègre seulement les éléments qui lui sont nécessaires et peut choisir ceux qui mettent
en oeuvre les politiques ad-hoc. Ce type de systèmes doit aussi pouvoir assurer une
tolérance aux fautes adaptée à la technologie composant, et donc adaptable.
Ce travail s’inscrit dans le cadre du projet NODS (Networked Open Database
Services) [COL 00] (http ://www-lsr.imag.fr/storm.html) qui vise la construction des
systèmes de gestion de données à composants. Dans le but d’avoir des systèmes de
données sur mesure, des services d’évènements, de requêtes, de persistance, et de
duplication sont en construction [Gar 02a, DRA 02, Gar 02b, SOL 00]. Ces services
sont adaptables dans la mesure où le choix des politiques à appliquer est laissé au
concepteur du système. L’objectif du travail présenté dans cet article est de construire
un framework de tolérance aux fautes permettant au constructeur d’un tel système à
composants de choisir le niveau de tolérance aux fautes (NTF) et d’intégrer d’une
manière simple les mécanismes nécessaires pour maintenir ce niveau.
La suite de cet article est structurée de la manière suivante : la section 2 contient
la description détaillée de l’approche. La section 3 présente la notion de NTF, les différents niveaux possibles, ainsi que les correspondances entre les NTFs et les mécanismes nécessaires à leur support. Des exemples d’application de l’approche pour un
gestionnaire de données sont présentés en section 4. Dans la section 5 notre approche
est comparée qualitativement à d’autres propositions et finalement, les conclusions et
les perspectives de ce travail sont données dans la section 6.
2. Approche
Traditionnellement, un système tolérant aux fautes est construit en intégrant des
éléments redondants qui sont superflus dans un cas normal, mais qui sont nécessaires
dans le cas d’une faute. Durant l’exécution, le système est surveillé pour détecter la
présence de fautes et, lors de l’apparition d’une faute, la reprise est réalisée en utilisant
les éléments redondants inclus préalablement. Le choix des éléments redondants à
inclure dépend des types de fautes à tolérer et du fonctionnement requis. De ce fait,
la tolérance aux fautes peut être fournie à différents niveaux, chacun nécessitant une
infrastructure particulière et introduisant des sur-coûts différents.
Dans notre approche, nous distinguons deux étapes dans le processus permettant
de fournir la tolérance aux fautes adaptable. Ces deux étapes sont appelées respectivement personnalisation et régulation dynamique du NTF. La première étape vise
à aider les constructeurs à personnaliser le NTF de leurs systèmes. Il faut :
i) fournir un moyen de préciser le NTF requis,
ii) guider le choix des éléments redondants, de surveillance, de détection et de récupération en fonction du NTF spécifié,
iii) faciliter l’intégration de ces éléments dans le système cible, et
iv) assurer l’exécution correcte du système intégré.
Notre objectif est de fournir pour cela un framework de personnalisation de
la tolérance aux fautes. Le terme framework désigne ici un ensemble d’interfaces
avec une implémentation partielle. En effet, seul un sous-ensemble des interfaces sera
implémenté tandis que le reste doit être pris en charge par le système cible. Cette
approche est bien adaptée pour les composants gris. Un composant est dit gris lorsqu’il
permet d’exposer son architecture, ce qui facilite les démarches des mécanismes de
tolérance aux fautes.
La deuxième étape, la régulation dynamique du NTF, tient compte du fait que la
tolérance aux fautes est coûteuse par nature et requiert une quantité minimale de ressources pour être assurée. Étant donné que les ressources dans un système ne sont
pas constantes, par exemple, les machines sont ajoutées et retirées dynamiquement, le
NTF requis ne peut pas toujours être fourni. En revanche, le système doit ajuster le
NTF en fonction des ressources disponibles. Cet ajustement peut entraîner une évolution de l’architecture de l’application qui doit être réalisée en surveillant la cohérence
de l’exécution. Notre framework sera étendu pour prendre en compte cet aspect et
obtenir ainsi un framework adaptable pour la tolérance aux fautes.
Ce papier décrit les premiers éléments de définition de notre framework. Il concerne
l’étape de personnalisation du NTF des systèmes. Nous supposons que les ressources
disponibles sont infinies et que les éléments qui constituent un système respectent
leur spécification en l’absence de fautes. Nous supposons également que ces éléments
n’intègrent aucun mécanisme de tolérance aux fautes.
3. Niveaux de la tolérance aux fautes
Le comportement d’un système peut être caractérisé par un ensemble de propriétés.
Ces propriétés peuvent être classifiées en propriétés de sûreté (safety properties) et
propriétés de vivacité (liveness properties) [LAM 77]. Intuitivement, les propriétés
de sûreté indiquent que les mauvaises choses n’arrivent jamais, et les propriétés de
vivacité indiquent que les bonnes choses arrivent. Une faute a lieu quand au moins
une de ces propriétés n’est pas vérifiée.
Les fautes qui surviennent au cours du cycle de vie du système et qui ont une
cause matérielle sont appelées fautes opérationnelles (operational faults). Les fautes
dues à une mauvaise conception sont appelées fautes de conception (design faults)
[JAL 94]. On connaît à priori l’ensemble des propriétés qui potentiellement ne sont
pas respectées lors de la présence d’une faute de conception. La présence d’une faute
opérationnelle peut violer n’importe quelle propriété du système.
3.1. Types de fautes et leur relation d’inclusion
Les types de fautes pris en compte dans notre travail font partie des types de fautes
décrits dans [CRI 91]. Ils sont les suivants :
Panne franche (Crash) : Le système s’arrête prématurément. Les pannes franches
peuvent être classifiées selon l’état du système lors de la reprise de fonctionnement :
– Panne franche amnésique (Amnesia-crash) : Le système est relancé à
partir d’un état prédéfini indépendant de l’état au moment de la panne franche.
Il perd donc les informations produites pendant son exécution antérieure.
– Panne franche partiellement amnésique (Partial Amnesia-crash) : Certaines parties de l’état du système sont restaurées à leur état au moment de la
panne franche, les autres parties sont relancées à partir d’un état prédéfini, par
exemple l’état initial.
– Panne franche pause (Pause-crash) : Le système est relancé à partir de
son état au moment de la panne franche.
– Panne franche définitive (Halting-crash) : Le système n’est pas relancé.
Omission (Omission) : Le système est en panne d’omission s’il ne répond pas à une
requête, c-à-d, lorsque le résultat du traitement d’une requête n’est pas observé.
Réponse tardive (Late timing) : La réponse provenant d’un système arrive en retard
par rapport au délai prévu.
Valeur (Value) : La valeur de la réponse fournie par le système n’est pas correcte.
Byzantine (Byzantine) : Le comportement du système est arbitraire vis-à-vis de la
panne.
Les types de fautes présentés1 ci-dessus appartiennent à la classe des fautes opérationnelles. Ces fautes ne sont pas indépendantes. Par exemple, un crash entraîne une
faute d’omission car lors qu’un système a un crash, il ne peut plus répondre à une
demande. Par conséquent, il a aussi une faute d’omission.
La relation d’inclusion [JAL 94] montrée dans la figure 1 établit de manière naturelle une hiérarchie entre les différents types de fautes. En conséquence, nous définissons la relation parent entre deux types de fautes comme suit :
Definition 1 Le type de fautes
est le parent du type de fautes
si l’ensemble
est inclus dans l’ensemble . Par simplicité nous dirons que est le parent de
ou
nous écrirons simplement
.
. Dans la suite, nous utilisons les termes en anglais pour désigner les différents types de fautes.
Byzantine
Crash
Omission
Value
Timing
Figure 1. Relation d’inclusion entre les types de fautes
3.2. Définition du niveau de tolérance aux fautes
Nous nous inspirons de la définition donnée dans [GAR 99] pour définir le NTF
d’un système en fonction de ses propriétés et des fautes considérées.
Un système est dit tolérant au type de fautes
conditions suivantes est vraie :
pour la propriété
– La propriété est préservée lors la présence de la faute de type
la faute est dite masquée.
si une des
. Dans ce cas
– La propriété est violée lorsque la faute de type se produit mais quand la faute
ne se produit plus, le système rétablit son exécution et la propriété est à nouveau
satisfaite. Dans ce cas la faute est perçue mais le système est capable de se remettre et
de continuer à fonctionner normalement.
En conséquence, pour un type de fautes il est possible d’avoir l’un des deux niveaux de tolérance : masquage (masking) ou non masquage (unmasking). Le premier
est plus “fort” que le deuxième.
Nous nous intéressons aussi au cas où le système est capable de signaler la présence d’une faute. Ce niveau intermédiaire est appelé signalisation (signaling), et il
est moins “fort” que le niveau de non masquage. Le plus “faible” niveau est de ne
rien faire par rapport à une faute. Il est appelé néant (nothing) et complète le spectre
des possibilités. Par la suite, nous utilisons les termes anglais : masking, unmasking,
signaling et nothing pour décrire les valeurs possibles d’un niveau de tolérance aux
fautes.
Étant donné la relation d’inclusion entre les types de fautes, le choix du niveau
pour un type de fautes influence le choix du niveau pour les types de fautes qui se
trouvent au dessous dans la hiérarchie.
Comme nous l’avons déjà mentionné, les types de fautes pris en compte dans notre
proposition actuelle sont exclusivement les fautes opérationnelles. Par conséquent,
nous devons nous intéresser à toutes les propriétés du système dans la définition du
NTF d’un système :
Definition 2
f est un type de fautes et
où
l est plus “fort” que ou égal à si
.
Le NTF suivant est valide sur les types de fautes donnés dans la figure 1 :
!#"$%&'(
!)# *+(
,.%/(0'1 + 324/
1 5467 1 8 !
Dans cet exemple, puisque les fautes late timing ont un niveau de tolérance aux
fautes unmasking, le niveau pour les fautes d’omission peut donc prendre une des
deux valeurs : unmasking ou masking. Si la valeur masking est choisie, le niveau pour
les crash doit être masking car les fautes d’omission incluent les crash.
Il faut noter que la contrainte sur les valeurs possibles pour chaque type de fautes
dans la définition 2 réduit le nombre des NTFs valides à un nombre fini, permettant
ainsi de les lister. À partir de la liste des NTFs possibles, nous pouvons donc établir
les correspondances entre un niveau de tolérance aux fautes donné et les éléments
redondants, les éléments de surveillance, le processus de diagnostic et les éléments de
récupération nécessaires. Cette démarche est présentée dans la sous-section suivante.
3.3. Correspondances entre le niveau de tolérance souhaité et les éléments
nécessaires
À partir de la définition du NTF, nous sommes capables d’identifier d’une manière
systématique les éléments nécessaires à intégrer dans un système afin que le NTF
demandé soit assuré. Pour cela, nous avons établi trois tableaux dont le contenu guide
le choix des moyens logiciels permettant d’assurer le NTF souhaité. Ces tableaux de
correspondance ont été conçus en utilisant les solutions existantes dans le domaine de
tolérance aux fautes. Ce sont :
– Le Tableau des éléments redondants (TER) qui établit les correspondances entre
le niveau souhaité et les éléments redondants ainsi que les procédures de récupération
associées ;
– Le Tableau de surveillance (TS) qui établit les correspondances entre les types
de fautes pris en compte et les informations de surveillance à recueillir ;
– Le Tableau de diagnostic (TD) qui établit les correspondances entre les types de
fautes et les procédures de diagnostic de la présence d’un type de fautes correspondant.
Les trois tableaux sont donnnés en annexe A. On ne donne aucune indication sur la
fréquence de la prise d’informations diagnostiques ainsi que sur la façon de “capter”
ces informations. Plus la prise est fréquente, plus la présence de faute est vite détectée
mais plus la mise en oeuvre est coûteuse. La prise d’informations diagnostiques peut
être effectuée en mode pull2 ou push3 . Ces choix sont laissés aux concepteurs de
système.
Pour mettre en oeuvre le NTF de notre exemple, la duplication est le mécanisme
adéquat. La politique précise de duplication doit être déterminée selon la disponibilité
des ressources. Pour détecter la présence d’un crash, on lit dans le tableau TS qu’il est
nécessaire d’utiliser des messages de battement de coeur. Lorsqu’ils n’arrivent pas au
moment prévu, le système est suspecté d’être en panne franche. Cette procédure de
diagnostic est donnée dans le tableau TD sur la ligne correspondant au crash.
Il faut remarquer que nos tableaux présentent des mécanismes parfaitement bien
définis et testés ce qui assure la possibilité de mettre en oeuvre les différents NTF
possibles. Donc dans le framework, les interfaces de chaque élément sont proprement
définies et les implémentations des éléments qui ne dépendent pas de l’application
précise sont fournies.
4. Application de l’approche à un gestionnaire de données
Dans cette section, nous illustrons notre approche en utilisant un gestionnaire de
données à base de composants comme système cible. Pour cela, nous décrivons, dans
la sous-section 4.1, le modèle de composants avec lequel le gestionnaire de données
est conçu. Ensuite, nous présentons l’architecture du gestionnaire en excluant les aspects de la tolérance aux fautes. Finalement, les sous-sections 4.3 et 4.4 présentent
l’architecture du même gestionnaire avec deux NTFs différents.
4.1. Modèle de composant
Le modèle de composants décrit dans cette section est inspiré du modèle de composant Fractal [GRO b], un travail en cours dans le cadre de ObjectWeb [CON ]. Nous
présentons seulement des éléments essentiels permettant la compréhension de notre
démarche.
Un composant est une structure qui existe seulement à l’exécution. Il peut correspondre à un objet ou à une agrégation d’objets. Un composant est formé de deux
parties : un contrôleur et un contenu.
Le contenu d’un composant peut être composé (d’un nombre fini) d’autres composants. Ces composants sont appelés sous-composants. Un composant primitif est
celui dont le contenu est un objet.
. En mode pull, le système envoie les informations diagnostiques seulement quand il y a une
demande de prise d’informations.
. En mode push, le système envoie les informations diagnostiques à sa volonté sans se soucier
s’il y a une demande de prise d’informations.
Le contrôleur d’un composant incarne le comportement de contrôle associé à un
composant particulier. Un contrôleur peut :
– intercepter les appels entrant et sortant du contenu,
– superposer le comportement de contrôle au comportement du contenu du composant,
– gérer le cycle de vie du contenu (et par conséquent, du composant),
– exporter les interfaces du contenu,
– connaître et modifier la composition du contenu.
En pratique, le contrôleur est matérialisé par deux parties : un conteneur et une
racine de composition. La racine de composition encapsule la composition des souscomposants participant au contenu et les interactions entre eux. La racine de composition représente l’aspect fonctionnel du composant en question tandis que le conteneur
représente l’aspect technique.
Nous utilisons le terme entité pour désigner un composant, un contenu ou un
contrôleur. Les entités interagissent à travers des appels de méthodes. Le regroupement de différents appels de méthodes constitue une interface.
Une interface serveur regroupe des appels de méthode servis par une entité tandis
qu’une interface cliente regroupe des appels de méthode émis par une entité.
Une liaison (binding) est un lien entre une interface cliente et une interface serveur.
Une liaison est établie si et seulement si l’interface serveur peut accepter au moins tous
les appels que le client émet vers cette interface serveur.
La figure 2 montre la convention graphique utilisée dans la suite pour présenter les
différentes parties d’un composant.
interface (serveur) exportée du contenu
lia
iso
n
interface cliente
contenu
un composant vu
interface serveur
racine de composition
conteneur
Figure 2. Convention graphique
de l’extérieur
un composant
primitif
4.2. Architecture du gestionnaire de données
Le gestionnaire de données que nous utilisons dans ce papier est inspiré du travail présenté dans [Gar 02a]. Dans le cas où la tolérance aux fautes n’est pas prise
en compte, le composant de persistance (Persistance) a besoin d’un composant
pour accéder à un stockage permanent (Stockage) et d’un composant qui gère le
cache (Cache). Le composant Cache, à sont tour, est composé d’un composant qui
gère le cache (Cache) et d’un composant qui décide quels sont les objets à supprimer dans le cache quand le cache est plein (Remplacement). Les trois composants Persistance, Stockage et Cache sont englobés dans un composant
appelé Gestionnaire de données. La figure 3 montre l’architecture qui vient
d’être décrite. Les deux sous-sections suivantes montrent comment cette architecture
évolue quand un NTF est requis.
Persistance
Cache
Cache
Stockage
Remplacement
Gestionnaire de données
Figure 3. Architecture d’un gestionnaire de données selon l’approche à base de composants
4.3. Un premier niveau de tolérance aux fautes
Dans cette sous-section, nous montrons comment nous ajoutons un NTF au gestionnaire de données de la figure 3 selon notre approche. Le NTF choisi est {<(Crash,
unmasking), <Omission, nothing>, <Late timing, nothing>, <Value, nothing>, <Byzantine, nothing>} .
Éléments redondants Afin d’assurer le niveau unmasking du crash, nous utilisons la journalisation et le checkpointing.
La journalisation est réalisée par la collaboration entre deux éléments : un Facade 4
et un Journal. Le Journal est responsable de l’organisation de l’ensemble des enregistrements gardant les traces de l’exécution des opérations effectuées sur un espace
de stockage fiable. Il fournit des méthodes permettant d’écrire, lire et rechercher de tels
enregistrements. Cependant, la sémantique des données stockées dans le journal lui est
étrangère. La connaissance de la sémantique des données relève de la responsabilité
du Facade. Le Facade est donc un élément appartenant à la racine de composition
du composant Gestionnaire de données. Il est mis en oeuvre par le programmeur du composant Gestionnaire de données, tandis que le Journal est
mis en oeuvre par le concepteur du framework de tolérance aux fautes (c.f section 2).
Le checkpointing est mis en place d’une manière similaire. Il utilise le même élément Facade décrit plus haut et un élément appelé Checkpoint. Lors de l’implantation, le Journal et le Checkpoint peuvent être mis en oeuvre par une même
classe.
Surveillance Nous avons besoin d’un élément d’information qui émet périodiquement des battements de coeur (heartbeat) afin de détecter le crash du gestionnaire
de données. Cet élément est donc inséré dans l’architecture sous la forme d’une interface serveur HeartBeat du composant final. Cette interface est à la charge de la
racine de composition du composant Gestionnaire de données, c-à-d, lors de
la mise en oeuvre, la racine de composition du Gestionnaire de données doit
implanter cette interface.
Récupération Le principe de la récupération est de trouver un état cohérent du
gestionnaire de données à partir du journal et du checkpoint, et ensuite de l’installer
sur le système, à savoir le cache et éventuellement le stockage. La récupération étant
spécifique à chaque application, nous laissons cette tâche à la charge du programmeur.
Dans le cas du gestionnaire de données, la procédure de récupération est effectuée par
l’élément Facade car il a l’accès aux informations dans le journal et le checkpoint,
et il sait les interpréter. L’élément Facade doit exporter une interface permettant de
déclencher le processus de récupération.
Architecture finale
Le résultat de l’ajout du NTF {<(Crash, unmasking),
<Omission, nothing>, <Late timing, nothing>, <Valeur, nothing>, <Byzantine, nothing>} est montré dans la figure 4. Dans cette architecture finale :
– Le conteneur est enrichi de deux interfaces serveur disponibles à la racine de
composition : Journal et Checkpoint.
– La racine de composition est enrichie de quatre interfaces serveur : Heartbeat
et trois interfaces de l’élément Facade. Ces trois interfaces correspondent à l’inter. Le nom Facade désigne un élément qui offre une interface unifiée pour un ensemble d’interfaces dans un sous-système. Cet élément Facade a pour but de cacher les interfaces plus
complexes du sous-système et donc de permettre d’utiliser ces interfaces plus facilement.
face de récupération, une interface cliente vers les deux interfaces serveur mentionnées
au dessus du conteneur et une interface vers le contenu pour rassembler des informations à écrire sur le journal et le checkpoint.
Persistance
Facade
recover
journal
Stockage
Cache
racine de composition
heartbeat
checkpoint
conteneur
Gestionnaire de données
Figure 4. Architecture du composant final avec le NTF {<(Crash, unmasking),
<Omission, nothing>, <Late timing, nothing>, <Value, nothing>, <Byzantine, nothing>}
4.4. Un autre niveau de tolérance aux fautes
Le NTF présenté dans cette sous-section est {<(Crash, masking), <Omission, nothing>, <Late timing, nothing>, <Value, nothing>, <Byzantine, nothing>} .
Éléments redondants La duplication avec au moins deux copies actives permet
d’assurer le niveau masking du crash.
Nous supposons disposer d’un framework de duplication tel que celui décrit dans
[DRA 02]. Une politique de duplication est définie par quatre éléments : le nombre de
copies, l’emplacement des copies, le moment de création des copies et la façon dont
les copies évoluent (ou le modèle de l’évolution des copies). Le choix de ces quatre
autres éléments n’est pas à la charge du framework de duplication. Une fois que le
modèle d’évolution des copies est choisi, le framework de duplication assure que ce
modèle est respecté. Le modèle d’évolution des copies correspondant à la duplication
avec au moins deux copies actives est le modèle de copie unique5 .
Un objet de liaison fournit par le framework de duplication est ajouté dans le conteneur du composant Gestionnaire de données. Cet objet de liaison a pour but
d’intercepter les opérations à effectuer sur le support de stockage. Il interagit avec le
framework de duplication afin d’assurer que les copies évoluent correctement vis-à-vis
du modèle choisi.
Surveillance Comme dans le cas précédent, pour pouvoir détecter le crash, un
élément d’information qui émet périodiquement les battements de coeur (heartbeat)
est ajouté à la racine de composition.
Récupération Une partie de la procédure de récupération est incluse dans le
choix du modèle d’évolution des copies. Elle est donc assurée par le framework de
duplication. Afin que la récupération soit effectuée, le framework de tolérance aux
fautes doit introduire un nouveau élément que nous appelons le Gestionnaire
du niveau de tolérance aux fautes (GNTaF). Ce gestionnaire a pour
but de maintenir le nombre de copies nécessaires à un modèle d’évolution donné. Par
conséquent, dans notre cas, si une copie est en crash, le GNTaF doit être capable de
créer une nouvelle copie pour que deux copies actives soient toujours disponibles.
Pour cela, le GNTaF interagit avec le framework de duplication à travers l’interface
fournie par le framework de duplication pour la création d’une nouvelle copie.
Architecture finale
La figure 5 montre l’architecture finale de cet exercice.
5. Travaux similaires
5.1. Niveaux de tolérance aux fautes
Le terme tolérance aux fautes a des sémantiques diverses. Les sémantiques les plus
utilisées par les concepteurs de systèmes sont les suivantes :
– Les comportements du système lors de l’apparition de certains types de fautes
sont bien décrits dans la spécification, et l’implantation du système respecte cette spécification. Cette forme de tolérance est connue sous le terme : fail-safe.
– Le système accomplit la tâche décrite dans sa spécification malgré la panne de
certains de ses composants. Cette forme de tolérance est appelée masquage.
La distinction entre ces deux niveaux de la tolérance aux fautes est difficile. Si
la spécification d’un système précise son comportement lors de la présence de fautes
et il le respecte, il est fail-safe mais puisqu’il accomplit sa tâche, il fait également le
masquage.
. Le modèle de copie unique assure que toutes les copies sont équivalentes et donc évoluent
de la même manière. La lecture et l’écriture sur les copies s’effectuent sur les copies les plus à
jour.
Framework
de
duplication
Persistance
création d’une
nouvelle copie
Objet
de
liaison
Stockage
Cache
Gestionnaire
du niveau de
tolérance aux fautes
racine de composition
heartbeat
contenuer
Gestionnaire de données
Figure 5. Architecture du composant final avec le NTF {<(Crash, masking), <Omission, nothing>, <Late timing, nothing>, <Value, nothing>, <Byzantine, nothing>}
Il existe des travaux sur la spécification formelle des systèmes informatiques
qui définissent la tolérance aux fautes par rapport aux propriétés de sûreté (safety properties) et aux propriétés de vivacité (liveness properties) d’un système
[GAR 99, KUL 99]. Ces travaux distinguent quatre formes de tolérance aux fautes
lors de la présence de fautes :
– nothing : Les propriétés de sûreté et de vivacité sont violées,
– fail-safe : Les propriétés de sûreté sont préservées tandis que les propriétés de
vivacité sont violées,
– unmasking : Les propriétés de sûreté sont violées tandis que les propriétés de
vivacité sont préservées,
– masking : Les propriétés de sûreté et de vivacité sont préservées.
La classification à quatre niveaux proposée par les travaux formels prend en compte
essentiellement les classes de fautes de conception, ce qui n’est pas applicable dans
notre contexte.
5.2. Adaptabilité de la tolérance aux fautes
Parmi les travaux qui ont essayé de découpler la tolérance aux fautes de l’aspect
applicatif d’un système et ensuite de rendre la tolérance aux fautes adaptable, on peut
citer Chameleon [KAL 99], AQuA [REN 01], la spécification de CORBA tolérant aux
fautes [GRO a] et DARX [PAR ].
Aucun de ces travaux ne donne une définition précise du NTF. Bien que Chameleon propose la notion de “spécification de tolérance aux fautes” utilisée par le système
cible pour indiquer ses besoins de fiabilité. Nous n’avons pas trouvé dans les papiers
publiés une définition claire de la façon dont le système peut exprimer ses besoins.
Les autres travaux ne mentionnent pas explicitement le concept NTF.
AQuA, la spécification de CORBA tolérant aux fautes et DARX assurent un seul
NTF correspondant au masquage6 des pannes franches. AQuA masque aussi les fautes
de valeur.
Donc, les types de fautes pris en compte dans ces travaux sont limités à deux :
pannes franche et fautes de valeur. Le seul mécanisme utilisé pour ces types de fautes
est la duplication. Dans certains cas, l’adaptabilité porte sur le nombre de fautes tolérées. Par ailleurs, l’adaptabilité même dans le cas de la personnalisation peut être exprimée par différentes variables tels que le type de fautes, le degré des conséquences
causées par la présence de fautes, etc. Les travaux existants proposent une solution
partielle au problème de l’introduction de la tolérance aux fautes adaptable dans un
système.
Tous les travaux cités dans cette section considèrent les systèmes cibles comme
des boîtes noires. Ils n’ont pas de connaissances sur l’architecture ni sur les comportements de ces systèmes. Ceci explique le fait que le seul mécanisme de tolérance aux
fautes utilisé dans ces travaux est la duplication, et donc le seul niveau de tolérance
aux fautes envisageable est le masquage.
6. Conclusion et perspectives
Dans cet article, nous avons présenté nos premiers résultats vers la tolérance aux
fautes adaptable, à savoir notre approche de définition d’un framework de personnalisation de la tolérance aux fautes pour les constructeurs de systèmes répartis à composants. Nous avons donné une nouvelle définition du niveau de tolérance aux fautes
pour un système. Avec cette définition nous sommes capables de déduire les éléments
redondants, de surveillance, de détection et de récupération nécessaires au support
d’un NTF spécifié par le constructeur d’un système.
Nous avons aussi développé deux exemples qui montrent comment intégrer les
éléments des mécanismes de tolérance aux fautes à une application précise. Ces exercices nous ont permis d’identifier d’autres éléments qui doivent apparaître dans l’architecture pour assurer la coordination des composants, par exemple le gestionnaire
du niveau de TaF. D’autres expériences visant la définition d’une architecture globale
qui prend en compte tous les NTFs possibles et où les composantes choisis s’intègrent
sans difficulté sont en cours de réalisation. Le résultat de cette tâche nous permettra
. La sémantique de masquage est celle utilisée par les concepteurs de système (c.f le paragraphe Niveaux de tolérance aux fautes au début de cette section).
finalement de définir complètement notre framework et poursuivre sa validation par le
biais du prototypage.
À plus long terme nous prévoyons de lever l’hypothèse des ressources infinies pour
faire évoluer notre framework et le rendre adaptable. Dans cette future étape du travail,
une représentation dynamique des ressources du système s’avère nécessaire ; le NTF
effectivement fourni sera déterminé à partir des ressources disponibles et ajusté dynamiquement. La réflexivité de notre modèle de composants nous semble déterminante
dans la réalisation de cette tâche.
7. Bibliographie
[AVI 97] AVIZIENIS A., « Toward Systematic Design of Fault Tolerant Systems », IEEE Computer, vol. 30, n 4, 1997, p. 51-58, IEEE Computer Society.
[COL 00] C OLLET C., « The NODS project : Networked Open Database Services », Proceedings of Symposium on Objects and Databases (ECOOP), LNCS1944, 2000, p. 153-169.
[CON ] C ONSORTIUM O., « Open Source Middleware », http ://www.objectweb.org.
[CRI 91] C RISTIAN F., « Understanding fault-tolerant distributed systems », Communications
of the ACM, vol. 34, n 2, 1991, p. 56-78.
[DRA 02] D RAPEAU S., RONCANCIO C., D ÉCHAMBOUX P., « Design of an Adaptable Replication Service », submitted to publication, 2002.
[GAR 99] G ARTNER F. C., « Fundamentals of Fault-Tolerant Distributed Computing in Asynchronous Environments », ACM Computing Surveys, vol. 31, n 1, 1999, p. 1-26.
[Gar 02a] G ARCÍA -BAÑUELOS L., « An Adaptable Infrastructure for Customized Persistent
Object Management », Proceedings of the EDBT Ph.D. Workshop, 2002.
[Gar 02b] G ARCÍA -BAÑUELOS L., D UONG P.-Q., C OLLET C., « A component-based infrastructure for customized persistent object management », à apparaitre dans les actes des
18èmes Journées Bases de données Avancées, , 2002.
[GRO a] O BJECT M ANAGEMENT G ROUP, « CORBA 2.5 - chapter 25 - Fault Tolerant
CORBA », http ://www.omg.org/cgi-bin/doc ?formal/01-09-29.
[GRO b] T ECHNICAL C OMPONENT M ODEL W ORKING G ROUP, « Fractal component model », http ://www.objectweb.org/architecture/component/index.html.
[JAL 94] JALOTE P., Fault Tolerance in Distributed Systems, Prentice Hall, 1994.
[KAL 99] K ALBARCZYK Z., I YER R. K., BAGCHI S., W HISNANT K., « Chameleon : A
Software Infrastructure for Adaptive Fault Tolerance », IEEE Transactions on Parallel and
Distributed Systems, vol. 10, n 6, 1999, p. 560-579.
[KUL 99] K ULKARNI S., « Component based design of fault-tolerance », PhD thesis, The
Ohio State University, 1999.
[LAM 77] L AMPORT L., « Proving the Correctness of Multiprocess Programs », IEEE Transactions on Software Engineering, vol. 3, n 2, 1977, p. 125-143.
[PAR ] L ABORATOIRE D ’I NFORMATIQUE DE PARIS 6, « Dynamic Agent Replication eXtension », http ://www-src.lip6.fr/darx/.
[REN 01] R EN Y., « AQuA : A Framework for Providing Adaptive Fault Tolerance to Distributed Applications », PhD thesis, University of Illinois at Urbana-Champaign, 2001.
[SOL 00] S OLAR G. V., « Service d’événements flexible pour l’intégration d’applications
bases de données réparties », PhD thesis, Université Joseph Fourier, 2000.
ANNEXE A
Type de fautes
Crash
Omission
Late timing
Value
Byzantine
Informations recueillies pour le diagnostic
Messages périodiques de battement de coeur
Le moment où une requête est délivrée à la couche application et le
message d’acquittement quand la réponse correspondante est envoyée
Le moment où une requête est délivrée à la couche application et le
moment où la réponse correspondante est envoyée
Le message envoyé à d’autres systèmes
Toutes les informations recueillies pour d’autres types de fautes
Tableau 1. Tableau de surveillance (TS)
Type de fautes
Crash
Omission
Late timing
Value
Byzantine
Comment détecter la présence de faute
Si le message de battement de coeur n’a pas été encore reçu, le système
est supposé d’être en crash.
Aucun acquittement n’est reçu à T+ où T
est le moment de la livraison
de la requête à la couche application) et est le temps d’attente pour la
réponse correspondante.
-idemSi la valeur du message sortant est différente de la valeur majoritaire du
même message envoyé par d’autres instances du système, cet instance
a une faute value.
L’intégration des mécanismes de détection des fautes value et des fautes
late timing.
Tableau 2. Tableau de diagnostic (TD)
Nothing/Signaling
Amnesia crash,
X
Unmasking
Mécanismes
Actions à faire
Checkpointing, Journalisa- Revenir au denier point de
tion
sauvegarde (checkpoint)
Partial amnesia crash
Masking
Duplication
(sauf la duplication passive)
Pause crash
X
Halting crash
Omission
X
X
Timing
Value
Byzantine
X
X
X
Duplication passive
X
Activer une réplique passive
X
Duplication passive
Activer une réplique passive
Journalisation (requête, ré- Ré-soumettre la requête au
ponse)
système
X
X
N/A
N/A
Duplication (sauf la duplication passive)
-idem-idem-idemDuplication active avec au moins 3 répliques
-idem-
Tableau 3. Tableau des éléments redondants (TER). X : aucun élément n’est nécessaire, N/A : le cas est invalide