https://dzone.com/articles/exactly-once-semantics-with-apache-kafka-1
了解Kafka的新功能-exactly one semantics(一次性语义),从数学的角度来看,这在分布式系统中是不可行的。
Kafka最近刚刚引入了一次性语义版本,即使生产者重试发送消息,该版本也只会给最终消费者传递一次消息。
这一主要版本引起了社区的许多关注,因为从数学的角度来看,在分布式系统中是不可行的。
Confluent的联合创始人兼Apache Kafka的联合创始人杰伊·克雷普斯(Jay Kreps)解释了它的可能性以及在这篇文章中Kafka是如何实现这一目标。
在这篇博客中,我们将讨论如何利用Kafka提供的一次性消息语义。
Apache Kafka提供的不同消息传递语义概述
“大多数一次性消息可能会丢失,但永远不会被重新发送。”
在这种情况下,即使生产者尝试重新发送消息,消息也仅向最终消费者传递一次。
完全一次的语义是最理想的保证,并且需要消息传递系统本身与生产和消费消息的应用程序之间的协作。
例如,如果在成功发送消息后,Kafka消费者倒回到先前的偏移量,您将再次收到从该偏移量到最新消息的所有消息。这说明了为什么消息传递系统和客户端应用程序必须合作才能完成一次语义。
为什么要使用Kafka的完全一次语义?
我们知道至少一次需要保证每条消息至少会保留一次,而不会丢失任何数据,但这可能会导致消息在流中重复。
例如,如果代理在发送ACK之前就失败了,但在将消息成功写入Kafka topic 之后,此重试将导致消息被写入两次,因此会重复发送给最终消费者。
在新的一次性语义中,Kafka的处理语义保证将消息只传递给最终消费者一次。通过以下方式加强了这一点:
- Idemptotent producers 幂等发送
- Atomic transactions 事物法送
Idempotent Producer(幂等发送)
幂等操作是可以多次执行的操作,而不会产生与仅执行一次操作不同的效果。
现在,在Kafka中,生产者发送可以认为是幂等操作,因此如果发生导致生产者重试的错误,生产者多次发送的相同消息,但Kafka broker日志将只记录一次。
幂等生成器确保在单个生成器的生命周期内将消息一次性传递到特定主题分区。
要打开此功能并每个分区获得完全一次语义 - 没有重复,没有数据丢失和按顺序语义 - 生产者使用以下属性配置:
enable.idempotence=true
启用此功能后,每个生产者都会获得一个唯一ID(PID),并且每条消息都会与序列号一起发送。当代理或连接失败,并且生产者试图重新发送消息时,只有当该消息的序列号比最后一个消息多一个时才会被接受。
但是,如果生产者出现失败并重新启动,它将获得一个新的PID。因此,唯一生产者会话保证幂等性。
Atomic Transactions(原子事物)
Kafka现在通过新的事务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();
}
}
Consumers(消费者)
为了使用事务,我们需要为Consumer配置正确的isolation.level并使用新的Producer API。 Kafka消费者现在有两个新的隔离级别:
- read_committed:提交事务后,读取两种消息(那些不属于事务的消息)。
- read_uncommitted:按照偏移顺序读取所有消息,从而无需等待提交事务。此选项类似于Kafka使用者的当前语义。
此外,必须将transactional.id属性设置为producer配置中的唯一ID。此唯一ID可以保证跨应用程序重新启动的事务状态的连续性。
参考文档
- Confluent’s blog on exactly once semantics
- Transactions in Apache Kafka
- Image source for comparison between favorable and gone cases of at least once semantics