Article
Idempotence par l'exemple
L'idempotence en clair : exécuter une opération une ou plusieurs fois laisse le même état. Avec la clé d'idempotence, retry et doublon ne débitent qu'une fois.
Vous cliquez sur « Payer ». La page rame. Vous recliquez. Avez-vous été débité une fois, ou deux ? La réponse tient en un mot — l'idempotence — et c'est la propriété qui tient debout la plupart des systèmes distribués.
Une opération est idempotente si l'exécuter une fois ou plusieurs fois laisse le système dans le même état final. Le mot fait peur ; l'idée est simple. Appuyer sur le bouton d'appel d'un ascenseur est idempotent : trois appuis n'appellent pas trois ascenseurs. Régler un thermostat sur 20 °C est idempotent : le refaire ne change rien. Poser solde = 100 est idempotent.
Ce qui ne l'est pas : solde = solde + 10. Deux exécutions font +20. La distinction est exactement là : une opération qui fixe une valeur ou marque un fait tend à être idempotente ; une opération qui incrémente ou ajoute ne l'est pas, sauf précaution. « Marquer la commande 4567 comme payée » est idempotent ; « débiter 10 € » ne l'est pas.
Pourquoi c'est vital
Dès qu'un message franchit une frontière — un appel réseau, une file, un bus —, il peut être redélivré, retrié, ou reçu en double. Ce n'est pas un cas rare : c'est le mode de fonctionnement normal des systèmes qui ne veulent rien perdre. Un client qui n'a pas reçu de réponse (timeout) réessaie, sans savoir si le serveur avait déjà traité sa demande. Un bus de messages garantit « au moins une fois », donc parfois deux. Sans idempotence, chaque doublon corrompt l'état : double débit, double e-mail, double réservation.
C'est pour ça que l'idempotence est la clé de voûte de la résilience : elle est ce qui rend un retry sûr. Tant qu'une opération n'est pas idempotente, on n'a pas le droit de la rejouer — et un système distribué passe son temps à rejouer.
La clé d'idempotence
Comment rendre idempotent un débit, qui ne l'est pas par nature ? On lui attache une clé d'idempotence : un identifiant unique de l'intention, généré par le client et stable à travers ses propres retries. Le client envoie sa demande de paiement avec une clé — par exemple l'en-tête HTTP Idempotency-Key: 7f3a…. Le serveur, avant d'agir, regarde s'il a déjà traité cette clé :
- clé inconnue → il exécute le débit, enregistre la clé et le résultat, répond ;
- clé déjà vue → il n'exécute rien, et renvoie le résultat mémorisé la première fois.
Le second clic, le retry du client, le doublon du bus : tous portent la même clé, donc ne débitent qu'une fois. L'opération est devenue idempotente de l'extérieur, sans l'être par nature.
Trois détails font la différence entre une clé d'idempotence qui marche et une qui blesse :
- la clé doit être générée par le client et stable à travers ses retries — une clé régénérée à chaque tentative ne protège de rien ;
- une même clé avec une charge utile différente doit être rejetée, pas appliquée : la clé identifie une intention précise, pas « la prochaine opération » ;
- la clé a une durée de rétention (le serveur ne peut pas s'en souvenir éternellement) : assez longue pour couvrir tous les retries plausibles, pas plus.
Idempotence n'est pas ordre
Un dernier piège, fréquent : l'idempotence neutralise les doublons et les rejeux, pas le désordre. Si deux messages arrivent dans le mauvais ordre, une clé d'idempotence n'y changera rien — remettre les choses dans l'ordre est un autre problème, qui relève d'une clé de partition ou d'un numéro de séquence. Confondre les deux mène à des bugs tenaces : « pourtant c'est idempotent ! » — oui, mais le problème n'était pas le doublon, c'était l'ordre.
Retenez l'essentiel : une opération idempotente peut être rejouée sans dommage, et une clé d'idempotence rend rejouable ce qui ne l'était pas. C'est la condition qui autorise tous les autres mécanismes de résilience — retry, file de rattrapage, replay. Sans elle, on ne réessaie jamais sans trembler.
Laisser un commentaire
Vous devez être connecté pour pouvoir laisser un commentaire.