Kafka事件到达保证模式

到達保証の種類意味注意事項At least once最低一回のイベントを送信イベントの損失はないが、重複が発生する可能性があるAt most once最大一回のイベントを送信イベントが再送されず、損失が発生する可能性があるExactly once確実に一回のイベントを送信イベントの損失も重複も発生しない

默认情况下至少执行一次。

至少一次

如果生产者从Kafka代理中收到确认(acknowledgement),并且acks=all,则表示该消息已经准确地写入了Kafka主题。

然而,如果生产者的ACK超时或遇到错误,我们可能会假设消息没有被写入Kafka主题,并尝试重新发送消息。

如果在经纪人发送ACK之前失败,并且消息已成功写入Kafka主题,那么通过此重试将导致消息被写入两次,因此将递送给终端消费者超过一次。这种方法可能会导致双重处理和不准确的结果。

最多一次

如果生产者在ack超时或返回错误时不进行重试,则该消息将不会被写入Kafka主题,因此可能无法传递给消费者。

大多数情况下都会被写入,但为避免重复,有时会接受消息无法通过的情况。

只有一次

即使制作人重试发送信息,该信息也只会成功传送到最终受众一次。

在中文中,完全一次是最理想的保证,但也很难理解。这是因为消息系统本身和生产消费消息的应用之间需要合作。

假设在成功消费消息后,将Kafka的消费者回滚到先前的偏移量,那么将再次接收从该偏移量到最新消息的所有消息。为了实现这一点,消息系统和客户端应用程序必须共同努力,实现Exactly Once。

必须考虑的障碍

经纪人可能会造成问题

Kafka是一个非常高度可靠、持久性和耐用性的系统,所有写入到分区的消息都将被保存和复制多个固定次数(记作n)。

在这种情况下,Kafka可以容忍n-1个经纪人的故障,只要至少有一个经纪人可用,分区就是可用的。

卡夫卡的复制协议确保当消息成功写入领导副本时,它将被复制到所有可用的副本。

从制片人到经纪人的通信有可能失败。

Kafka的持久性依赖于生产者从代理节点接收ack。即使没有收到ack,请求本身并不一定意味着失败。代理节点在写入消息后,在发送ack给生产者之前可能会崩溃。而且,在将消息写入主题之前也可能崩溃。由于生产者无法知道故障的性质,它被迫假设消息写入未成功,并强制进行重试。这导致相同的消息被重复记录在Kafka的分区日志中,使得终端消费者可能会接收到一条以上的相同消息。

客户失败了。

正确的一次性交付需要考虑到客户端的失败。但是,我们该如何判断客户端是真的出现故障了还是暂时被经纪人分割了呢?或者是应用程序暂停了呢?能够区分持续故障和暂时故障是非常重要的。

为了确保正确性,经纪人应该丢弃由僵尸生产者发送的消息。这同样适用于消费者。当新的客户端实例启动时,它必须从失败实例留下的状态中恢复,并且只有在安全的点开始处理。这意味着消费的偏移总是必须与生成的输出保持同步。

广告
将在 10 秒后关闭
bannerAds