• Aucun résultat trouvé

Partie III – Mise en œuvre et évaluation 101

8.1.1 Architecture logicielle générale

8.1.3 Les mécanismes de tolérance aux fautes . . . 108

8.2 Mise en œuvre d’un protocole de cohérence hiérarchique . . . 109

8.2.1 Mise en œuvre sur le client . . . 110 8.2.2 Mise en œuvre sur les fournisseurs . . . 111 8.2.3 Fonctionnement . . . 112

8.3 Mise en œuvre des groupes auto-organisants . . . 113

8.3.1 Mise en place de la réplication . . . 113 8.3.2 Auto-organisation des groupes . . . 115

8.4 Un protocole étendu pour une visualisation efficace . . . 116

8.4.1 La lecture relâchée . . . 116 8.4.2 Fenêtre de lecture . . . 117 8.4.3 Analyse de la sémantique des paramètres . . . 117

8.5 Analyse . . . 118

L’architecture en couches permettant une gestion conjointe de la tolérance aux fautes et de la cohérence des données présentée dans le chapitre 6 a été mise en œuvre au sein du service de partage de données JUXMEM [129]. Une mise en œuvre de protocoles de cohé-rence hiérarchiques tolérants aux fautes suivant le modèle décrit au chapitre 7 a également été réalisée au sein de cette architecture.

Deux thèses (celle de Mathieu Jan et celle-ci) ainsi que trois stages de master recherche deuxième année ont contribué au développement du service de partage de données JUX -MEM. Le prototype mettant en œuvre JUXMEMcorrespond à plus de 16 700 lignes de code Java et plus de 13 500 lignes de code C, dont environ 7 300 lignes de code Java et 6 100 lignes de code C pour la gestion de la cohérence des données et de la tolérance aux fautes.

Dans ce chapitre, nous nous focalisons sur la mise en œuvre de notre contribution. La section 8.1 décrit la mise en œuvre de l’architecture en couches présentée dans le chapitre 6 et les sections 8.2 et 8.3 présentent respectivement un exemple de mise en œuvre d’un protocole de cohérence et un exemple de mise en œuvre de la couche de tolérance aux fautes au sein de cette architecture. Enfin dans la section 8.4, nous nous intéressons à une extension du protocole de cohérence présenté dans la section 8.2 offrant aux applications la possibilité d’effectuer des observations efficaces d’une donnée partagée.

8.1 Mise en œuvre de l’architecture en couches

Le rôle de l’architecture en couches est de découpler la gestion de la tolérance aux fautes de la gestion de la cohérence des données. Cela permet d’une part de pouvoir se concentrer sur un problème unique lors de la mise en œuvre des différentes couches et d’autre part d’offrir différentes implémentations de chacune des couches. Grâce à ce dernier point, notre prototype peut offrir aux applications le choix parmi un éventail de combinaisons.

8.1.1 Architecture logicielle générale

Pour clarifier notre présentation, nous considérons que chaque nœud physique héberge un seul pair JUXMEM. Nous considérons également que chaque pair JUXMEMne joue qu’un seul rôle au sein de la plate-forme, c’est-à-dire que chaque pair est soit client, soit fournis-seur, soit gestionnaire1. Ces différents rôles sont décrits en détail dans la section 6.1. Les pairs clients sont liés aux processus applicatifs et permettent d’accéder aux données par-tagées présentes au sein du service JUXMEM. Les pairs fournisseurs sont quant à eux res-ponsables du stockage des copies des données partagées. Toujours à des fins de clarté, nous nous focalisons ici sur une seule donnée, même si les clients peuvent accéder à plusieurs données partagées, et que les fournisseurs peuvent stocker des copies de plusieurs données différentes.

Instantiation des couches sur les pairs JUXMEM. Pour chaque donnée partagée à laquelle il accède, un client doit instancier la partie client du protocole de cohérence choisi ainsi qu’une couche de tolérance aux fautes, c’est-à-dire la pile logicielle représentée par la fi-gure 8.1. Le rôle de chacune des couches de cette pile logicielle est décrit au chapitre 6. Le protocole de cohérence utilise la couche de tolérance aux fautes via la couche de jonction afin de communiquer avec la copie de référence répliquée sur des pairs fournisseurs.

