Kafka Streams:处理器有时在应用程序重新启动时处理相同的消息

时间:2019-04-22 11:28:53

标签: java apache-kafka apache-kafka-streams

在我的Java应用程序中,我有一个Kafka处理器。

我的处理方法如下:

@Override
public void process(String key, String value) {
    System.out.println("In the process method, the offset is: " + context.offset());
    //Some more code
}

其中context是init方法中的ProcessorContext。

我启动了应用程序,并记录了该信息:

In the process method, the offset is: 1203
In the process method, the offset is: 1204

然后,我再次启动该应用程序,并且得到相同的消息。几个应用程序重新启动后(或一段时间后,我找不到模式),process方法停止调用,并且在应用程序启动时不再收到这些消息。

您知道为什么有时有时会多次处理这些消息吗?

“我的流配置”具有以下属性:

props.put(StreamsConfig.APPLICATION_ID_CONFIG, "someId");
props.put(StreamsConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
props.put(StreamsConfig.DEFAULT_KEY_SERDE_CLASS_CONFIG, Serdes.StringSerde.class.getName());
props.put(StreamsConfig.DEFAULT_VALUE_SERDE_CLASS_CONFIG, Serdes.StringSerde.class.getName());
props.put(StreamsConfig.DEFAULT_TIMESTAMP_EXTRACTOR_CLASS_CONFIG, WallclockTimestampExtractor.class.getName());
props.put(StreamsConfig.NUM_STREAM_THREADS_CONFIG, 10);
props.put(StreamsConfig.STATE_DIR_CONFIG, "somedir");

编辑

下面的代码段显示了我如何创建KafkaStreams:

public class KafkaStreamsProcessorBean implements SmartLifecycle {
    @Override
    public synchronized void start() {
        final KStreamBuilder builder = new KStreamBuilder();

        final KStream<String, String> debeziumStream = builder.stream("debezium.topic");
        debeziumStream.process(() -> debeziumProcessor);

        kafkaStreams = new KafkaStreams(builder, streamsConfig);
        kafkaStreams.start();
    }
}

在这里,streamsConfig是具有我显示的属性的配置,而debeziumProcessor是第一个代码段中的Kafka处理器。

1 个答案:

答案 0 :(得分:4)

默认情况下,Kafka Streams的处理保证为至少一次。这意味着可以对邮件进行重新处理。

就您而言,即使您将StreamsConfig.PROCESSING_GUARANTEE_CONFIG设置为StreamsConfig.EXACTLY_ONCE,重启后也会看到相同的日志(具有相同的偏移量信息)。

处理保证是关于在一次交易中向主题写入偏移量结果。 这并不意味着消息不能多次被处理(使用相同的键和值多次调用Processor :: process(...)。

可能出现以下情况:

  • 已阅读邮件。
  • Processor::process(...)被呼叫。
  • 应用程序完成后未写入偏移量。
  • 重启后,应用程序将读取相同的消息,并且将调用Processor::process(...)中相同的键和值