Une commande, quatre systèmes
Un client paie sa commande. L'entrepôt doit la préparer, la facturation doit l'enregistrer et le service de courriels doit remercier le client.
Si le site appelle chacun d'eux, un système lent ralentit toutes les commandes. Mieux vaut écrire un événement dans un journal, et laisser chaque système le lire quand il est prêt.
À la fin de cette leçon
Remarque
Je peux expliquer un journal d'événements et la façon dont les consommateurs le lisent.
Mots clés
| Mot | Ce que ça veut dire | Exemple |
|---|---|---|
| Événement | la trace que quelque chose s'est produit | commande payée |
| Topic | un journal d'événements qui porte un nom | |
| Partition | une tranche ordonnée d'un topic | |
| Décalage | le numéro d'un événement dans sa partition, à partir de zéro (offset en anglais) | |
| Producteur | un programme qui ajoute des événements à un topic | |
| Consommateur | un programme qui lit les événements d'un topic |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
Un topic est un journal où l'on ajoute
Kafka range les événements dans un topic. Pensez à un registre de caisse : les nouvelles lignes vont à la fin et les anciennes ne changent pas.
Un producteur ajoute des événements. Chacun reçoit un décalage, son numéro de place, à partir de 0. Les événements restent un temps fixé, sept jours par exemple, que quelqu'un les ait lus ou non.
Exemple : un journal et ses décalages
| Décalage | Événement | Écrit par |
|---|---|---|
| 0 | commande 2001 payée | site web |
| 1 | commande 2002 payée | site web |
| 2 | commande 2001 préparée | entrepôt |
| 3 | commande 2003 payée | site web |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
Créer un topic de deux partitions
curl -s -X POST -H "Content-Type: application/json" -d '{"name":"caisse","partitions":2,"replicationFactor":1,"configs":{}}' http://kafka-ui:8080/api/clusters/lab/topics -o /dev/null -w "%{http_code}\n"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Voir les décalages du topic vide
curl -s http://kafka-ui:8080/api/clusters/lab/topics/caisse | grep -o '"partition":[0-9]*\|"offsetMax":[0-9]*'Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Les partitions partagent le travail
Un seul journal sur une seule machine ne suffirait pas aux événements d'une grande enseigne. Un topic est donc coupé en partitions. Chacune est un journal à part, avec ses propres décalages.
Les événements gardent leur ordre dans une même partition. Entre deux partitions, aucun ordre n'est promis.
Ajouter un événement à la partition 0
curl -s -X POST -H "Content-Type: application/json" -d '{"partition":0,"key":"caisse1","value":"pain","headers":{},"keySerde":"String","valueSerde":"String"}' http://kafka-ui:8080/api/clusters/lab/topics/caisse/messages -w "%{http_code}\n"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Ajouter un second événement à la partition 0
curl -s -X POST -H "Content-Type: application/json" -d '{"partition":0,"key":"caisse1","value":"lait","headers":{},"keySerde":"String","valueSerde":"String"}' http://kafka-ui:8080/api/clusters/lab/topics/caisse/messages -w "%{http_code}\n"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Ajouter un événement à la partition 1
curl -s -X POST -H "Content-Type: application/json" -d '{"partition":1,"key":"web","value":"cafe","headers":{},"keySerde":"String","valueSerde":"String"}' http://kafka-ui:8080/api/clusters/lab/topics/caisse/messages -w "%{http_code}\n"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Revoir les décalages
curl -s http://kafka-ui:8080/api/clusters/lab/topics/caisse | grep -o '"partition":[0-9]*\|"offsetMax":[0-9]*'Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Un consommateur retient son décalage
Un consommateur lit les événements d'une partition, dans l'ordre, et retient le décalage du prochain dont il a besoin. S'il s'arrête puis redémarre, il reprend là.
Deux services peuvent lire un même topic. Chacun garde son décalage : un service lent ne retient jamais un service rapide. L'écart entre la fin du journal et le décalage d'un consommateur est son retard.
Un consommateur lit et avance
# Une partition d'un topic, sous forme de liste. Un consommateur retient un seul nombre.
partition = ["pain", "lait", "cafe", "riz"]
decalage = 2
print("Lu :", partition[decalage], "au décalage", decalage)
decalage = decalage + 1
print("Prochain décalage :", decalage)
print("Reste à lire :", len(partition) - decalage)
# Remplacez le premier décalage par 0 pour lire depuis le début.
Deux consommateurs, deux décalages
# Deux services lisent le même journal. Chacun a son propre décalage.
journal = ["pain", "lait", "cafe"]
decalages = {"facturation": 3, "courriels": 1}
for nom in decalages:
reste = len(journal) - decalages[nom]
print(nom, "a", reste, "messages à lire")
# Mettez le décalage de courriels à 3 puis relancez.
Relire la partition 0 depuis le début
curl -s -N "http://kafka-ui:8080/api/clusters/lab/topics/caisse/messages/v2?seekType=BEGINNING&partitions=0&limit=10" | grep -o '"partition":[0-9]*,"offset":[0-9]*\|"value":"[a-z]*"'Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Une erreur fréquente
Attention
On croit souvent qu'une lecture retire l'événement, comme une lettre prise dans une boîte. Dans un journal, non. Lire ne fait avancer que le décalage du consommateur. L'événement reste : un autre service peut le lire aussi.
Pour aller plus loin : prévoir les décalages
Reprenez la commande qui ajoute un événement à la partition 1, et changez la valeur cafe en sel. Envoyez-la deux fois.
Avant chaque envoi, écrivez l'offsetMax que vous attendez pour la partition 1. Vérifiez ensuite avec la commande « Revoir les décalages ». Et la partition 0, a-t-elle bougé ?