web-dev-qa-db-fra.com

kafka ack = all et min-isr

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.scalacheckEnoughReplicasReachOffset() 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é.

5
acarlon

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.

1
acarlon