如何使用Exactly-once模式实现Processor API

时间:2017-08-20 08:31:56

标签: apache-kafka apache-kafka-streams

我正在学习Kafka Stream并使用Processor API来实现我的用例。下面的代码显示了Process方法,该方法将消息转发到下游并在调用std::isdigit之前中止。这会导致流被重新处理并复制接收器上的消息。

commit

processing.guarantee参数:

public void process(String key, String value) {

    context.forward(key, value);

    .. 
    ..
    //killed

    context.commit();
}

是否有办法仅在调用streamsConfiguration.put(StreamsConfig.PROCESSING_GUARANTEE_CONFIG, StreamsConfig.EXACTLY_ONCE); 语句时应用转发。如果没有,那么实现Exactly-once模式的正确方法是什么。

谢谢

2 个答案:

答案 0 :(得分:2)

确保您的接收器处于read_committed消费者模式,因此它只会看到已提交的消息。如果在事务中止之前将消息写入输出主题,则在中止时,消息仍然存在,只是没有标记为已提交。第二次完成事务,因此将消息和提交标记添加到输出主题。如果您在没有处于read_committed模式的情况下阅读,那么您将看到所有消息(包括未提交的消息),并且它可能显示为重复消息,因为您会看到已中止的结果和已提交的结果。

来自0.11 javadoc https://kafka.apache.org/0110/javadoc/index.html?org/apache/kafka/clients/consumer/KafkaConsumer.html

  

在Kafka 0.11.0中引入了交易,其中应用程序可以   以原子方式写入多个主题和分区。为了这个   为了工作,应该配置从这些分区读取的消费者   只读取已提交的数据。这可以通过设置来实现   在消费者的配置中,isolation.level = read_committed。

     

在read_committed模式下,消费者将只读取那些   已成功提交的事务性消息。它会   像以前一样继续读取非事务性消息。没有   read_committed模式下的客户端缓冲。相反,结束偏移   read_committed使用者的分区的偏移量是   属于开放事务的分区中的第一条消息。   此偏移称为“最后稳定偏移”(LSO)。

     

read_committed消费者只会读到LSO并过滤掉   任何已中止的交易消息。 LSO也   影响seekToEnd(Collection)和的行为   read_committed消费者的endOffsets(Collection),详细信息   在每种方法的文档中。最后,获取延迟指标是   也调整为相对于read_committed消费者的LSO。   具有事务性消息的分区将包括提交或中止   指示交易结果的标记。有标记   没有返回到应用程序,但在日志中有一个偏移量。作为一个   结果,应用程序从具有事务性消息的主题中读取   将看到消耗的补偿中的差距。这些丢失的消息将是   交易标记,它们被过滤掉给消费者   两种隔离级别。此外,使用read_committed的应用程序   消费者也可能因为交易中止而出现差距   消费者不会返回消息,但会有消息   有效抵消。

答案 1 :(得分:-1)

您可能希望在finally块下包装context.commit()以确保它被调用。但是,您还需要确保在成功处理后确实调用它。