我正在学习Kafka复制和生产者的设计。 令我惊讶的是,我以某种方式得出的结论是,生产者不可能准确地知道消息是否由代理提交,并且写入的安全性是不可知的。
我希望我的结论是错误的,我会列出我的分析步骤,希望我能在这里得到一些评论。
** 我从 Kafka 文档中获得的关键信息: **
根据Kafka Document这里的两个陈述,我得到第一个结论:
My-Conclusion-1: 提交背后的副本数量是动态的。
然后我想将涉及生产者的写入链接到数据的提交。 然后我发现了两个关键配置:生产者的
acks
和经纪人的min.insync.replica
。
直接引用这些解释:
当生产者将 acks 设置为“all”(或“-1”)时,min.insync.replicas 指定必须确认写入才能被视为成功的最小副本数。如果无法满足此最小值,则生产者将引发异常(NotEnoughReplicas 或 NotEnoughReplicasAfterAppend)。 当一起使用时,min.insync.replicas 和 ack 允许您强制执行更高的持久性保证。典型的场景是创建一个复制因子为 3 的主题,将 min.insync.replicas 设置为 2,并使用“all”的 ack 进行生成。这将确保生产者在大多数副本未收到写入时引发异常。
然后我发现虽然我们可以设置生产者
ack=all
,但我们不能那样min.insync.replica=all
,因为它需要一个特定的数字。然后我得到:
我的结论-2: 对于分区 =
f+1
副本:
如果具有
ack=all
但 min.insync.replica=f
的生产者成功:消息仍有可能丢失,因为提交消息需要所有 ISR(现在可以是 f+1)接收消息;
如果具有
ack=all
但 min.insync.replica=f+1
的生产者失败,仍然有一些机会 - 消息成功,因为提交消息需要所有 ISR(可以是 我的结论-3: 未提交的消息可能会丢失,即使大多数 ISR 都有该消息并且当 当领导失败时,没有消息的 ISR 将被选举。
现在我开始思考我可以从制作人那里得到什么:
对于分区 =
f+1
副本,我们至少有 2 个选择:
ack=all
但min.insync.replica=f
的制作人是成功的ack=all
但 min.insync.replica=f+1
如果我们不关心重试延迟/吞吐量/SLA 并且我们对数据丢失非常敏感, 我们应该使用第二个选项。 如果我们不关心数据丢失,但想要高 SLA/吞吐量/重试延迟,我们应该使用选项 1,这是比它更宽松的选项。
我希望Kafka专家帮助审查我的分析和结论,以评论它们是错误的还是有道理的。
我想我误解了“min.insync.replica”的含义,不知道如何更好地表达它,只是在这里举个例子:
如果生产者
ack=all
,则所有 ISR 都应在生产者收到成功响应之前收到消息。 min.insync.replica
仅限制“所有”ISR 引用的最小数量,而不意味着 ISR 接收消息的一部分足以成功写入全确认生产者。