Kafka Streams:不会发生

时间:2018-07-09 09:58:45

标签: apache-kafka apache-kafka-streams stream-processing

我是Kafka Streams的新手,我想尝试在超时情况下kafka Streams的行为。

这是我正在使用Processor API测试的场景:

  • 我的kafka流应用程序从kafka主题(字符串键,字符串消息)中消费并写入kafka主题(字符串键,字符串消息)

  • 我已将使用者配置参数max.poll.interval.ms设置为60000 ms。

  • 我的处理方法如下:

    public void process(String key, String value) {
        System.out.println("the key is : " +key);
        LocalDateTime start= LocalDateTime.now();
        System.out.println("startTime:" + dtf.format(start));
        if ( key.startsWith("12345678"){
            Thread.sleep(80000);
        }
        System.out.println("done sleeping");
        LocalDateTime end=LocalDateTime.now();
        System.out.println("endTime:" + dtf.format(end));
        System.out.println("Offset*****"+context.offset()+" 
            partitionId****"+context.partition()+"taskId*****"+context.taskId()+ 
            "javaThreadId*******"+ Thread.currentThread().getId()+ " 
            value****"+value);
    }
    
  • 所有其他配置均设置为默认值。

  • 我正在尝试查看如果处理时间超过max.poll.interval.ms时应用程序的行为。

会发生以下情况: 第一次尝试时,它开始使用kafka主题中的消息,并在调用process()时开始休眠。 60000 ms之后,它再次调用process方法,没有引发任何异常,但是此时,它仅在20000 ms打印中退出睡眠状态,“ done sleep”并发送消息到输出主题。此后,它再次从相同的偏移量开始消耗相同的消息,而无需提交。这是循环发生的。

示例输出:

密钥是:12345678

开始时间:2018/07/09 07:34:25

密钥是:12345678

开始时间:2018/07/09 07:35:27

睡着了

结束时间:2018/07/09 07:35:45

Offset ***** 224 partitionId **** 0taskId ***** 0_0javaThreadId ******* 12 value **** abc

密钥是:12345678

开始时间:2018/07/09 07:36:27

睡着了

结束时间:2018/07/09 07:36:47

Offset ***** 224 partitionId **** 0taskId ***** 0_0javaThreadId ******* 14 value **** abc

密钥是:12345678

开始时间:2018/07/09 07:37:27

睡着了

结束时间:2018/07/09 07:37:47

Offset ***** 224 partitionId **** 0taskId ***** 0_0javaThreadId ******* 12 value **** abc

  • 我尝试显式调用context#commit(),但它也不起作用。我在这里想念什么? kafka流会记住以前的处理状态吗?如果不是,为什么在第一次尝试后20000毫秒之后准确地说“完成睡眠”(mall.poll.interval.ms-60000,处理时间(睡眠)设置为80000毫秒)?

其他信息:

  • 我的输入和输出主题每个都有2个分区,并且我已经将StreamsConfig num.streams.threads配置为2。

  • 我有一个3节点的kafka集群-Kafka和Kafka Streams版本1.1.0

  • 我不在任何地方使用标点方法或任何复杂的处理。

谢谢。

1 个答案:

答案 0 :(得分:1)

不确定100%,但是请注意:如果您调用context#commit()只是“请求”一个提交,而Kafka Streams试图尽快提交-但是在返回context#commit()之后,该提交尚未发生...

还要注意,如果您的超时时间是60.000,而您睡了80.000,则应将应用程序从使用者组中删除,因此,不允许再提交该应用程序。在这种情况下,日志中应该有一个WARN日志消息。

希望这会有所帮助。