ZooKeeper pour Solr : principes, installation et supervision

Lors de la mise en place d’un cluster SolrCloud, la présence d’un ensemble Zookeeper fonctionnel est indispensable. Un ensemble Zookeeper désigne un groupe de serveurs coordonnés assurant ensemble la gestion de la configuration distribuée et la coordination des nœuds Solr.

Cet article présente le rôle essentiel de Zookeeper dans l’architecture SolrCloud, explique son principe de fonctionnement, détaille les étapes d’installation d’un ensemble Zookeeper ainsi que les métriques à superviser. Enfin, les bonnes pratiques à respecter pour garantir la fiabilité et la résilience de l’ensemble sont également abordées.

Rôle de Zookeeper dans un système distribué

ZooKeeper est un projet open source de la fondation Apache conçu pour faciliter la coordination et la synchronisation des composants au sein d’un système distribué.

ZooKeeper repose sur une base de données hiérarchique de type clé/valeur, dans laquelle les clés sont représentées par des chemins (à la manière d’un système de fichiers) et les valeurs appelées znodes. Chaque znode peut contenir des métadonnées ainsi que, facultativement, un contenu (souvent un fichier de configuration ou un statut).

Les nœuds d’un système distribué interagissent avec ZooKeeper pour lire ou écrire des informations essentielles au bon fonctionnement du cluster. Pour SolrCloud par exemple, cela inclut, les fichiers de configuration des collections, ainsi que les fichiers de statut relatifs aux nœuds ou aux shards.

Au-delà de Solr, ZooKeeper est également utilisé dans de nombreux projets distribués majeurs tels que :

ZooKeeper est ainsi un composant incontournable des principales distributions Big Data comme Cloudera.

Pour garantir une haute disponibilité, un ensemble ZooKeeper est généralement composé de 3 ou 5 nœuds répliqués, ce qui permet de tolérer des défaillances tout en maintenant le quorum. Cette résilience est critique : si un ensemble ZooKeeper devient indisponible, c’est l’ensemble des systèmes distribués qui en dépendent qui deviennent inopérants. Le choix entre 3 ou 5 nœuds dépend du besoin de tolérance aux pannes : seuls 5 nœuds permettent de supporter l’indisponibilité de 2 membres simultanément et donc pouvoir tolérer par exemple la panne d’un nœud lors de l’arrêt pour maintenance d’un autre nœuds.

Fonctionnement de Zookeeper dans un environnement SolrCloud

Dans un cluster SolrCloud, ZooKeeper joue un rôle central en assurant la cohérence de la configuration et l’état du cluster entre tous les nœuds Solr. Chaque nœud Solr se connecte à l’un des membres de l’ensemble ZooKeeper, généralement un follower et envoie régulièrement des pings pour signaler qu’il est actif. En retour, le serveur ZooKeeper répond pour confirmer sa propre disponibilité. Si un nœud ne reçoit pas de réponse, il tente automatiquement de se reconnecter à un autre membre de l’ensemble.

ZooKeeper conserve l’intégralité de ses données en mémoire, ce qui rend les lectures très rapides et sans accès disque. Lorsqu’un client effectue une écriture (par exemple une mise à jour de configuration), celle-ci est d’abord transmise au leader de l’ensemble ZooKeeper, qui se charge de la propager aux autres membres (les followers) via un mécanisme de consensus.

Un point clé du fonctionnement de ZooKeeper est la mise à jour synchrone des membres de l’ensemble, ainsi, toutes les lectures par les clients sont bloquées tant que l’écriture n’a pas été enregistrée sur disque par tous les membres (dans leur journal de transaction ou transaction log). Cela garantit une forte cohérence, mais au prix d’une latence accrue lors des opérations d’écriture.

Cependant, dans la pratique, les clients ne lisent pas en permanence dans ZooKeeper. Ils maintiennent en mémoire un cache des données et sont automatiquement notifiés de toute modification via un mécanisme de watchers. Cela permet de limiter la charge sur ZooKeeper lors des opérations courantes.

