L'inconvénient est que tandis que commitSync () réessayera la validation jusqu'à ce qu'elle réussisse ou rencontre un échec non récupérable, commitAsync () ne réessayera pas.
Cette phrase n'est pas claire pour moi. Je suppose que le consommateur envoie une demande de validation au courtier et si le courtier ne répond pas dans un certain délai, cela signifie que la validation a échoué. Ai-je tort?
Pouvez-vous clarifier la différence entre commitSync
et commitAsync
en détail?
Veuillez également fournir des cas d'utilisation lorsque je préfère le type de validation.
Comme il est dit dans la documentation de l'API:
Ceci est une validation synchrone et se bloquera jusqu'à ce que la validation réussisse ou qu'une erreur irrécupérable soit rencontrée (auquel cas elle est envoyée à l'appelant).
Cela signifie que le commitSync
est une méthode de blocage. L'appeler bloquera votre thread jusqu'à ce qu'il réussisse ou échoue.
Par exemple,
while (true) {
ConsumerRecords<String, String> records = consumer.poll(100);
for (ConsumerRecord<String, String> record : records) {
System.out.printf("offset = %d, key = %s, value = %s", record.offset(), record.key(), record.value());
consumer.commitSync();
}
}
Pour chaque itération dans la boucle for, seulement après que consumer.commitSync()
a réussi ou interrompu avec exception levée, votre code passera à l'itération suivante.
Il s'agit d'un appel asynchrone et ne bloquera pas. Toutes les erreurs rencontrées sont soit transmises au rappel (le cas échéant), soit supprimées.
Cela signifie que le commitAsync
est une méthode non bloquante. L'appeler ne bloquera pas votre fil. Au lieu de cela, il continuera à traiter les instructions suivantes, qu'il réussisse ou échoue éventuellement.
Par exemple, similaire à l'exemple précédent, mais ici nous utilisons commitAsync
:
while (true) {
ConsumerRecords<String, String> records = consumer.poll(100);
for (ConsumerRecord<String, String> record : records) {
System.out.printf("offset = %d, key = %s, value = %s", record.offset(), record.key(), record.value());
consumer.commitAsync(callback);
}
}
Pour chaque itération de la boucle for, quel que soit le sort de consumer.commitAsync()
, votre code passera à l'itération suivante. Et, le résultat de la validation va être géré par la fonction de rappel que vous avez définie.
Compromis: latence vs cohérence des données
commitSync()
car il s'assurera qu'avant d'effectuer d'autres actions, vous saurez si la validation du décalage a réussi ou échoué. Mais comme il s'agit de synchronisation et de blocage, vous passerez plus de temps à attendre la fin de la validation, ce qui entraîne une latence élevée.commitAsync()
car il n'attendra pas d'être terminé. Au lieu de cela, il enverra simplement la demande de validation et gérera la réponse de Kafka (succès ou échec) plus tard, et pendant ce temps, votre code continuera à s'exécuter.C'est tout de manière générale, le comportement réel dépendra de votre code réel et de l'endroit où vous appelez la méthode.
CommitSync et commitAsync utilisent la fonction de gestion de décalage kafka et les deux ont des démérites. Si le traitement du message réussit et que le décalage de validation échoue (pas atomique) et en même temps que le rééquilibrage de la partition se produit, votre message traité est traité à nouveau (traitement en double) par un autre consommateur. Si vous êtes d'accord avec le traitement des messages en double, vous pouvez opter pour commitAsync (car il ne bloque pas et ne fournit pas une faible latence, et il fournit un commit d'ordre supérieur. vous devriez donc être d'accord Sinon, optez pour une gestion de décalage personnalisée qui prend en charge l'atomicité lors du traitement et de la mise à jour du décalage (utilisez un stockage de décalage externe)