Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/apache-kafka/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Apache kafka Kafka在窗口打开和重新启动时对丢弃的消息进行流式处理_Apache Kafka_Apache Kafka Streams_Windowing - Fatal编程技术网

Apache kafka Kafka在窗口打开和重新启动时对丢弃的消息进行流式处理

Apache kafka Kafka在窗口打开和重新启动时对丢弃的消息进行流式处理,apache-kafka,apache-kafka-streams,windowing,Apache Kafka,Apache Kafka Streams,Windowing,我正在使用以下拓扑结构开发Kafka Streams应用程序: private final Initializer<Set<String>> eventInitializer = () -> new HashSet<>(); final StreamsBuilder streamBuilder = new StreamsBuilder(); final KStream<String, AggQuantityByPrimeValue>

我正在使用以下拓扑结构开发Kafka Streams应用程序:

private final Initializer<Set<String>> eventInitializer = () -> new HashSet<>();

final StreamsBuilder streamBuilder = new StreamsBuilder();

    final KStream<String, AggQuantityByPrimeValue> eventStreams = streamBuilder.stream("testTopic",
            Consumed.with(Serdes.String(), **valueSerde**));

    final  KStream<String, Value> filteredStreams = eventStreams
                .filter((key,clientRecord)->recordValidator.isAllowedByRules(clientRecord));

    final KGroupedStream<Integer, Value> groupedStreams = filteredStreams.groupBy(
        (key, transactionEntry) -> transactionEntry.getNodeid(),
        Serialized.with(Serdes.Integer(), **valueSerde**));

    /* Hopping window */
    final TimeWindowedKStream<Integer, Value> windowedGroupStreams = groupedStreams
        .windowedBy(TimeWindows.of(Duration.ofSeconds(30)).advanceBy(Duration.ofSeconds(25))
            .grace(Duration.ofSeconds(0)));

    /* Aggregating the events */
    final KStream<Windowed<Integer>, Set<String>> suppressedStreams = windowedGroupStreams
        .aggregate(eventInitializer, countAggregator, Materialized.as("counts-aggregate")
        .suppress(Suppressed.untilWindowCloses(Suppressed.BufferConfig.unbounded())
                .withName("suppress-window")
            .toStream();

    suppressedStreams.foreach((windowed, value) -> eventProcessor.publish(windowed.key(), value)); 

    return new KafkaStreams(streamBuilder.build(), config.getKafkaConfigForStreams());
private final Initializer eventInitializer=()->new HashSet();
最终StreamsBuilder streamBuilder=新StreamsBuilder();
最终KStream eventStreams=streamBuilder.stream(“testTopic”,
使用(Serdes.String(),**valueSerde**));
最终KStream filteredStreams=事件流
.filter((键,clientRecord)->recordValidator.isAllowedByRules(clientRecord));
最终KGroupedStream groupedStreams=filteredStreams.groupBy(
(键,transactionEntry)->transactionEntry.getNodeid(),
序列化的.with(Serdes.Integer(),**valueSerde**));
/*跳窗*/
最终时间WindowedKStream windowedGroupStreams=groupedStreams
.windowedBy(TimeWindows.of(持续时间秒(30)).advanceBy(持续时间秒(25))
.grace(持续时间为秒(0));
/*聚合事件*/
最终KStream suppressedStreams=windowedGroupStreams
.aggregate(eventInitializer、countAggregator、Materialized.as(“counts aggregate”)
.suppress(supprested.untilwindowcloss(supprested.BufferConfig.unbounded())
.withName(“抑制窗口”)
.toStream();
suppressedStreams.foreach((加窗,值)->eventProcessor.publish(加窗,键(),值));
返回新的KafkaStreams(streamBuilder.build(),config.getkafkanconfigforstreams());
我观察到,在窗口打开期间/之后,间歇性地很少有事件被丢弃。 例如:

  • 所有记录都可以在isAllowedByRules()方法中查看/打印,这些记录都是有效的(过滤器允许的)并由流使用
  • 但是当在countAggregator中打印事件时,我可以看到很少有事件没有通过它
流的当前配置:

Properties streamsConfig = new Properties();
streamsConfig.put(StreamsConfig.APPLICATION_ID_CONFIG,"kafka-app-id"
streamsConfig.put(StreamsConfig.BOOTSTRAP_SERVERS_CONFIG, <bootstraps-server>); 
streamsConfig.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "latest");
streamsConfig.put(StreamsConfig.COMMIT_INTERVAL_MS_CONFIG, 30000);
streamsConfig.put(StreamsConfig.NUM_STREAM_THREADS_CONFIG, 5);
streamsConfig.put(ConsumerConfig.HEARTBEAT_INTERVAL_MS_CONFIG, 10000);
streamsConfig.put(ConsumerConfig.SESSION_TIMEOUT_MS_CONFIG, 30000);
streamsConfig.put(ConsumerConfig.FETCH_MAX_BYTES_CONFIG, 10485760);
streamsConfig.put(ProducerConfig.MAX_REQUEST_SIZE_CONFIG, 10485760);
streamsConfig.put(ConsumerConfig.MAX_PARTITION_FETCH_BYTES_CONFIG, 10485760);
/*For window buffering across all threads*/
streamsConfig.put(StreamsConfig.CACHE_MAX_BYTES_BUFFERING_CONFIG, 52428800);

streamsConfig.put(StreamsConfig.DEFAULT_KEY_SERDE_CLASS_CONFIG, Serdes.Integer().getClass().getName());
streamsConfig.put(StreamsConfig.DEFAULT_VALUE_SERDE_CLASS_CONFIG, **customSerdesForSet**);
Properties streamsConfig=新属性();
streamsConfig.put(streamsConfig.APPLICATION\u ID\u CONFIG,“卡夫卡应用程序ID”
streamsConfig.put(streamsConfig.BOOTSTRAP_SERVERS_CONFIG,);
streamsConfig.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG,“最新”);
streamsConfig.put(streamsConfig.COMMIT\u INTERVAL\u MS\u CONFIG,30000);
streamsConfig.put(streamsConfig.NUM\u STREAM\u THREADS\u CONFIG,5);
streamsConfig.put(ConsumerConfig.HEARTBEAT\u INTERVAL\u MS\u CONFIG,10000);
streamsConfig.put(ConsumerConfig.SESSION\u TIMEOUT\u MS\u CONFIG,30000);
streamsConfig.put(ConsumerConfig.FETCH\u MAX\u BYTES\u CONFIG,10485760);
streamsConfig.put(ProducerConfig.MAX\u REQUEST\u SIZE\u CONFIG,10485760);
streamsConfig.put(ConsumerConfig.MAX\u PARTITION\u FETCH\u BYTES\u CONFIG,10485760);
/*用于跨所有线程的窗口缓冲*/
streamsConfig.put(streamsConfig.CACHE\u MAX\u BYTES\u BUFFERING\u CONFIG,52428800);
streamsConfig.put(streamsConfig.DEFAULT_KEY_SERDE_CLASS_CONFIG,Serdes.Integer().getClass().getName());
streamsConfig.put(streamsConfig.DEFAULT\u VALUE\u SERDE\u CLASS\u CONFIG,**customSerdesForSet**);
最初,我使用的是翻滚窗口,但我发现大多数情况下在窗口结束时,很少有事件丢失,所以我改为跳跃窗口(复制比丢失更好)。然后丢弃的事件变为零。但今天,在将近4天之后,我又看到了一些丢弃的事件,其中有一种模式,即与一起生成的其他事件相比,它们迟到了近一分钟。但预期这些迟到的事件会出现在未来的任何窗口中,但不会发生。对吗如果我的理解不正确的话

正如我在主题中提到的,在重新启动流时(优雅地),我可以看到在聚合步骤中很少有事件再次丢失,尽管是通过isAllowedByRules()方法处理的


我在堆栈溢出和其他站点上搜索了很多,但找不到这种行为的根本原因。这是否与我缺少/未正确设置的某些配置有关,或者可能是由于其他原因造成的?

据我所知,您的宽限期为空:

 /* Hopping window */
...
            .grace(Duration.ofSeconds(0))
所以你的窗口是关闭的,不允许任何迟到的人

那么关于你的子问题:

但人们期望这些迟来的事件会出现在未来的任何窗口中,但不会发生。如果我的理解不正确,请在此处更正。

也许你把事件时间和处理时间混在一起了。 如果记录的时间戳(由制作人在制作时添加,或由代理在到达集群时添加,如果不是由制作人设置),则您的记录将被归类为“延迟”

下面是一个包含2条记录“*”的示例

他们的活动时间(et1和et2)适合窗口:

 |    window       |
 t1                t2
 |      *    *     |
       et1  et2          

但是,et2(pt2)的处理时间实际上如下:

 |    window       |
 t1                t2
 |      *          |   *
       pt1            pt2

这里的窗口是t1和t2之间的一段时间(处理时间) et1和et2分别是2条记录“*”的事件时间。 et1和et2是在记录本身中设置的时间戳。 在本例中,et1和et2介于t1和t2之间,et2在窗口关闭后已收到,由于宽限期为0,因此将跳过


可能是一种解释

transactionEntry.getNodeid()可能会返回null(从而解释某些删除)?
但预期这些延迟事件会出现在未来的任何窗口中,但不会发生
——正如下面@Yannick的回答中所提到的,这在默认情况下不会发生,因为默认情况下使用了事件时间语义。可能会将
时间戳。提取器
更改为
WallclockTimestampExtractor
解决您的问题。Hi@MatthiasJ.Sax stream谢谢您的回复。它运行了很长一段时间,但我再次看到邮件被删除。在您的建议后,我将
时间戳。提取器
更改为
WallclockTimestampExtractor
。此外,我还添加了宽限期。当前配置为:Kafka窗口时间:30秒窗口提前时间:25秒宽限期:60秒提交间隔:100秒是否可能