Les types de données que Solr stocke dans ZooKeeper incluent :

  • Les configurations globales : fichiers liés à l’autoscaling, à la sécurité (security.json), etc.
  • Les configurations de collections : schémas, solrconfig.xml, etc.
  • L’état des collections : state.json, information sur les leaders, routing, etc.
  • L’état des nœuds Solr : nœuds actifs (live_nodes), rôle d’overseer, etc.

Cas où des écritures sont réalisées dans ZooKeeper :

  • Lors du démarrage ou de l’arrêt d’un nœud Solr.
  • Lors de l’envoi ou de la mise à jour d’une configuration de collection.
  • Lors d’une opération sur une collection : création, suppression, modification (quasi toutes les opérations via les API Collections, Core ou Config).

Cas où aucune écriture n’est réalisée dans ZooKeeper :

  • Création d’un objet client SolrJ (lecture uniquement).
  • Indexation de documents (via SolrJ, API HTTP ou DataImportHandler).
  • Recherche de documents.

Cas où des lectures sont réalisées dans ZooKeeper :

  • Création d’un client SolrJ.
  • Démarrage d’un nœud Solr.
  • Notification de changement via un watch déclenché par ZooKeeper.

Ces éléments permettent d’identifier les cas susceptibles de générer une charge importante sur l’ensemble ZooKeeper, notamment :

  • La présence d’un grand nombre de nœuds Solr (démarrages/arrêts fréquents, pings, reconfigurations).
  • Une utilisation intensive des APIs de gestion des collections (création, suppression, resharding, etc.).

À l’inverse, dans un environnement SolrCloud stable où les collections évoluent peu et où seules des opérations d’indexation ou de recherche sont effectuées, ZooKeeper est relativement peu sollicité. Zookeeper n’intervient pas lors des opérations d’indexation et de recherche par les data nodes de Solr et donc Zookeper n’est pas un goulot d’étranglement des performances de Solrcloud.

Installation de Zookeeper

Pré-requis

Logiciel

Zookeeper est une application Java. Le seul vrai pré-requis est de disposer d’un environnement Java 1.8 ou supérieur (JDK 8 LTS, JDK 11 LTS, JDK 12 – Java 9 et 10 ne sont pas supportés).

Hardware

Zookeeper ne requiert pas des serveurs très puissants, les caractéristiques de base conseillées afin de supporter une grande majorité de cas d’usages sont généralement ceux indiqués ci-dessous. Il va de soi que selon l’usage réel de SolrCloud, le monitoring des serveurs Zookeeper (CPU, espace disque, JVM, …) doit amener à adapter ces caractéristiques.

  • Processeurs dual-core ou quad-core
  • 2 Go de RAM
  • 80 Go d’espace disque
  • des I/O disques très performantes en écriture
  • un réseau gigabits très performant avec une très faible latence entre les membres de l’ensemble Zookeeper et les nœuds Solr

Bonnes pratiques

L’ensemble Zookeeper est un point critique de la stabilité et des performances de SolrCloud. Pour atteindre cette objectif, les bonnes pratiques impératives sont :

  • Utiliser des serveurs dédiés
  • Désactiver le swap des serveurs (vm.swappiness=1)
  • Augmenter la limite « nofile » à 8192 (1024 par défaut) dans « /etc/security/limits.conf »
  • Rendre Zookeeper indépendant des DNS en utilisant le fichier « /etc/hosts »
  • Allouer à la mémoire heap de Zookeeper au maximum la quantité de mémoire disponible moins 1 Go. Dans la pratique, une Heap de 512 Mo doit couvrir les besoins. Il faut monitorer la JVM et ses GC afin de valider la bonne taille de heap.
  • Utiliser des volumes disques distincts pour les données et les logs de transaction (paramètres dataDir et dataLogDir dans zoo.cfg)
  • Activer les logs de GC de la JVM et les analyser régulièrement avec le site gceasy.io
  • Installer des outils de monitoring du système (CPU, I/O disques, …) afin d’en contrôler le bon fonctionnement et les performances du système. Nous préconisons « sar » qui fait parti du package sysstat

