C’est une solution que l’on trouve sur le marché et utilisée par des entreprises comme Google, Yahoo… Cette solution gère la réplication : serveur de coordination et de synchronisation.
ZooKeeper est un service centralisé pour le maintien des informations de configuration, le nommage, la synchronisation distribuée et la fourniture de services de groupe. Tous ces types de services sont utilisés sous une forme ou une autre par des applications distribuées. Même lorsque cela est fait correctement, les différentes implémentations de ces services entraînent une complexité de gestion lorsque les applications sont déployées.
Déploiement sous forme d’un cluster, ensemble de machines.
Aucun intérêt d’avoir un Zookeper sur un seul serveur.
Le but est de savoir si un serveur de la grappe tombe. Mieux, Zookeeper Client gère le failover : il détecte le serveur qui tombe et il répartit les services automatiquement sur les autres serveurs restants.
Une question? Posez-la ici
Le besoin
Exemple sur google, on cherche des informations sur "Consultingit"
Vision développeur : on a un client, un serveur (www.google.fr)
On appelle la méthode « recherche » avec en paramètre « Consultingit.fr »
En arrière plan, Google met à jour son serveur de stats. Ne pas oublier la mise à jour du serveur de stats sur le diagramme de séquences.
Google met à jour l’historique : lorsqu’on tapera ulterieurment U, on aura UPEC…
Il y a plein de mécanismes invisibles : c’est le proxy dynamique, un pattern de conception qui permet d’attraper la requête du client et la rendre transparente.
Idem pour Spring.
Junit utilise aussi un proxy dynamique : il simule certaines invocations pour donner le résultat1
Vocabulaire : objet, objet distribué, objet thread safe
Une question? Posez-la ici
Architecture orientée services/architecture orientée composants
Architecture orientée composants : on gère un contexte
exemple : un client qui veut se connecter à sa banque en ligne. Au moment où le client se connecte, le serveur derrière créée un contexte, une session. Le client met à jour son panier, fait des opération, le serveur met à jour le contexte = architecture statefull . architecture stateless = sans session, contexte, orienté services.
Quelle est la différence entre un objet distribué et une API?
Un objet distribué a besoin d’un protocole pour être interrogé, d’une API.
L’API donne accès à des services : on protège notre objet distribué
On donne au client que l’API justement, pas l’objet distribué.
L’API n’est pas obligatoire, c’est un accès plus simple.
Pattern proxy/ Pattern proxy dynamique
Pattern proxy : on a un client qui requête un objet qui propose un service, exemple dépôt d’argent.
On ne veut pas que le client requête directement la somme à retirer. On veut requêter une classe intermédiaire qui vérifie que la somme à retirer existe bien sur le compte.
C’est une classe intermédiaire qui interroge la classe suivante à la place du client.
Pattern proxy dynamique : par exemple le client requette « retrait d’argent » et le proxy dynamique intercepte la méthode d’une façon transparente.
Il peut etre géré de manière implicite ou explicite
Explicite
le client a les moyens de gérer le proxy, avec retour d’un objet, exemple ContextManager qui permet de démarrer la réplication ou non.
Inconvénient : le client a la responsabilité de la réplication, s’il oublie, ce n’est pas bon.
Implicite
C’est le proxy qui gère la réplication de manière autonome
Handler, objet qui implémente l’interface InvocationHandler qui redefinit la méthode Invoke()
L’objet proxy est crée avec ReplicationInvocationHandler
Diagramme de séquences
Diagramme de séquences avec les 3 acteurs: Terminal1, Service et Server
Ensuite, je peux faire mon...
Diagramme de composants
On a souvent 3 composants : client serveur common
Pour créer le multicast Rest : utilisation de Jersey SSE (qui est utilisé pour faire des radios en ligne par exemple)
Pourquoi Zookeeper ?
Zookeeper est un seveur de coordiation distribué. On l’utilise pour la synchronisation, la sérialisation, et la coordination.
Il gère les réplications de scénarios entre les serveurs. Exemple : Deadlocks. Quand on a 2 threads dans un contexte, il peut y avoir des accès concurrents si les 2 threads accèdent à la ressource en même temps. Grace à Zookeeper (au master leader), on peut modifier la même ressource sans avoir d’exception.
Api très simple
Une simple API permet d’accéder à la dépendance Zookeeper dans notre projet. Cette API contient par exemple des ordres comme read, write.
Zookeeper utilise un design pattern de proxy dynamique pour gérer les différents serveurs. Il y a plusieurs traitements invisibles derrière.
Ce diagramme de séquences nous montre besoin de création du contexte et de réplication du contexte.
Le cluster Zookeeper
On trouve 3 ypes de serveurs, de rôles, dans le cluster zookeeper
Follower à Follower à Leader à follower à Observer
On doit avoir un centre de décision : le leader , c’est celui qui gère l’écriture dans le contexte. Les clients demandent au leader d’écrire dans le contexte. Les followers sont ensuite informés de la mise à jour et répliquent.
Il y a 2 algorithmes :
1) Le FastLeaderElection
ZS1 | ZS2 | ZS3 | ZS4 |
Soit 4 serveurs Zookeepers ZS: quand on démarre par exemple le premier serveur S2, il envoie une requête de découverte. Il vérifie dans sa configuration pour savoir s’il y a un leader. S2 se trouve un peu seul, il prépare donc une requête RequeteNewLeader. On démarre ZS3. ZS3 regarde s’il y a uns erveur : il trouve S2. S2 lui envoie la RequeteNewLeader ; ZS3 accepte et envoie sa réponse sous forme d’un Ack. S4 démarre, il envoie lui aussi sa requete de découverte. S2 et S3 répondent à la réponse de requête. S2 envoie la RequeteNewLeader.
Pré-requis : dans le fichier de configuration, il faut renseigner l’ensemble des serveurs (Adresse IP, plage de ports…)
Règle : c’est le 1er serveur du cluster qui démarre qui se propose Leader.
Tant q’un serveur ne trouve pas d’autres serveurs, il n’envoie pas la requete RequeteNewLeader.
Les followers : ils votent pour savoir qui est le leader. C’est un mécanisme d’élection. Le follower est indépendant ; Quand il a besoin d’interroger une ressource, il interroge le contexte pour les requêtes de lectures.