kafka ack = all and min-isr

时间:2018-06-04 21:42:10

标签: apache-kafka

摘要

Kafka的文档和代码注释表明,当生产者设置acks设置为all时,只有当所有同步副本都已捕获时,才会向生产者发送确认,但代码(Partition.ScalacheckEnoughReplicasReachOffset)似乎表明,只要 min in-sync副本已经赶上,就会发送确认。< / p>

详情

kafka文档有这个:

  

acks = all这意味着领导者将等待完整的同步副本集以确认记录。   source

另外,查看Kafka源代码 - partition.scala checkEnoughReplicasReachOffset()有以下评论(强调我的):

  

请注意,只有在requiredAcks = -1时才会调用此方法,并且我们等待ISR中的所有副本完全赶上与此生成请求相对应的(本地)领导者偏移量我们承认产品要求。

最后,Stack Overflow上的this answer(再次强调我的)

  

同步最小副本设置还指定了分区保持可用于写入所需的最小副本数。当生产者指定ack(-1 / all config)时,它仍将等待来自所有同步副本的确认(与min in-sync副本的设置无关)。

但是当我查看Partition.Scala中的代码时(注意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)

调用它的代码返回ack:

if (error != Errors.NONE || hasEnough) {
  status.acksPending = false
  status.responseStatus.error = error
}

因此,只要同步副本集大于min同步副本,代码就会返回ack。但是,文档和注释表明只有在所有同步副本都赶上后才会发送确认。我错过了什么?至少,checkEnoughReplicasReachOffset上方的评论看起来应该更改。

1 个答案:

答案 0 :(得分:1)

感谢ji-dev邮件列表中的Ismael。

  

关键点是这一行:

     

if(leaderReplica.highWatermark.messageOffset >= requiredOffset) {

     

只有当ISR中的所有副本都具有该特定偏移时,高水印才会移动。