Installation 

Il s’agit d’une procédure d’installation sur la base de 3 membres.

Cette opération est à répéter sur chaque serveur de l’ensemble.

  • créer un utilisateur zookeeper
$ sudo useradd zookeeper
  • mettre en place le fichier /etc/hosts avec le contenu suivant. Le but est d’être totalement indépendant des DNS (pannes ou configuration)
xxx.xxx.xxx.xx1 zk1
xxx.xxx.xxx.xx2 zk2 
xxx.xxx.xxx.xx3 zk3 
  • extraire l’archive dans /opt/zookeeper-3.x.x et créer un lien symbolique générique “/opt/zookeeper” indépendant de la version. Les mises à jours seront plus faciles
$ cd /opt
$ sudo tar xzf apache-zookeeper-3.x.x-bin.tar.gz
$ sudo ln -s apache-zookeeper-3.x.x-bin zookeeper
$ sudo chown -R zookeeper: apache-zookeeper-3.x.x-bin
  • créer des répertoires pour les données, les logs de transactions et les logs de Zookeeper sur des volumes si possible distincts
$ sudo mkdir /<volume_dedie_aux_donnees>/zookeeper-data
$ sudo mkdir /<volume_dedie_aux_logs_de_transaction>/zookeeper-data-log 
$ sudo mkdir /var/log/zookeeper
$ sudo chown -R zookeeper: /<volume_dedie_aux_donnees>/zookeeper-data /<volume_dedie_aux_logs_de_transaction>/zookeeper-data-log /var/log/zookeeper
  • créer le fichier de configuration “/opt/zookeeper/conf/zoo.cfg” avec le contenu suivant. Il s’agit des paramètres par défaut conseillés avec notamment la distinction des volumes pour les données et les logs de transaction et également l’activation de la purge automatique des données.
tickTime=2000
initLimit=5
syncLimit=2
dataDir=//zookeeper-data/
dataLogDir=//zookeeper-data-log/ 
clientPort=2181
4lw.commands.whitelist=mntr,conf,ruok
autopurge.snapRetainCount=10
autopurge.purgeInterval=24
server.1=zk1:2888:3888
server.2=zk2:2888:3888
server.3=zk3:2888:3888
  • Créer un fichier myid dans le répertoire data. Ce fichier ne contient uniquement une ligne qui est le numéro de l’instance Zookeeper qui utilise ce répertoire de données (un chiffre de 1 à 255).
cd /opt
echo 1 > /<volume_dedie_aux_donnees>/zookeeper-data/myid

L’id 1 est à remplacer par 2, 3, … n sur chacun des serveurs

  • mettre en place le fichier d’initialisation “/opt/zookeeper/conf/zookeeper-env.sh” avec le contenu suivant. Contrairement à zoo.cfg, ce fichier est relatif à la configuration de la JVM et des logs. Il permet également de pallier un problème de conservation des logs de la JVM lors des redémarrages. Les logs des JVM sont en rotation avec une taille de 20 Mo par fichier et un historique de 10 fichiers. Ces valeurs peuvent être adaptées.
    Si une version de JVM supérieur à 9 est détectée, le garbadge collector choisi est le G1GC.
if [[ -n "$JAVA_HOME" ]] && [[ -x "$JAVA_HOME/bin/java" ]];  then    JAVA="$JAVA_HOME/bin/java"

elif type -p java; then
    JAVA=java
else
    echo "Error: JAVA_HOME is not set and java could not be found in PATH." 1>&2
    exit 1