Chaque donnée stockée au sein du service JUXMEMest répliquée, c’est-à-dire qu’elle est présente en plusieurs exemplaires. Nous avons décrit au chapitre 7 notre architecture hiérar-chique pour la réplication et la gestion de la cohérence. Chaque donnée fait donc intervenir 1Notre implémentation permet cependant d’exécuter plusieurs pairs sur un même nœud physique, et chaque pair peut jouer chacun des rôles, simultanément, ou à tour de rôle.

8.1 – Mise en œuvre de l’architecture en couches 105

Protocole de cohérence (client)

Couche de jonction

Client SOG

(couche de tolérance aux fautes)

FIG. 8.1 – Pile logicielle instanciée sur les pairs clients pour chaque donnée partagée à la-quelle le client accède.

plusieurs pairs fournisseurs. Les pair fournisseurs hébergeant des copies d’une même don-née et appartenant à une même grappe (groupeclusterJUXMEM) forment unLocal Data Group

(LDG) qui est responsable d’une copie de référence locale. L’ensemble des LDG forme le Glo-bal Data Group(GDG) qui est responsable de la copie de référence globale (voir chapitre 7). Le LDG est un groupe dont les membres sont eux-mêmes des groupes, c’est donc un groupe de groupes. Chaque pair fournisseur hébergeant une copie d’une donnée appartient à un LDGetchaque LDG appartient à un GDG. Pour chaque donnée, les deux piles logicielles représentées par la figure 8.2 doivent être instanciées surtousles pairs fournisseurs qui en hébergent une copie. Un exemple de groupe hiérarchique de fournisseurs formant un GDG comprenant deux LDG est illustré par la figure 8.3.

(copie de référence locale)

Couche de communication de groupe Couche d’adaptation aux fautes

Couche de jonction

Groupe auto−organisant (SOG) global Protocole de cohérence niveau GDG

Couche de communication de groupe Couche d’adaptation aux fautes

Couche de jonction Protocole de cohérence niveau LDG

Groupe auto−organisant (SOG) local

GDG LDG

(copie de référence globale)

FIG. 8.2 – Piles logicielle instanciée sur les pairs fournisseurs pour chaque donnée qu’ils hébergent.

Client

Pile logocielle coté client

GDG c

Grappe A

Grappe B

c

Piles logicielles des fournisseurs GDG (G) et LDG (L) G L G L G L G L G L LDG A LDG B G L

FIG. 8.3 – Aperçu de l’architecture logicielle : un client et un GDG composé de deux LDG eux-mêmes composés de 2 à 3 pairs fournisseurs.

8.1.2 Les protocoles de cohérence

Les processus applicatifs utilisent l’interface de JUXMEMlors des accès aux données par-tagées. Cette dernière utilise alors l’interface offerte par les protocoles de cohérence2, repré-sentée par le listing 8.1.

Listing 8.1 – Interface des protocoles de cohérence des clients JUXMEM.

1 ...

2 /* l’objet peer est éutilis pour éaccder aux fonctions du noyau JuxMem */

3 Jxta_id* cp_alloc(JuxMem_peer* peer, Jxta_vector* local_provider_ids,

4 Jxta_vector* remote_provider_ids,

5 Jxta_id** provider_comm_id, long size,

6 int cp_type, int sog_type);

7 consistency_protocol* consistency_protocol_open(JuxMem_peer* peer,

8 Jxta_id* data_id,

9 Jxta_id* provider_comm_id,

10 long size, char* localkey,

11 void* attributes);

12 /* self éreprsent le protocole de écohrence */

2Pour une donnée particulière, un seul protocole de cohérence est employé. Cependant, pour un même client, des protocoles de cohérence différents peuvent être utilisés pour des données différentes.

8.1 – Mise en œuvre de l’architecture en couches 107

13 void consistency_protocol_close(consistency_protocol* self);

14 int cp_flush(consistency_protocol* self, void* ptr, size_t size,

15 Jxta_message_element* msg_element_localkey);

16 int cp_acquire(consistency_protocol* self, void* ptr, size_t size,

17 Jxta_message_element* msg_element_localkey);

18 int cp_release(consistency_protocol* self, void* ptr, size_t size,

19 Jxta_message_element* msg_element_localkey);

20 int cp_acquire_read(consistency_protocol* self, void* ptr, size_t size,

21 Jxta_message_element* msg_element_localkey);

22 int cp_get_state(consistency_protocol* self);

23 ...

