文件名称:消息交付语义-树莓派python编程指南
文件大小:3.8MB
文件格式:PDF
更新时间:2024-07-21 13:27:43
kafka官方文档 kafka kafka中文 kafka文档
4.6 消息交付语义 现在我们对于 producer 和 consumer 的⼯作原理已将有了⼀点了解,让我们接着讨论 Kafka 在 producer 和 consumer 之间提供的语义保证。显然,Kafka可以提供的消息交付语义保证有多种: At most once——消息可能会丢失但绝不重传。 At least once——消息可以重传但绝不丢失。 Exactly once——这正是⼈们想要的, 每⼀条消息只被传递⼀次. 值得注意的是,这个问题被分成了两部分:发布消息的持久性保证和消费消息的保证。 很多系统声称提供了“Exactly once”的消息交付语义, 然⽽阅读它们的细则很重要, 因为这些声称⼤多数都是误 导性的 (即它们没有考虑 consumer 或 producer 可能失败的情况,以及存在多个 consumer 进⾏处理的情况, 或者写⼊磁盘的数据可能丢失的情况。). Kafka 的语义是直截了当的。 发布消息时,我们会有⼀个消息的概念被“committed”到 log 中。 ⼀旦消息被提 交,只要有⼀个 broker 备份了该消息写⼊的 partition,并且保持“alive”状态,该消息就不会丢失。 有关 committed message 和 alive partition 的定义,以及我们试图解决的故障类型都将在下⼀节进⾏细致描述。 现在让我们假设存在完美⽆缺的 broker,然后来试着理解 Kafka 对 producer 和 consumer 的语义保证。如果 ⼀个 producer 在试图发送消息的时候发⽣了⽹络故障, 则不确定⽹络错误发⽣在消息提交之前还是之后。这 与使⽤⾃动⽣成的键插⼊到数据库表中的语义场景很相似。 在 0.11.0.0 之前的版本中, 如果 producer 没有收到表明消息已经被提交的响应, 那么 producer 除了将消息重传 之外别⽆选择。 这⾥提供的是 at-least-once 的消息交付语义,因为如果Y初的请求事实上执⾏成功了,那么 重传过程中该消息就会被再次写⼊到 log 当中。 从 0.11.0.0 版本开始,Kafka producer新增了幂等性的传递选 项,该选项保证重传不会在 log 中产⽣重复条⽬。 为实现这个⽬的, broker 给每个 producer 都分配了⼀个 ID ,并且 producer 给每条被发送的消息分配了⼀个序列号来避免产⽣重复的消息。 同样也是从 0.11.0.0 版本开 始, producer 新增了使⽤类似事务性的语义将消息发送到多个 topic partition 的功能: 也就是说,要么所有的 消息都被成功的写⼊到了 log,要么⼀个都没写进去。这种语义的主要应⽤场景就是 Kafka topic 之间的 exactly-once 的数据传递(如下所述)。 并⾮所有使⽤场景都需要这么强的保证。对于延迟敏感的应⽤场景,我们允许⽣产者指定它需要的持久性级 别。如果 producer 指定了它想要等待消息被提交,则可以使⽤10ms的量级。然⽽, producer 也可以指定它 想要完全异步地执⾏发送,或者它只想等待直到 leader 节点拥有该消息(follower 节点有没有⽆所谓)。 现在让我们从 consumer 的视⻆来描述语义。 所有的副本都有相同的 log 和相同的 offset。consumer 负责控 制它在 log 中的位置。如果 consumer 永远不崩溃,那么它可以将这个位置信息只存储在内存中。但如果 consumer 发⽣了故障,我们希望这个 topic partition 被另⼀个进程接管, 那么新进程需要选择⼀个合适的位 置开始进⾏处理。假设 consumer 要读取⼀些消息——它有⼏个处理消息和更新位置的选项。 1. Consumer 可以先读取消息,然后将它的位置保存到 log 中,Y后再对消息进⾏处理。在这种情况下,消 费者进程可能会在保存其位置之后,带还没有保存消息处理的输出之前发⽣崩溃。⽽在这种情况下,即使 在此位置之前的⼀些消息没有被处理,接管处理的进程将从保存的位置开始。在 consumer 发⽣故障的情 况下,这对应于“at-most-once”的语义,可能会有消息得不到处理。 49