fi
JAVA_VER=$("$JAVA" -version 2>&1)
JAVA_VER_NUM=$(echo $JAVA_VER | head -1 | awk -F ‘"‘ ‘/version/ {print $2}’ | sed -e’s/^1\.//’ | sed -e’s/[._-].*$//’)
echo "Java version $JAVA_VER_NUM"
 
# Configure Log 
ZOO_LOG_DIR="/opt/zookeeper/log" 
ZOO_LOG4J_PROP="WARN, ROLLINGFILE" 
ZOO_GC_LOG_DIR="$ZOO_LOG_DIR" 
 
# Configure mémoire JVM selon la mémoire disponible
SERVER_JVMFLAGS="-Xmx512m"
 
# Configure JMX (enabled by default for local monitoring by PID)
JMXDISABLE=true
JMXPORT=10900
 
# Configure JVM GC and log 
if [[ "$JAVA_VER_NUM" -lt "9" ]] ; then
	SERVER_JVMFLAGS="$SERVER_JVMFLAGS -verbose:gc -XX:+PrintHeapAtGC -XX:+PrintGCDetails -XX:+PrintGCDateStamps" 
	SERVER_JVMFLAGS="$SERVER_JVMFLAGS -XX:+PrintGCTimeStamps -XX:+PrintTenuringDistribution -XX:+PrintGCApplicationStoppedTime"
	SERVER_JVMFLAGS="$SERVER_JVMFLAGS -Xloggc:$ZOO_GC_LOG_DIR/zookeeper-gc.log" 
	SERVER_JVMFLAGS="$SERVER_JVMFLAGS -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=20M" 
else
	# Use G1GC
	SERVER_JVMFLAGS="$SERVER_JVMFLAGS -XX:+UseG1GC -XX:MaxGCPauseMillis=100″
	SERVER_JVMFLAGS="$SERVER_JVMFLAGS -Xlog:gc*:file=$ZOO_GC_LOG_DIR/zookeeper-gc.log:time,uptime:filecount=10,filesize=20M"
fi


# Backup des logs GC au démarrage (sinon ils sont perdus)
if [ "x$1" = "xstart" ]; then
    for f in $ZOO_GC_LOG_DIR/zookeeper-gc.log*; do
        ## Check if the glob gets expanded to existing files.
        ## If not, f here will be exactly the pattern above
        ## and the exists test will evaluate to false.
        if [ -e "$f" ] ; then
            echo "GC log files found – backing up"
            d=$PWD && cd $ZOO_GC_LOG_DIR && tar czf zookeeper-gc.$(date +%Y%m%d-%H%M%S).tgz zookeeper-gc.log* && cd $d
        else
            echo "No GC log files found"
        fi
        ## This is all we needed to know, so we can break after the first iteration
        break
    done
fi
  • Mettre en place le fichier de configuration des logs “/opt/zookeeper/conf/log4j.properties” avec le contenu suivant. Les logs sont en rotation avec une taille de 20 Mo par fichier et un historique de 10 fichiers. Ces valeurs peuvent être adaptées.
# Define some default values that can be overridden by system properties
zookeeper.root.logger=INFO, LOGFILE
zookeeper.console.threshold=INFO
zookeeper.log.dir=.
zookeeper.log.file=zookeeper.log
zookeeper.log.threshold=DEBUG
zookeeper.tracelog.dir=.
zookeeper.tracelog.file=zookeeper_trace.log

#
# ZooKeeper Logging Configuration
#

# Format is " (, )+

# DEFAULT: console appender only
log4j.rootLogger=${zookeeper.root.logger}

#
# Log to the console
#
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.Threshold=${zookeeper.console.threshold}
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} [myid:%X{myid}] - %-5p [%t:%C{1}@%L] - %m%n

# Add ROLLINGFILE to rootLogger to get log file output
log4j.appender.ROLLINGFILE=org.apache.log4j.RollingFileAppender
log4j.appender.ROLLINGFILE.Threshold=${zookeeper.log.threshold}
log4j.appender.ROLLINGFILE.File=${zookeeper.log.dir}/${zookeeper.log.file}
log4j.appender.ROLLINGFILE.MaxFileSize=20MB
log4j.appender.ROLLINGFILE.MaxBackupIndex=10
log4j.appender.ROLLINGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.ROLLINGFILE.layout.ConversionPattern=%d{ISO8601} [myid:%X{myid}] - %-5p [%t:%C{1}@%L] - %m%n