Les protocoles de cohérence doivent donc définir ces différentes primitives. Les primitives cp_acquireetcp_acquire_readsont appelées avant chaque entrée dans une section de code contenant des accès à la donnée :cp_acquirelorsque les accès sont en lecture/écriture etcp_ acquire_readlorsqu’ils sont en lecture seule. La primitivecp_releaseest appelée à la sortie des sections de code contenant des accès à la donnée. Les autres primitives sont utilisées par l’interface de JUXMEMpour propager les écritures à la copie de référence locale (cp_flush) ou pour connaître l’état du protocole de cohérence (cp_get_state). Pour mettre en œuvre ces primitives, les protocoles de cohérence utilisent les fonctions de l’interface de la couche de jonction dont un extrait est présenté dans le listing 8.2.

Listing 8.2 – Interface de communication offerte par la couche de jonction.

1 ...

2 /* self éreprsente ici la couche de jonction */

3 int send_lock_request(client_grp_comm* self, Jxta_message* message);

4 int send_lock_read_request(client_grp_comm* self, Jxta_message* message);

5 int send_unlock_request(client_grp_comm* self, Jxta_message* message);

6 int send_unlock_read_request(client_grp_comm* self, Jxta_message* message);

7 int send_read_request(client_grp_comm* self, Jxta_message* message);

8 int send_update_request(client_grp_comm* self, Jxta_message* message);

9 int send_reset_ack(client_grp_comm* self, Jxta_message* message);

10 int set_cp_handler(client_grp_comm* self, consistency_protocol* cp);

11 ...

Il est intéressant de remarquer que ces fonctions ne prennent pas en paramètre l’iden-tifiant du destinataire du message. En effet, le destinataire est un groupe de copies dont les membres sont susceptibles de changer au cours du temps, lors d’occurrences de fautes. L’identifiant du groupe est inconnu au niveau de cette couche. La localisation du groupe et les communications avec ce groupe sont donc à la charge de la couche de tolérance aux fautes dont un exemple de mise en œuvre est décrit à la section 8.3. Il n’est par conséquent pas nécessaire de connaître ni la localisation, ni la composition du LDG/GDG au niveau du protocole de cohérence.

Le protocole de cohérence client doit également définir la manière dont il réagit aux réponses du LDG. Pour ce faire, il doit mettre en œuvre les fonctions du listing 8.3 appelées par la couche de jonction lors de la réception d’un message de ce dernier.

Listing 8.3 – Fonctions du protocole de cohérence client appelées lors de la réception d’un message de la copie de référence locale.

1 ...

2 /* self éreprsente ici le protocole de écohrence */

4 Jxta_message* message);

5 void recv_lock_read_ack(consistency_protocol* self, Jxta_id* sender,

6 Jxta_message* message);

7 void recv_unlock_ack(consistency_protocol* self, Jxta_id* sender,

8 Jxta_message* message);

9 void recv_unlock_read_ack(consistency_protocol* self, Jxta_id* sender,

10 Jxta_message* message);

11 void recv_update_ack(consistency_protocol* self, Jxta_id* sender,

12 Jxta_message* message);

13 void recv_read_ack(consistency_protocol* self, Jxta_id* sender,

14 Jxta_message* message);

15 void recv_reset_request(consistency_protocol* self, Jxta_id* sender,

16 Jxta_message* message);

17 ...

La partie des protocoles de cohérence mise en œuvre au niveau de la copie de référence locale, sur les pairs fournisseurs doit implémenter les fonctions miroirs (recv_∗pour chacun dessend_∗) qui seront appelées par la couche de jonction. Elle utilise de plus une interface semblable à celle du listing 8.2 afin d’émettre des requêtes à la copie de référence globale.

De la même manière, la copie de référence globale doit implémenter les fonctionsrecv_∗

pour chacune des requêtes émises par les copies de référence locales. À ce niveau égale-ment, la couche de jonction propose des fonctions du typesend_∗permettant à la copie de référence globale de répondre aux requêtes des copies de référence locales.

Au niveau de l’implémentation d’un protocole de cohérence, la tolérance aux fautes est rendue invisible grâce à ces interfaces. En effet, le protocole de cohérence utilise les fonctions send_∗ et recv_∗de la couche de jonction, masquant la localisation et la composition des groupes pour les communications entre les clients, les copies de références locales et la copie de référence globale. Ces trois entités d’un protocole de cohérence implémentent le protocole de cohérence hiérarchique en mettant en œuvre des automates à états semblables à ceux présentés dans le chapitre 5. Un exemple de mise en œuvre est donnée à la section 8.2.