【Kafka】Kafka 实现 Exactly-once

本文详细介绍了 Kafka 的 Exactly-once 语义实现,包括幂等性和事务特性。通过幂等性保证单个分区内的精确一次,通过事务支持跨分区原子写入。同时讨论了依赖业务控制和 Kafka 内置特性的策略,以及面临的问题和解决方案。
摘要由CSDN通过智能技术生成

本篇结构:

  • Kafka 三种语义
  • Kafka 故障
  • 保证 Exactly-once
  • 参考博客

一、Kafka 三种语义

在分布式系统中,构成系统的任何节点都是被定义为可以彼此独立失败的。比如在 Kafka 中,broker 可能会 crash,在 producer 推送数据至 topic 的过程中也可能会遇到网络问题。根据 producer 处理此类故障所采取的提交策略类型,有如下三种:

  1. at-least-once:如果 producer 收到来自 Kafka broker 的确认(ack)或者 acks = all,则表示该消息已经写入到 Kafka。但如果 producer ack 超时或收到错误,则可能会重试发送消息,客户端会认为该消息未写入 Kafka。如果 broker 在发送 Ack 之前失败,但在消息成功写入 Kafka 之后,此重试将导致该消息被写入两次,因此消息会被不止一次地传递给最终 consumer,这种策略可能导致重复的工作和不正确的结果。

  2. at-most-once:如果在 ack 超时或返回错误时 producer 不重试,则该消息可能最终不会写入 Kafka,因此不会传递给 consumer。在大多数情况下,这样做是为了避免重复的可能性,业务上必须接收数据传递可能的丢失。

  3. exactly-once:即使 producer 重试发送消息,消息也会保证最多一次地传递给最终consumer。该语义是最理想的,但也难以实现,因为它需要消息系统本身与生产和消费消息的应用程序进行协作。

二、Kafka 故障

理想状况,网络良好,代码没有错误,则 Kafka 可以保证 exactly-once,但生产环境错综复杂,故障几乎无法避免,主要有:

  1. Broker失败:Kafka 作为一个高可用、持久化系统,保证每条消息被持久化并且冗余多份(假设是 n 份),所以 Kafka 可以容忍 n-1 个 broker 故障,意味着一个分区只要至少有一个 broker 可用,分区就可用。Kafka 的副本协议保证了只要消息被成功写入了主副本,它就会被复制到其他所有的可用副本(ISR)。
  2. Producer 到 Broker 的 RPC 失败:Kafka 的持久性依赖于生产者接收broker 的 ack 。没有接收成功 ack 不代表生产请求本身失败了。broker 可能在写入消息后,发送 ack 给生产者的时候挂了,甚至 broker 也可能在写入消息前就挂了。由于生产者没有办法知道错误是什么造成的,所以它就只能认为消息没写入成功,并且会重试发送。在一些情况下,这会造成同样的消息在 Kafka 分区日志中重复,进而造成消费端多次收到这条消息。
  3. 客户端也可能会失败:Exactly-once delivery 也必须考虑客户端失败的情况。但是如何去区分客户端是真的挂了(永久性宕机)还是说只是暂时丢失心跳?追求正确性的话,broker 应该丢弃由 zombie producer 发送的消息。 consumer 也是如此,一旦新的客户端实例已经启动,它必须能够从失败实例的任何状态中恢复,并从安全点( safe checkpoint )开始处理,这意味着消费的偏移量必须始终与生成的输出保持同步。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值