Repositionner le bon propriétaire des fichiers de configuration

$ sudo chown -R zookeeper: /opt/zookeeper/conf

Mertre en place de Service Unit File SystemD

[Unit]
Description=Zookeeper Daemon
Documentation=http://zookeeper.apache.org
Requires=network.target
After=network.target

[Service]
Type=forking
WorkingDirectory=/opt/zookeeper
User=root
Group=root
ExecStart=/opt/zookeeper/bin/zkServer.sh start /opt/zookeeper/conf/zoo.cfg
ExecStop=/opt/zookeeper/bin/zkServer.sh stop /opt/zookeeper/conf/zoo.cfg
ExecReload=/opt/zookeeper/bin/zkServer.sh restart /opt/zookeeper/conf/zoo.cfg
TimeoutSec=30
Restart=on-failure

[Install]
WantedBy=default.target

Démarrer chaque serveur de l’ensemble

$ systemctl start zookeeper

Monitoring de Zookeeper

Préparation et configuration

Afin de pouvoir réaliser une monitoring de Zookeeper complet, nous pouvons utiliser plusieurs sources d’information :

  • Les logs de la JVM de Zookeeper pour contrôler les GC
  • Les métriques systèmes au moyen du node-exporter Prometheus
  • Les données fournies pas la JVM de Zookeeper au moyen du JMX exporter de Prometheus
  • Les métriques Zookeeper au moyen du Zookeeper exporter de Prometheus

Les métriques obtenus sont exploitables sous forme de graphes et d’alertes dans Prometheus et Grafana. Je ne reviens pas ici sur l’installation de ces composants car je l’ai déjà fait dans cet article « Monitoring SolrCloud avec Prometheus et Grafana« .

Pour les exemples de requêtes Prometheus indiquées ci-dessous, les serveurs Zookeeper se nomment zk1, zk2 et zk3.

Les exporters sont configurés pour utiliser les ports suivants :

  • node-exporter : 9100
  • jmx-exporter : 7070
  • zk-exporter : 7080

Les log des garbages collections de la JVM

Ces logs ne sont pas utilisés pour monitorer directement le fonctionnement de la JVM, mais ils permettent d’obtenir une analyse de son fonctionnement au moyen d’un outil tel que gceasy.io. Gceasy fournit un rapport du fonctionnement de la JVM (usage de la mémoire heap, fréquence et performances des GC, …).

Les métriques systèmes (node-exporter)

Pour un environnement SolrCoud de petite et moyenne dimension (moins de 20 serveurs Solr) avec peu de créations, suppressions et modifications de collections, la charge sur les serveurs ne doit pas être un sujet d’inquiétude. Cependant, par principe et pour une analyse à posteriori de problèmes sur l’environnement SolrCloud, les métriques systèmes suivants sont monitorés pour chaque serveur Zookeeper.

Métrique

Description et requête Prometheus

Charge CPU


Les charges CPU « user », « system » et « iowait » sont plus particulièrement à monitorer.


Requêtes pour le serveur zk1


avg by (mode)(irate(node_cpu_seconds_total{instance= « zk1:9100″,mode= « user »}[1m])) * 100


avg by (mode)(irate(node_cpu_seconds_total{instance= « zk1:9100″,mode= « system » »}[1m])) * 100


avg by (mode)(irate(node_cpu_seconds_total{instance= »zk1:9100″,mode= « iowait »}[1m])) * 100


Alertes


Déterminer les charges CPU lors d’un fonctionnement nominal sans erreur.


Générer une alerte si ces valeurs sont doublées.


Générer une alerte si la charge CPU « user » est supérieure à 20%.


Générer une alerte si la charge CPU « iowait » est supérieure à 5%.


Load CPU

Le Load CPU à 1, 5 et 15 minutes


Requêtes pour le serveur zk1


node_load1{instance= « zk3:9100″}


node_load5{instance= « zk3:9100″}


