概要
卡夫卡(Kafka)的文档和代码注释建议,当生产者设置acks
设置all
为时,仅当所有同步副本都已捕获时,才会将确认发送给生产者,但是代码(Partition.Scala
,checkEnoughReplicasReachOffset
)似乎表明已发送确认。只要分在同步副本已经赶上。
细节
kafka文档具有以下内容:
acks = all这意味着领导者将等待完整的同步副本集确认记录。资源
另外,查看Kafka源代码-partition.scala
checkEnoughReplicasReachOffset()
有以下注释(强调我的意思):
请注意,只有在requiredAcks = -1时,才会调用此方法,并且在我们确认生产请求之前,我们正在等待ISR中的所有副本完全达到与该生产请求相对应的(本地)领导者的偏移量。
最后,关于堆栈溢出的答案(再次强调我的意思)
最小同步副本数设置还指定了分区必须保持同步的最小副本数,以保持可用于写入。当生产者指定ack(-1 / all config)时,它仍将在那一刻等待所有同步副本的ack(与最小同步副本的设置无关)。
但是,当我查看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
}
因此,一旦异步副本集大于最小同步副本,该代码看起来就将返回一个ack。但是,文档和注释建议仅在所有同步副本都已捕获后才发送ack。我想念什么?至少,上面的注释checkEnoughReplicasReachOffset
看起来应该更改。
感谢jira-dev邮件列表中的Ismael。
关键是直线:
if(leaderReplica.highWatermark.messageOffset >= requiredOffset) {
只有当ISR中的所有副本都具有特定偏移时,高水位标记才会移动。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句