Leader Election
Désigner un seul nœud — re-désignable en quelques secondes — pour faire ce que plusieurs ne doivent pas faire en même temps.
Problème
Un service tourne en N instances pour la HA mais certaines tâches doivent n'avoir qu'un seul exécutant à un instant T : poller cron, ordonnanceur, processeur d'un canal séquentiel. Si toutes les instances exécutent en parallèle, on a soit de la duplication (envoi de la facture 5 fois), soit de la corruption (deux nœuds qui réorganisent le même outbox).
Forces
- Une instance plantée doit pouvoir céder son rôle rapidement (sinon la tâche est suspendue).
- Aucun nœud ne doit croire qu'il est leader alors qu'un autre l'est (split brain).
- Une élection trop fréquente crée du flapping et de la latence inutile.
- La détection de panne par heartbeat doit être plus rapide que la fenêtre de tolérance métier.
Solution
Utiliser un service de coordination (ZooKeeper, etcd, Consul, ou ConfigMap Lease Kubernetes) où chaque candidat tente de prendre un bail (lease) avec TTL. Le détenteur du bail est leader ; il doit renouveler avant l'expiration. Les autres l'observent : si le bail expire (le leader est mort ou injoignable), le premier candidat à réclamer le bail devient leader. Les algorithmes Raft (etcd) et ZAB (ZooKeeper) gèrent la cohérence du registre. Pour des cas simples, un SELECT ... FOR UPDATE sur une row dédiée en DB suffit (advisory lock Postgres).
Structure
Coordination service (etcd / ZooKeeper)
lease key: "edi.outbox.poller.leader"
│
┌──────────────┼──────────────┐
▼ ▼ ▼
Node A Node B Node C
(current (observer) (observer)
leader)
│
│ renew lease every 5s (TTL 15s)
│
X dies (network partition)
│
lease TTL expires 15s later
│
Node B acquires lease ──► becomes leader Implémentation EDI
Un hub EDI en 3 réplicas a besoin de désigner un seul nœud pour : (1) poller MDN AS2 — sinon deux nœuds traiteraient la même MDN et marqueraient la commande deux fois en « delivered » ; (2) générer le rapport de fin de journée envoyé au manager ; (3) nettoyer la table outbox. Implémentation simple : un Lease Kubernetes edi-mdn-poller avec rétention 30 s, renouvellement toutes les 10 s par le leader. À crash du nœud, un autre prend le bail en moins d'une minute.
Anti-patterns
- Bail TTL trop long — un nœud mort bloque la tâche pendant des minutes.
- Pas de fencing token — un ancien leader réveillé après une partition continue d'écrire et corrompt l'état.
- Élection sur un service de coordination single-instance — il devient un SPOF.
- Leader qui n'arrête pas la tâche quand il perd le bail — split brain assuré.
- Renouvellement de bail interrompu par un GC pause Java — le leader perd le bail sans se savoir mort.
Patterns liés
- Consensus (Raft) — algorithme utilisé par etcd et beaucoup d'autres.
- Competing Consumers — alternative quand la concurrence est acceptable.
- Circuit Breaker — à associer pour gérer la panne du service de coordination.
- Health Check — base de la détection de panne.
Sources
- Microsoft Azure Architecture — Leader Election. learn.microsoft.com/en-us/azure/architecture/patterns/leader-election
- Kubernetes — Coordinated Leader Election (Lease API). kubernetes.io/docs/concepts/architecture/leases
- Kleppmann M. — Designing Data-Intensive Applications, O'Reilly 2017, chap. 9 « Consistency and Consensus ».