node_load15{instance= « zk3:9100″}


Alertes


Si load supérieur au nombre de cpu.

Espace disque


L’un et/ou l’autre de ces métriques peuvent être utilisés.


* Le pourcentage d’espace disque utilisé sur les partitions des données et des transactions logs.


Requêtes pour le serveur zk1 et une partition « /dev/xxx »


100-(node_filesystem_avail_bytes{instance= « zk1:9100″,device= « /dev/xxx »} / node_filesystem_size_bytes{instance= « zk1:9100″,device= « /devxxx »}*100)


Alertes


Si espace disque utilisé > 50%


* L’espace disque restant sur les partitions des données et des transactions logs.


Requêtes pour le serveur zk1 et une partition « /dev/xxx »


node_filesystem_avail_bytes{instance= « zk1:9100″,device= « /dev/xxx »} / 1024 / 1024


Alertes


Si espace disque restant < 1 Go


I/O disque


Latence en ms pour les écritures (à l’exception du démarrage, Zookeeper ne fait qu’écrire).


Requêtes pour le serveur zk1 et un device « xxx »


rate(node_disk_write_time_seconds_total{instance= « zk1:9100″,device= « xxx »}[1m])/rate(node_disk_writes_completed_total{instance= « zk1:9100″,device= « xxx »}[1m])


Alertes


Si latence > 1ms


Erreurs réseau


Le but est de détecter des erreurs de transmission ou de réception de paquets. On surveille le pourcentage de paquets en erreur par rapport aux nombre de paquets transmis et reçus.


Requêtes pour le serveur zk1 et une interface « xxx »


rate(node_network_transmit_errs_total{instance= « zk1:9100″,device= « xxx »}[1m]) /rate(node_network_transmit_packets_total{instance= « zk1:9100″,device= « xxx »}[1m])*100


rate(node_network_receive_errs_total{instance= « zk1:9100″,device= « xxx »}[1m]) /rate(node_network_receive_packets_total{instance= « zk1:9100″,device= « xxx »}[1m])*100


Alerte


Si > 1%


Les métriques JMX de la JVM (jmx-exporter)

Il s’agit de surveiller le fonctionnement de la JVM de Zookeeper. Nous nous intéresserons plus particulièrement à l’usage de la mémoire heap et des GC.

Métrique

Description et requête Prometheus

Heap utilisée


Les 3 mesures suivantes sont à surveiller pour bien suivre l’utilisation de la mémoire heap


* Mémoire heap courante (Mo)


Requêtes pour le serveur zk1


java_lang_Memory_HeapMemoryUsage_used{instance= « zk1:7070″} / 1024 / 1024


* Mémoire heap maximum sur la dernière heure (Mo)


Requêtes pour le serveur zk1


max_over_time(java_lang_Memory_HeapMemoryUsage_used {instance= « zk1:7070″}[1h])/1024/1024


* Mémoire heap maximum sur la dernière journée (Mo)


Utiliser ce métrique pour déterminer la valeur de heap à configurer. Ne pas allouer plus de deux fois cette valeur avec le paramètre Xmx.


Requêtes pour le serveur zk1


max_over_time(java_lang_Memory_HeapMemoryUsage_used {instance= « zk1:7070″}[1d])/1024/1024


* Mémoire heap minimum sur les 5 dernières minutes (Mo)


Utiliser cette valeur pour alerter sur une mémoire heap haute de manière durable. Pourquoi monitorer la mémoire heap minimun sur les 5 dernières minutes ? Parce que la JVM a tendance à utiliser un maximum de mémoire heap avec d’en libérer lors des GC et donc la taille maximum est atteinte très fréquemment sans que cela soit un signe de problème. Par contre, les GC font redescendre très régulièrement la quantité de mémoire heap utilisée. Lorsque cette quantité de mémoire heap utilisée ne descend plus, c’est donc les GC ne remplissent plus leur rôle et qu’un problème risque de se produire à très court terme.


Requêtes pour le serveur zk1


