Apache ZooKeeper est un service de coordination centralisé conçu pour les systèmes distribués. S'appuyant sur un modèle d'observateur, il a pour fonction de stocker et de gérer des données partagées essentielles. Lorsqu'un changement d'état survient sur ces données, ZooKeeper est chargé de notifier les clients qui se sont préalablement enregistrés en tant qu'observateurs, afin qu'ils puissent réagir en conséquence.
Caractéristiques Essentielles
- Architecture Clusterisée : Un déploiement ZooKeeper est généralement composé d'un serveur Leader et de plusieurs Followers.
- Tolérance aux Pannes : Le service demeure opérationnel tant qu'une majorité des nœuds du cluster est active et connectée.
- Cohérence Globale : Chaque serveur maintient une réplique identique des données, assurant que tout client, quel que soit le serveur auquel il se connecte, accède à des informations cohérentes.
- Exécution Séquentielle des Requêtes : Les demandes de mise à jour provenant d'un même client sont traitées et exécutées dans l'ordre où elles ont été émises.
- Opérations Atomiques : Toute modification de données est atomique, c'est-à-dire qu'elle est soit entièrement appliquée, soit pas du tout.
- Réactivité : Les clients sont en mesure de lire les données les plus récentes dans des délais raisonnables.
Structure des Données : Les Znodes
ZooKeeper organise ses données en une structure hiérarchique arborescente, rappelant un système de fichiers. Chaque élément de cette arborescence est désigné sous le terme de "znode". Les znodes peuvent stocker des données (bytes) et posséder des enfants, ce qui permet de modéliser des configurations complexes ou des états de service.
Types de Nœuds (Znodes)
Les znodes se déclinent en plusieurs catégories, chacune ayant des propriétés spécifiques en termes de persistance :
- Znodes Persistants : Ces nœuds existent de manière continue et ne sont supprimés que par une action explicite du client.
- Persistant Standard : Un znode qui reste présent indéfiniment.
- Persistant Séquentiel : Un znode persistant dont le nom est complété par un numéro de séquence unique et monotone croissant, attribué par ZooKeeper.
- Znodes Éphémères : Ces nœuds sont automatiquement détruits lorsque la session du client qui les a créés se termine (par déconnexion, expiration de session, etc.).
- Éphémère Standard : Un znode temporaire lié à la durée de vie de la session client.
- Éphémère Séquentiel : Combine les propriétés éphémères et séquentielles, utile pour gérer des listes de processus actifs ou des verrous distribués ordonnés.
Le numéro de séquence est un identifiant unique pour les znodes séquentiels, géré par le znode parenet. Il est crucial pour assurer un ordre global des événements dans les systèmes distribués.
Interprétation des Paramètres de Configuration (zoo.cfg)
Le fichier de configuration principal de ZooKeeper, zoo.cfg, contient des paramètres essentiels pour le fonctionnement du cluster :
tickTime = 2000: Définit l'unité de temps de base de ZooKeeper en millisecondes (ici, 2 secondes). Il est utilisé pour les battements de cœur et pour calculer les délais d'expiration des sessions.initLimit = 10: Multiplicateur detickTime, il spécifie le délai maximum pendant lequel les Followers peuvent se connecter et se synchroniser avec le Leader lors du démarrage initial. Le délai total estinitLimit * tickTime.syncLimit = 5: Également un multiplicateur detickTime, il détermine la durée maximale pendant laquelle un Follower peut être désynchronisé du Leader après l'initialisation. Un Follower qui dépasse ce seuil est considéré comme défaillant. Le délai total estsyncLimit * tickTime.dataDir = /chemin/vers/les/donnees/zookeeper: Indique le répertoire où ZooKeeper stocke les instantanés de ses données (snapshots) et ses journaux de transactions.clientPort = 2181: Le port TCP sur lequel le serveur ZooKeeper écoute les requêtes des clients.
Configuration d'un Cluster ZooKeeper
Pour mettre en place un cluster ZooKeeper, quelques configurations spécifiques sont requises pour chaque nœud :
- Fichier
myid: Chaque serveur ZooKeeper doit avoir un fichier nommémyid, situé dans le répertoire spécifié pardataDir. Ce fichier doit contenir un identifiant numérique unique (par exemple, '1', '2', '3') pour ce serveur au sein du cluster. - Paramètres de Cluster : Le fichier
zoo.cfgde chaque serveur doit inclure les informations de tous les serveurs du cluster, sous le format suivant : ``` server.ID=adresse_IP:port_inter_serveur:port_élection- `ID` : Correspond à l'identifiant numérique du serveur (celui dans le fichier `myid`). - `adresse_IP` : L'adresse IP ou le nom d'hôte du serveur. - `port_inter_serveur` : Le port utilisé par les Followers pour se connecter au Leader et échanger des données. - `port_élection` : Le port dédié à la communication entre les serveurs lors du processus d'élection du Leader.
Opérations Courantes via le Client en Ligne de Commande
Le script zkCli.sh permet d'interagir directement avec ZooKeeper :
Démarrer le client
bin/zkCli.sh
Afficher la liste des commandes disponibles
help
Lister le contenu d'un znode
Pour voir les enfants d'un znode :
ls /
ls /applications
Pour obtenir plus de détails sur le znode lui-même et ses enfants :
ls2 /applications/serviceX
Créer des znodes
Pour créer des znodes persistants avec des données :
create /configurations "Donnees de configuration generales"
create /configurations/dev "Environnement de developpement"
Pour créer un znode éphémère (supprimé à la déconnexion du client) :
create -e /sessions/client_A "ID_session_12345"
Pour créer un znode séquentiel (ZooKeeper ajoute un suffixe numérique) :
create -s /taches_en_attente/job_ "Traitement_fichier_X"
Exemple de nom généré : /taches_en_attente/job_0000000000
Obtenir les données d'un znode
get /configurations/dev
Cette commande renvoie les données stockées et les métadonnées du znode.
Modifier les données d'un znode
set /configurations/dev "Nouvelles donnees de configuration"
Mettre en place un Watcher (Observateur) sur les données
Un watcher est une notification unique déclenchée par un changement. Pour surveiller les données d'un znode :
get /configurations/dev watch
Si un autre client exécute set /configurations/dev "MiseAJour", le client avec le watcher recevra une notification comme :
WATCHER::WatchedEvent state:SyncConnected type:NodeDataChanged path:/configurations/dev
Mettre en place un Watcher sur les enfants d'un znode
Pour surveiller l'ajout ou la suppression d'enfants d'un znode :
ls /configurations watch
Si un autre client exécute create /configurations/test "info_test", le client avec le watcher recevra une notification comme :
WATCHER::WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/configurations
Supprimer un znode
Supprime un znode s'il n'a pas d'enfants :
delete /configurations/test
Supprime un znode et tous ses enfants de manière récursive :
rmr /configurations
Consulter les métadonnées détaillées d'un znode (stat)
stat /configurations/dev
Les informations affichées incluent :
cZxid: L'ID de la transaction qui a créé ce znode.ctime: L'heure de création du znode en millisecondes (depuis l'époque Unix).mZxid: L'ID de la transaction de la dernière modification des données de ce znode.mtime: L'heure de la dernière modification des données du znode en millisecondes.pZxid: L'ID de la transaction de la dernière modification des enfants de ce znode.cversion: Le nombre de modifications apportées aux enfants de ce znode.dataVersion: Le nombre de modifications apportées aux données de ce znode.aclVersion: Le nombre de modifications apportées à la liste de contrôle d'accès (ACL) de ce znode.ephemeralOwner: L'ID de session du client propriétaire si le znode est éphémère (0 si persistant).dataLength: La longueur des données stockées dans le znode.numChildren: Le nombre d'enfants directs du znode.
Principe des Observateurs (Watchers)
Le système de watchers de ZooKeeper est un mécanisme de notification asynchrone. Lorsqu'un client s'abonne à un événement sur un znode (changement de données ou de liste d'enfants), le serveur ZooKeeper maintient cette souscription. Dès que l'événement surveillé se produit, le serveur envoie une notification unique au client via une connexion dédiée. Cette approche basée sur la "poussée" de l'information diffère des systèmes qui exigent un "polling" (interrogation répétée) de la part du client pour détecter les changements.
Flux d'Opération pour les Écritures
Lorsqu'un client initie une opération d'écriture (par exemple, create, set, delete), la requête est envoyée à un serveur ZooKeeper. Si ce serveur n'est pas le Leader actuel, il transmet la requête au Leader. Le Leader exécute la transaction localement, puis diffuse cette modification à tous les Followers. L'opération n'est considérée comme validée et persistante qu'une fois qu'une majorité des nœuds du cluster (le quorum) a confirmé avoir appliqué la transaction. Ce mécanisme garantit la durabilité et la cohérence des données dans l'environnement distribué.
Processus d'Élection du Leader
À l'initialisation d'un cluster ZooKeeper ou en cas de défaillance du Leader en exercice, les serveurs restants lancent un processus d'élection pour désigner un nouveau Leader. Ce processus est régi par le protocole Zab (ZooKeeper Atomic Broadcast), qui assure l'accord entre les serveurs sur l'état du système et l'identité du Leader. Chaque serveur propose un candidat en fonction des transactions les plus récentes qu'il a traitées. Le candidat qui obtient une majorité de votes parmi le quorum est alors promu Leader.