与apache Kafka的一次语义

卡夫卡的“一次语义学”是在最近推出的版本中引入的,它使消息能够准确地传递给最终消费者一次,即使生产者试图发送消息。

这一重大发布在社区中引起了许多人的注意,因为人们认为在分布式系统中这在数学上是不可能的。合流公司的联合创始人,阿帕奇卡夫卡的共同创建者杰伊克雷普斯解释了它的可能性,以及它是如何在卡夫卡实现的。岗.

在这个博客中,我们将讨论如何利用卡夫卡提供的一次消息语义。

ApacheKafka提供的不同消息传递语义综述
“最多一次-m要旨可能会丢失,但永远不会重来。“
在这种情况下,当ACK超时或返回错误时,生产者不会重试发送消息,因此消息可能最终不会写入Kafka主题,因此不会传递给使用者。

"至少有一次-消息永远不会丢失,但可能会被重新传递。"
在这种情况下,如果ACK超时或收到错误,生产者试图重新发送消息,假设消息没有写入Kafka主题。

" 一次— 这是人们真正想要的,每条信息只传递一次。"
在这种情况下,即使生产者试图重新发送消息,它也会导致消息被准确地传递一次给最终使用者。

准确地说,一次语义是最理想的保证,并且需要消息传递系统本身与生成和使用消息的应用程序之间的协作。

例如,如果在成功地使用了一条消息之后,您将您的Kafka使用者倒带到以前的偏移量,那么您将再次收到来自该偏移量的所有消息到最新的偏移量。这说明了为什么消息传递系统和客户端应用程序必须合作,以使语义发生精确一次。

为什么要用卡夫卡的一次语义学?
我们知道,至少一次保证每条消息至少保存一次,而不会丢失任何数据,但这可能会导致流中的重复。

例如,如果代理在发送ACK之前失败,但是在消息成功地写入Kafka主题之后,此重试将导致消息被写入两次,从而多次传递给最终使用者。

在新的完全一次语义学中,卡夫卡的处理语义保证了消息准确地传递给最终消费者一次。通过采取以下措施加强了这一点:

Idempate生产者

原子事务

幂等生产者
阿幂等操作是一种可以多次执行的操作,而不会产生与只执行一次操作不同的效果。

现在,在Kafka中,生产者发送的操作可以是幂等的,因此,如果发生错误导致生产者重试,生产者多次发送的相同消息将只被写入维护的Kafka Broker上的日志一次。

幂等生成器确保消息在单个生成器的生存期内准确地传递到特定的主题分区。

要打开此特性并获得准确的每个分区一次语义-意味着不存在重复、数据丢失和顺序语义-请使用以下属性配置您的生产者:

enable.idempotence=true
打开此功能后,每个生产者都会得到一个唯一的id(PID),并将每条消息与序列号一起发送。当代理或连接失败,并且生产者试图重新发送消息时,只有当该消息的序列号比最后一条消息多一个时,它才会被接受。

但是,如果生产者失败并重新启动,它将得到一个新的PID。因此,幂等性仅为单一生产者会议.

原子事务
Kafka现在通过新的事务API支持跨多个分区的原子写入。这允许生产者向多个分区发送一批消息,这样,批处理中的所有消息对所有使用者都是可见的,或者对任何使用者都是不可见的。

它允许您在同一个事务中提交您的使用者抵消和您处理过的数据,从而允许端到端精确地一次语义。

下面是一个示例片段,描述如何使用新的生产者API将消息原子地发送到一组主题分区:

{
producer.initTransactions();
try{
producer.beginTransaction();
producer.send(record0);
producer.send(record1);
producer.sendOffsetsToTxn(…);
producer.commitTransaction();
} catch( ProducerFencedException e) {
producer.close();
} catch( KafkaException e ) {
producer.abortTransaction();
}
}
消费者
若要使用事务,需要将使用者配置为使用以下权限孤立无援并使用新的生产者API。卡夫卡消费者现在有两个新的隔离级别:

读承诺:在提交事务后读取两种类型的消息(那些不是事务的一部分并且是事务的消息)。
读未承诺:按偏移顺序读取所有邮件,而不等待事务提交。此选项类似于卡夫卡消费者当前的语义。
此外,transactional.id属性必须设置为生产者配置中的唯一ID。需要这个唯一的ID来提供跨应用程序重新启动的事务状态的连续性。

参考文献
CONFLUENT关于同一语义的博客
Apache Kafka中的事务
图像源比较至少一次语义的有利和消失的情况

猜你喜欢

转载自blog.51cto.com/14009535/2307982