Évolution de schéma dans un flux : qui casse qui
Dans un flux, producteur et consommateurs ne se déploient jamais ensemble et les anciens messages restent lisibles. Ce que veulent dire compatibilité ascendante et descendante, quel changement casse quel côté, et ce qu'un registre de schémas vérifie ou ne vérifie pas.
Par Elias Varen8 min de lectureMembres
Changer le schéma d'une API synchrone oblige à gérer deux versions pendant la durée d'un déploiement. Changer le schéma d'un message oblige à gérer toutes les versions qui ont existé, pour toujours ou presque. Le message publié ce matin sera lu par un consommateur déployé le mois dernier, par un autre déployé demain, et par un troisième qui rejouera le flux dans six mois avec un code qui n'existe pas encore. Il n'y a pas d'instant où tout le monde est à la même version. La question n'est donc jamais « ce changement est-il compatible ? » mais « compatible pour qui, et dans quel ordre de déploiement ? ».
Backward, forward, et qui déploie en premier
Les deux mots sont souvent employés l'un pour l'autre. Ils désignent deux garanties distinctes, et chacune impose qui déploie en premier.
Compatibilité ascendante (backward) : le nouveau lecteur sait lire les anciennes données. On peut alors mettre à jour les consommateurs d'abord ; ils liront les messages de l'ancien producteur, puis ceux du nouveau.
Compatibilité descendante (forward) : l'ancien lecteur sait lire les nouvelles données. On peut alors mettre à jour le producteur d'abord, et les consommateurs existants continuent sans redéploiement.
lit les messages v1 lit les messages v2
consommateur v1 oui forward : doit tenir
consommateur v2 backward : doit tenir ouiDans une organisation où le producteur ne connaît pas tous ses consommateurs, ce qui est précisément l'intérêt d'un flux, personne ne maîtrise l'ordre de déploiement. Il faut donc les deux à la fois, la compatibilité complète. Et dès que les messages sont conservés et rejouables, elle doit être transitive : la version 5 du lecteur doit lire la version 1 des données, et pas seulement la version 4. Une chaîne de changements compatibles deux à deux peut ne pas l'être de bout en bout. Si l'on ajoute un champ facultatif en version 2, puis qu'on le rend obligatoire en version 3 parce que « tous les producteurs l'envoient », chaque pas semblait raisonnable, et les messages de la version 1 encore dans le journal deviennent illisibles.
À lire ensuite
Toute la rubrique DonnéesDonnées
Files d'attente dans PostgreSQL : jusqu'où
Une table et SKIP LOCKED font une file d'attente sérieuse, jusqu'au jour où une transaction longue ailleurs dans la base la met à genoux. Le mécanisme, les deux patrons de consommation, et les signaux qui disent qu'il est temps d'en sortir.
6 minMembres
Données
Le retard des consommateurs, votre vraie métrique
Pourquoi le retard se mesure en temps et non en messages, comment un rééquilibrage en boucle ou un message empoisonné le font monter sans qu'aucune erreur n'apparaisse, et quelles alertes poser pour le voir avant vos utilisateurs.
8 minMembres
Données
Kafka, RabbitMQ ou une table : choisir par mode de défaillance
Les trois options savent toutes transporter vos messages. Elles diffèrent par ce qui se passe quand un consommateur ralentit, qu'un message est empoisonné ou qu'il faut rejouer. Une grille pour choisir la panne que votre équipe sait gérer.
7 minMembres