Kafka学习笔记:Kafka 消息交付可靠性保障以及精确处理一次语义的实现

  • 日期:03-10
  • 点击:(914)


幂等生成器只能保证消息在单个分区和单个会话上的幂等性;事务可以确保跨分区和会话的幂等性。

所谓消息传递的可靠性保证是指卡夫卡对生产者和消费者所处理的消息提供了什么样的承诺。

有三个常见的承诺:

最多一次:信息可能会丢失,但不会再发送。

至少一次:消息不会丢失,但可能会重复发送。[卡夫卡默认选项]

仅此一次:信息不会丢失或重复发送。

只有当代理成功“提交”消息,并且生产者收到代理的回复时,该消息才被视为已成功发送。但是,如果消息成功“提交”,但代理的响应没有成功发送回生产者(例如,网络中存在瞬时抖动),生产者无法确定消息是否真正成功提交。因此,它只能选择重试,即再次发送相同的消息。这就是为什么默认情况下卡夫卡至少提供一次可靠性保证,但这将导致消息被重复发送。

卡夫卡也可以提供最多一次的交付保证,只是要求生产者禁止重试。这样,消息要么写得成功,要么写得不成功,但绝不会重复发送。我们通常不想丢失信息,但是在某些场景中偶尔丢失信息是允许的。相反,消息复制是绝对避免的。此时,最合适的是使用最一次性的交货保证。

卡夫卡做的正是:幂等与交易。

幂等性定义

“幂等性”最初是数学领域中的一个概念,它意味着某些运算或函数可以被执行多次,但每次得到的结果是相同的。

在计算机领域,幂等性的含义略有不同:

在命令式编程语言(如C语言)中,如果子程序是幂等的,它不能修改系统状态。这样,不管这个子程序运行多少次,与这个子程序相关的系统状态部分保持不变。

在函数式编程语言(如Scala或Haskell)中,许多纯函数自然是幂等的,不会产生任何副作用。

幂等性有许多优点,它最大的优点是我们可以安全地重试任何幂等性操作,这无论如何都不会破坏我们的系统状态。

幂等生产者

在卡夫卡中,生产者在默认情况下不是幂等的,但是我们可以创建幂等生产者。

指定生产者幂等元的方法非常简单,只需要设置一个参数。

即props.put(“使能.幂等”,图片),或

props.put(生产者配置.使能_幂等配置,真)。当

enable .幂等性设置为真时,生成器将自动升级为幂等生成器,并且不需要更改所有其他代码逻辑。

卡夫卡会自动帮你重复留言。

底层的具体原理非常简单,这是用空间换时间的经典优化思想,也就是说,在代理端节省更多的字段。当生产者发送具有相同字段值的消息时,代理可以自动知道这些消息已经被重复,因此它可以在后台无声地“丢弃”它们。当然,实际的实现原理并不那么简单,但是你可以大致这样理解它。

首先,它只能保证单个分区上的幂等性,也就是说,幂等性生成器可以保证某个主题的一个分区上没有重复的消息,并且它不能实现多个分区的幂等性。其次,它只能在单个会话上实现幂等性,而不能在跨会话上实现幂等性。这里的对话可以理解为生产者过程的运行。当您重新启动生成器进程时,这种幂等保证会丢失。

意识到多个分区和多个会话上的消息不会重复。我该怎么办?

答案是交易或依赖交易生产者。

事务定义

事务提供的安全保证是典型的ACID。

即原子性、一致性、隔离性和持久性。

read committed isolation level

所谓的read committed是指在读取数据库时,只能看到提交的数据,即没有脏读。

同时,当写入数据库时,只有提交的数据可以被覆盖,也就是说,没有脏写。

kafka当前处于读提交隔离级别。

它可以确保多个消息被自动写入目标分区,同时,它可以确保消费者只能看到事务成功提交的消息。

Transactional Producer

Transactional Producer可以确保消息被自动写入多个分区。这批消息要么全部写成功,要么全部失败。此外,事务性生产者不怕重新启动流程。生产者重新启动后,卡夫卡仍然确保他们发送的消息只被处理一次。

设置事务生成器的方法也很简单,满足两个要求:

就像幂等生成器一样,enable .幂等=true。

设置生产者端参数Transactional.id。最好为它设置一个有意义的名称。

代码示例

与普通的生产者代码相比,事务生产者的特征是调用一些事务API:

initTransaction :事务初始化

beginTransaction :交易开始

committation:事务提交

abortTransaction :交易终止

此代码可确保记录1和记录2作为交易提交给卡夫卡,要么全部成功提交,要么全部失败写入。

事实上,即使写入失败,卡夫卡也会将它们写入底层日志,这意味着消费者仍然会看到这些消息。

因此,在消费者端,读取事务性生产者发送的消息也需要一些改变。

修改也很简单,只需设置隔离级别参数的值。

当前,该参数有两个值:

read_uncommitted:这是默认值,表示消费者可以读取卡夫卡写的任何消息,无论事务生产者是提交事务还是终止事务,消费者写的消息都可以被读取。如果使用事务生产者,则相应的消费者不使用该值。

read_committed:表示使用者只会读取交易产生器成功提交交易写入的讯息。当然,它也可以看到由非事务性生产者编写的所有消息。

原引:

卡夫卡核心技术与实战-胡