Je parcourais le document ce que j'ai compris que nous pouvons réaliser une transaction en une seule fois en activant idempotence=true
idempotence: Le producteur Idempotent permet exactement une fois pour un producteur sur un seul sujet. Fondamentalement, chaque message envoyé a des garanties plus solides et ne sera pas dupliqué en cas d'erreur
Donc, si nous avons déjà l'idempotence, alors pourquoi avons-nous besoin d'une autre propriété exactement une fois dans Kafka Stream? Qu'est-ce qui diffère exactement entre l'idempotence et exactement une fois
Pourquoi la propriété à une seule fois n'est pas disponible en normal Kafka Producer?
Dans un environnement distribué, la défaillance est un scénario très courant qui peut survenir à tout moment. Dans l'environnement Kafka, le courtier peut se bloquer, défaillance du réseau, échec du traitement, échec lors de la publication du message ou échec de la consommation des messages, etc. Ces différents scénarios ont introduit différents types de perte et de duplication de données.
Scénarios d'échec
A (Échec de l'acquittement): Le message du producteur a été publié avec succès avec une nouvelle tentative> 1 mais n'a pas pu recevoir d'accusé de réception en raison d'un échec. Dans ce cas, le producteur réessayera que le même message peut introduire un doublon.
B (Le processus du producteur a échoué dans les messages de lot): Le producteur a envoyé un lot de messages, il a échoué avec peu de succès publié. Dans ce cas et une fois que le producteur redémarrera, il republiera à nouveau tous les messages du lot, ce qui introduira un doublon dans Kafka.
C (Fire & Forget Failed) Message publié par le producteur avec nouvelle tentative = 0 (tirer et oublier). En cas d'échec publié ne sera pas au courant et envoyer le message suivant cela entraînera la perte du message.
D (Échec du consommateur dans le message de lot) Un consommateur reçoit un lot de messages de Kafka et valide manuellement son décalage ( enable.auto.commit = false). Si le consommateur a échoué avant de s'engager dans Kafka, la prochaine fois, le consommateur consommera à nouveau les mêmes enregistrements qui reproduisent le double du côté du consommateur.
Sémantique exacte
Dans ce cas, même si un producteur essaie de renvoyer un message, cela conduit à ce que le message soit publié et consommé par le consommateur une seule fois.
Pour atteindre la sémantique Exactly-Once dans Kafka, il utilise la propriété ci-dessous 3
Activer Idempotent (enable.idempotence = true)
La livraison idempotente permet au producteur d'écrire un message à Kafka exactement une fois sur une partition particulière d'un sujet pendant la durée de vie d'un seul producteur sans perte de données et ordre par partition.
"Notez que l'activation de l'idempotence nécessite que MAX_IN_FLIGHT_REQUESTS_PER_CONNECTION soit inférieur ou égal à 5, RETRIES_CONFIG soit supérieur à 0 et ACKS_CONFIG soit" tous ". Si ces valeurs ne sont pas définies explicitement par l'utilisateur, les valeurs appropriées seront choisies. Si des valeurs incompatibles sont définies, une ConfigException sera levée "
Pour atteindre l'idempotence Kafka utilise un identifiant unique qui est appelé id du produit ou PID et numéro de séquence lors de la production des messages. Le producteur continue d'incrémenter le numéro de séquence sur chaque message publié qui mappe avec un PID unique. Le courtier compare toujours la séquence actuelle nombre avec le précédent et il rejette si le nouveau n'est pas supérieur de +1 au précédent, ce qui évite la duplication et en même temps si plus que le plus grand s'affiche perdu dans les messages
Dans un scénario d'échec, le courtier comparera le numéro de séquence avec le précédent et si la séquence n'est pas augmentée, +1 rejettera le message.
Transaction (isolation.level)
Les transactions nous permettent de mettre à jour de manière atomique les données dans plusieurs partitions de sujet. Tous les enregistrements inclus dans une transaction seront sauvegardés avec succès, ou aucun d'entre eux ne le sera.Il vous permet de valider vos compensations de consommateur dans la même transaction avec les données que vous avez traitées, permettant ainsi une sémantique de bout en bout exactement une fois .
Le producteur n'attend pas pour écrire un message à kafka où le producteur utilise beginTransaction, commitTransaction et abortTransaction (en cas d'échec). Le consommateur utilise isolation.level soit read_committed soit read_uncommitted
Si un consommateur avec isolation.level = read_committed atteint un message de contrôle pour une transaction qui n'est pas terminée, il ne remettra plus de messages de cette partition tant que le producteur n'aura pas validé ou abandonné la transaction ou qu'un délai d'expiration de transaction ne se produira. Le délai de transaction est déterminé par le producteur à l'aide de la configuration transaction.timeout.ms (par défaut 1 minute).
Exactement une fois chez le producteur et le consommateur
Dans un état normal où nous avons un producteur et un consommateur séparés. Le producteur doit gérer les transactions de manière idempotente et en même temps pour que le consommateur puisse utiliser isolation.level en lecture seule read_committed pour faire de l'ensemble du processus une opération atomique. Cela garantit que le producteur sera toujours synchronisé avec le système source. Même le crash ou la transaction du producteur est abandonné, il doit toujours être cohérent et publier le message ou le lot de messages comme une seule fois.
Le même consommateur recevra un message ou un lot de messages comme unité une fois.
Dans Exactly-Once sémantique, Producer et Consumer apparaîtront comme une opération atomique qui fonctionnera comme une seule unité. Soit publier et être consommé une fois ou abandonné.
Exactement une fois dans Kafka Stream
Kafka Stream consomme les messages du sujet A, traite et publie le message dans le sujet B et une fois publié, utilisez commit (commit exécuté principalement sous le couvert) pour vider toutes les données du magasin d'état sur le disque.
Exactement une fois dans Kafka Stream est un modèle de processus de lecture-écriture qui garantit que ces opérations seront traitées comme des opérations atomiques. Puisque Kafka Stream cater producteur, consommateur et transaction tous ensemble Kafka Stream vient un traitement de paramètre spécial. garantie qui pourrait exactement_once ou at_least_once qui rend la vie facile de ne pas gérer tous les paramètres séparément.
Kafka Streams met à jour de manière atomique les compensations des consommateurs, les magasins d'état locaux, les sujets du journal des modifications du magasin d'état et la production pour sortir les sujets ensemble. Si l'une de ces étapes échoue, toutes les modifications sont annulées.
processing.guarantee: exactement_once fournit automatiquement ci-dessous les paramètres que vous n'avez pas besoin de définir de manière explicite
Le flux Kafka offre la sémantique exactement une fois du point de vue de bout en bout (consomme d'un sujet, traite ce message, puis le produit à un autre) sujet). Cependant, vous avez mentionné uniquement l'attribut idempotent du producteur . Ce n'est qu'une petite partie de l'image complète.
Laissez moi reformuler la question:
Pourquoi avons-nous besoin de la sémantique de livraison en une seule fois côté consommateur alors que nous avons déjà garanti la sémantique de livraison en une seule fois côté producteur?
Réponse: Étant donné que la sémantique de livraison en une seule fois est non seulement à l'étape de production, mais au flux complet de traitement. Pour atteindre la livraison sémantique exactement une fois, il faut que certaines conditions soient satisfaites avec la production et la consommation.
Voici le scénario générique: le processus A produit des messages vers le sujet T. En même temps, le processus B essaie de consommer les messages du sujet T. Nous voulons nous assurer que le processus B ne traite jamais un message deux fois.
Partie producteur: Nous devons nous assurer que les producteurs ne produisent jamais un message deux fois. Nous pouvons utiliser Kafka Idempotent Producer
Partie consommateur: Voici le workflow de base pour le consommateur:
Les étapes ci-dessus ne sont qu'un chemin heureux. De nombreux problèmes se posent en réalité.
Étant donné que de nombreux problèmes peuvent survenir, l'exécution du travail et l'offset de validation doivent être atomiques pour garantir une sémantique de livraison en une seule fois côté consommateur. Cela ne signifie pas que nous ne pouvons pas, mais il faut beaucoup d'efforts pour s'assurer de la sémantique de livraison en une seule fois. Kafka Stream soutient le travail des ingénieurs.
A noté que: Kafka Stream offre un "traitement de flux unique". Il s'agit de consommer à partir d'un sujet, de matérialiser état intermédiaire dans un sujet Kafka et produisant à un. Si notre application dépend de certains autres services externes (base de données, services ...), nous devons nous assurer que nos dépendances externes peuvent garantir une seule fois dans ces cas.
TL, DR: exactement une fois pour le flux complet a besoin de la coopération entre producteurs et consommateurs.
Références: