我正在浏览文档,查看多个地方,这增加了混乱..
关于属性 min.insync.replicas
当生产者将 acks 设置为“全部”(或“-1”)时,此配置指定必须确认写入才能将写入视为成功的最小副本数。如果无法满足此最小值,则生产者将引发异常(NotEnoughReplicas 或 NotEnoughReplicasAfterAppend)。当一起使用时,min.insync.replicas 和 acks 允许您强制执行更大的持久性保证。一个典型的场景是创建一个复制因子为 3 的主题,将 min.insync.replicas 设置为 2,并使用“all”的 acks 进行生产。如果大多数副本没有收到写入,这将确保生产者引发异常。
我提出的问题,
更新 #1 我遇到了这个短语
“当生产者指定 ack (-1 / all config) 时,它仍然会等待当时所有同步副本的 ack(独立于最小同步副本的设置)。因此,如果您在 4 个副本同步时发布那么除非所有 4 个副本都提交消息(即使最小同步副本配置为 2),否则您将不会收到确认。”
这句话是如何与今天相关的?这个属性“最小同步副本”是否仍然独立?
摘要
Kafka的文档和代码注释表明,当生产者设置acks设置all为时,只有当所有同步副本都赶上时,ack才会被发送给生产者,但代码(Partition.Scala,checkEnoughReplicasReachOffset)似乎表明ack已发送一旦最小的同步复制品赶上了.
细节
kafka文档有这个:
acks = all这意味着领导者将等待完整的同步副本集以确认记录. 资源
另外,查看Kafka源代码 - partition.scala checkEnoughReplicasReachOffset()有以下评论(强调我的):
请注意,只有在requiredAcks = -1时才会调用此方法,并且在我们确认生成请求之前,我们正在等待ISR中的所有副本完全捕获到与此生成请求相对应的(本地)领导者的偏移量.
最后,关于Stack Overflow的这个答案(再次强调我的)
此同步最小同步副本设置指定了分区保持可用于写入时需要同步的最小副本数.当生产者指定ack(-1/all config)时,它仍将等待来自所有同步副本的 ack(与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)
Run Code Online (Sandbox Code Playgroud)
调用它的代码返回ack:
if (error != Errors.NONE || hasEnough) {
status.acksPending = false
status.responseStatus.error = …Run Code Online (Sandbox Code Playgroud)