Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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 streams 如何在卡夫卡流中关闭窗口时发送主题记录_Apache Kafka Streams_Windowed - Fatal编程技术网

Apache kafka streams 如何在卡夫卡流中关闭窗口时发送主题记录

Apache kafka streams 如何在卡夫卡流中关闭窗口时发送主题记录,apache-kafka-streams,windowed,Apache Kafka Streams,Windowed,所以我已经为此苦苦挣扎了几天,事实上。我正在使用4个主题的记录。我需要在一段时间内汇总这些记录。时间到了,我想向接收主题发送已批准或未批准的消息。这可能与卡夫卡流有关吗 它似乎把每一张唱片都放在了新的主题上,即使窗口还开着,但这并不是我想要的 下面是简单的代码: builder.stream(getTopicList(), Consumed.with(Serdes.ByteArray(), Serdes.ByteArray())) .flatMap(new ExceptionSafeKey

所以我已经为此苦苦挣扎了几天,事实上。我正在使用4个主题的记录。我需要在一段时间内汇总这些记录。时间到了,我想向接收主题发送已批准或未批准的消息。这可能与卡夫卡流有关吗

它似乎把每一张唱片都放在了新的主题上,即使窗口还开着,但这并不是我想要的

下面是简单的代码:

 builder.stream(getTopicList(), Consumed.with(Serdes.ByteArray(), 
 Serdes.ByteArray()))
.flatMap(new ExceptionSafeKeyValueMapper<String, 
 FooTriggerMessage>("", Serdes.String(),
       fooTriggerSerde))
 .filter((key, value) -> value.getTriggerEventId() != null)
 .groupBy((key, value) -> value.getTriggerEventId().toString(),
       Serialized.with(Serdes.String(), fooTriggerSerde))

.windowedBy(TimeWindows.of(TimeUnit.SECONDS.toMillis(30))
.advanceBy(TimeUnit.SECONDS.toMillis(30)))

.aggregate(() -> new BarApprovalMessage(), /* initializer */
       (key, value, aggValue) -> getApproval(key, value, aggValue),/*adder*/
       Materialized
               .<String, BarApprovalMessage, WindowStore<Bytes, byte[]>>as(
                       storeName) /* state store name */
               .withValueSerde(barApprovalSerde))
.toStream().to(appProperties.getBarApprovalEngineOutgoing(), 
Produced.with(windowedSerde, barApprovalSerde));
builder.stream(getTopicList(),consumered.with(Serdes.ByteArray(),s),
Serdes.ByteArray())
.flatMap(新的例外情况SafeKeyValueMapper(“),Serdes.String(),
fooTriggerSerde)
.filter((键,值)->value.getTriggerEventId()!=null)
.groupBy((键,值)->value.getTriggerEventId().toString(),
序列化的.with(Serdes.String(),fooTriggerSerde))
.windowedBy(TimeWindows.of(TimeUnit.SECONDS.toMillis(30))
.advanceBy(时间单位为秒。托米利斯(30)))
.aggregate(()->new BarApprovalMessage(),/*初始值设定项*/
(key,value,aggValue)->getApproval(key,value,aggValue),/*加法器*/
具体化
.作为(
storeName)/*状态存储名称*/
.带ValueSerde(barApprovalSerde))
.toStream().to(appProperties.getBarApprovalEngineOutgoing(),
制作。使用(windowedSerde、Baraprovalsorde));
到目前为止,每一条记录都被放到了主题上,可以说,我只希望它在窗口关闭时发送一条消息


这可能吗?

如果其他人需要答案,我会回答自己的问题。在转换阶段,我使用上下文创建了一个调度程序。此计划程序接受三个参数。要加标点的时间间隔、要使用的时间(挂钟或流时间)和供应商(满足时间要求时调用的方法)。我使用了挂钟时间,并为每个唯一的窗口键启动了一个新的调度程序。我将每条消息添加到KeyValue存储中并返回null。然后,在每30秒调用一次的方法中,我检查窗口是否关闭,并迭代密钥库中的消息,聚合并使用context.forward和context.commit。中提琴!在30秒内收到4条消息,生成一条消息

您可以使用抑制功能

卡夫卡官方指南:


我遇到了这个问题,但我解决了这个问题,在固定窗口之后添加了grace(0)并使用了抑制API

public void process(KStream<SensorKeyDTO, SensorDataDTO> stream) {

        buildAggregateMetricsBySensor(stream)
                .to(outputTopic, Produced.with(String(), new SensorAggregateMetricsSerde()));

    }

private KStream<String, SensorAggregateMetricsDTO> buildAggregateMetricsBySensor(KStream<SensorKeyDTO, SensorDataDTO> stream) {
        return stream
                .map((key, val) -> new KeyValue<>(val.getId(), val))
                .groupByKey(Grouped.with(String(), new SensorDataSerde()))
                .windowedBy(TimeWindows.of(Duration.ofMinutes(WINDOW_SIZE_IN_MINUTES)).grace(Duration.ofMillis(0)))
                .aggregate(SensorAggregateMetricsDTO::new,
                        (String k, SensorDataDTO v, SensorAggregateMetricsDTO va) -> aggregateData(v, va),
                        buildWindowPersistentStore())
                .suppress(Suppressed.untilWindowCloses(unbounded()))
                .toStream()
                .map((key, value) -> KeyValue.pair(key.key(), value));
    }


    private Materialized<String, SensorAggregateMetricsDTO, WindowStore<Bytes, byte[]>> buildWindowPersistentStore() {
        return Materialized
                .<String, SensorAggregateMetricsDTO, WindowStore<Bytes, byte[]>>as(WINDOW_STORE_NAME)
                .withKeySerde(String())
                .withValueSerde(new SensorAggregateMetricsSerde());
    }
公共作废流程(KStream流){
buildAggregateMetricsBySensor(流)
.to(outputTopic,producted.with(String(),new SensorAggregateMetricsSerde());
}
专用KStream buildAggregateMetricsBySensor(KStream stream){
回流
.map((key,val)->新的KeyValue(val.getId(),val))
.groupByKey(分组为.with(String(),new SensorDataSerde())
.windowedBy(TimeWindows.of(持续时间分钟)(窗口大小以分钟为单位)).grace(持续时间百万分(0)))
.聚合(SensorAggregateMetricsDTO::新建,
(字符串k,传感器数据到v,传感器聚合技术到va)->聚合数据(v,va),
buildWindowPersistentStore())
.suppress(supprested.untilwindowclose(unbounded()))
.toStream()
.map((key,value)->KeyValue.pair(key.key(),value));
}
私有物化buildWindowPersistentStore(){
回报物化
.as(窗口\商店\名称)
.withKeySerde(字符串())
.带ValueSerde(新传感器聚合矩阵顺序());
}
在这里你可以看到结果


是否有可能重复使用此示例代码?这将非常有帮助,我正在为会话窗口开发一个类似的用例。我写了一篇关于它的博客文章。它是用瑞典语写的,但我猜代码部分无论如何都是有意义的。如果没有,我可以试着把它贴出来!非常感谢!大部分都是有意义的,因为我的用例有点不同,所以工作缓慢(不能安排固定的等待,因为会话可能没有完成)。然而,在您的示例中,“调度器”来自哪里?我不确定类型是什么,也没有看到它在任何地方被声明。事实上,对于sentIdsList来说,这是一个相同的问题,我想你应该把它传递给已经发送的内容的映射。这是一个状态存储,还是来自不同的东西?调度程序持有可取消项。我在变压器里申报。使用context.schedule在给定间隔处加标点。Sentidslist是一个全局变量。但是我认为你不需要关于那个的信息:)酷!然后我的黑客不再需要:)标记这是解决方案!这对活动时间来说不是仍然有效吗。如果我们想用挂钟时间来抑制呢?