Résumé
La documentation et les commentaires de code pour Kafka suggèrent que, lorsque le paramètre producteur acks
est défini sur all
, un accusé de réception n'est envoyé au producteur que lorsque tous les réplicas en synchronisation ont rattrapé , mais le code (Partition.Scala
, checkEnoughReplicasReachOffset
) semble suggérer que l'accusé de réception est envoyé dès que les répliques in-sync min ont rattrapé .
Détails
Les documents kafka ont ceci:
acks = all Cela signifie que le responsable attendra que l'ensemble des répliques synchronisées accuse réception de l'enregistrement. la source
Aussi, en regardant le code source de Kafka - partition.scala
checkEnoughReplicasReachOffset()
a le commentaire suivant (c'est moi qui souligne):
Notez que cette méthode ne sera appelée que si requiredAcks = -1 et que nous attendons que tous les réplicas dans ISR soit complètement rattrapé par l'offset (local) du leader correspondant à cette demande de produit avant de reconnaître le produit. demande.
Enfin, cette réponse sur Stack Overflow (encore une fois, soulignez le mien)
De plus, le paramètre de réplica in-sync min spécifie le nombre minimum de réplicas devant être synchronisés pour que la partition reste disponible en écriture. Lorsqu'un producteur spécifie ack (-1/all config), il attend toujours les acks de tous les réplicas synchronisés à ce moment-là (indépendamment du réglage des réplicas min in-sync).
Mais quand je regarde le code dans Partition.Scala (note minIsr < curInSyncReplicas.size
):
def checkEnoughReplicasReachOffset(requiredOffset: Long): (Boolean, Errors) = {
...
val minIsr = leaderReplica.log.get.config.minInSyncReplicas
if (leaderReplica.highWatermark.messageOffset >= requiredOffset) {
if (minIsr <= curInSyncReplicas.size)
(true, Errors.NONE)
Le code qui appelle cela renvoie l'ack:
if (error != Errors.NONE || hasEnough) {
status.acksPending = false
status.responseStatus.error = error
}
Ainsi, le code semble renvoyer un accusé de réception dès que le jeu de réplicas synchronisé est supérieur au nombre minimal de réplicas synchronisés. Toutefois, la documentation et les commentaires suggèrent que l’accusé de réception n’est envoyé que lorsque tous les réplicas synchronisés sont rattrapés. Qu'est-ce que je rate? À tout le moins, le commentaire ci-dessus checkEnoughReplicasReachOffset
semble devoir être modifié.
Merci à Ismael de la liste de diffusion jira-dev.
Le point clé est la ligne:
if(leaderReplica.highWatermark.messageOffset >= requiredOffset) {
Le filigrane haut ne se déplace que lorsque toutes les répliques en ISR ont ce décalage particulier.