min_over_time(java_lang_Memory_HeapMemoryUsage_used


{instance= « zk1:7070″}[5m])/1024/1024


Alerte


Si supérieur à 80% de la mémoire heap maximum (Xmx)


Fréquence des GC


Avec le garbadge collector G1GC, on surveille 2 types de GC : « G1 Young Generation » et  » G1 Old Generation ». On désire connaître le nombre de GC par seconde (moyenne sur la dernière minute).


Requêtes pour le serveur zk1


rate(jvm_gc_collection_seconds_count{instance= « zk1:7070″,gc= « G1 Young Generation »}[1m])


rate(jvm_gc_collection_seconds_count{instance= « zk1:7070″,gc= « G1 Old Generation »}[1m])


Alerte


Déterminer le nombre de GC lors d’un fonctionnement nominal.


Générer une alerte si ce nombre est doublé.


Durée des GC


On désire connaître la durée des GC (moyenne sur la dernière minute).


Requêtes pour le serveur zk1


rate(jvm_gc_collection_seconds_sum{instance= « zk1:7070″ ,gc= « G1 Young Generation » }[1m]) / rate(jvm_gc_collection_seconds_count{instance= « zk1:7070″ ,gc= « G1 Young Generation » }[1m])


rate(jvm_gc_collection_seconds_sum{instance= « zk1:7070″ ,gc= « G1 Old Generation » }[1m]) / rate(jvm_gc_collection_seconds_count{instance= « zk1:7070″ ,gc= « G1 Old Generation » }[1m])


Alerte


Déterminer le durée des GC lors d’un fonctionnement nominal.


Générer une alerte si cette durée est doublée.


Les métriques Zookeeper ( Zookeeper-exporter)

Le Zookeeper-exporter utilise les commandes 4lw (https://zookeeper.apache.org/doc/r3.9.2/zookeeperAdmin.html#sc_zkCommands).

Métrique

Description et requête Prometheus

Requêtes en attente


Nombre de requêtes mises en file d’attente par le serveur.


Requêtes pour le serveur zk1


zk_outstanding_requests{instance= « zk1:7080″}


Alerte


Si > 3


Synchronisations en attente


Ce métrique n’est disponible que sur le leader. On additionne les valeurs en provenance de tous les serveurs pour inclure le leader quel qu’il soit.


Requêtes


sum without (instance,job,zk_instance)(zk_pending_syncs)


Alerte


Si > 3


Nombre de followers


Ce métrique n’est disponible que sur le leader. On additionne les valeurs en provenance de tous les serveurs pour inclure le leader quel qu’il soit. On doit obtenir le nombre de serveurs moins 1.


Requêtes


sum without (instance,job,zk_instance)(zk_synced_followers)


Alerte


Si différent du nombre de serveurs moins 1


Fichiers ouverts


Nombre de fichiers ouverts. On surveille que la limite n’est pas atteinte.


Requêtes pour le serveur zk1


zk_open_file_descriptor_count / zk_max_file_descriptor_count * 100


Alerte


Si > 80%


Conclusions

ZooKeeper, par son architecture et son modèle de consensus éprouvé, s’avère très performant pour orchestrer des systèmes distribués à grande échelle. Dans un environnement SolrCloud, il joue un rôle central, sans être directement impliqué dans les opérations lourdes d’indexation ou de recherche. Même avec un trafic élevé, ZooKeeper reste peu sollicité. Il consomme peu de ressources, et une fois correctement configuré, il fonctionne de manière fiable et autonome. Cela n’exclut pas l’importance d’un monitoring rigoureux pour détecter à temps d’éventuelles dérives de performance, de quorum ou de saturation de ses fichiers de journalisation.

Cet article aura, espérons-le, permis de mieux comprendre le rôle fondamental mais souvent mal comprise de ZooKeeper dans une architecture SolrCloud. En éclairant sur son fonctionnement interne, ses forces, ses limites et ses bonnes pratiques de mise en œuvre, il sera plus facile de l’exploiter efficacement.