KTable Reduce功能不尊重窗口

时间:2018-02-21 12:26:35

标签: apache-kafka apache-kafka-streams

要求: - 我们需要合并具有相同orderid的所有消息,并对合并的消息执行后续操作。

说明: - 下面的代码片段尝试捕获从特定租户收到的所有订单消息,并在等待特定时间段后尝试合并到单个订单消息 它做了以下事情

  1. 基于OrderId的重新分区消息。因此,每个订单消息都将使用tenantId和groupId作为其键
  2. 执行groupby键操作,然后进行窗口操作2分钟
  3. 窗口完成后执行减少操作。
  4. Ktable再次转换为流回,然后将其输出发送到另一个kafka主题
  5. 预期输出: - 如果在窗口期内有5条消息具有相同的订单ID。预计最终的kafka主题应该只有一条消息,它将是最后一个reduce操作消息。

    实际输出: - 看到所有5条消息,表示在调用reduce操作之前没有发生窗口化。在接收到每条消息时,kafka中看到的所有消息都有适当的减少操作。

    查询: - 在kafka流库版本0.11.0.0中,减少用于接受timewindow作为其参数的函数。我看到这在kafka流版本1.0.0中已被弃用。在下面的代码中完成的窗口化是否正确?在较新版本的kafka流库1.0.0中是否支持窗口化?如果是这样,那么在下面的代码片段中是否可以改进某些内容?

            String orderMsgTopic = "sampleordertopic";
    
            JsonSerializer<OrderMsg> orderMsgJSONSerialiser = new JsonSerializer<>();
            JsonDeserializer<OrderMsg> orderMsgJSONDeSerialiser = new JsonDeserializer<>(OrderMsg.class);
    
            Serde<OrderMsg> orderMsgSerde = Serdes.serdeFrom(orderMsgJSONSerialiser,orderMsgJSONDeSerialiser);
    
    
    
            KStream<String, OrderMsg> orderMsgStream = this.builder.stream(orderMsgTopic, Consumed.with(Serdes.ByteArray(), orderMsgSerde))
                                                                    .map(new KeyValueMapper<byte[], OrderMsg, KeyValue<? extends String, ? extends OrderMsg>>() {
                                                                        @Override
                                                                        public KeyValue<? extends String, ? extends OrderMsg> apply(byte[] byteArr, OrderMsg value) {
                                                                            TenantIdMessageTypeDeserializer deserializer = new TenantIdMessageTypeDeserializer();
                                                                            TenantIdMessageType tenantIdMessageType = deserializer.deserialize(orderMsgTopic, byteArr);
                                                                            String newTenantOrderKey = null;
                                                                            if ((tenantIdMessageType != null) && (tenantIdMessageType.getMessageType() == 1)) {
                                                                                Long tenantId = tenantIdMessageType.getTenantId();
                                                                                newTenantOrderKey = tenantId.toString() + value.getOrderKey();
                                                                            } else {
                                                                                newTenantOrderKey = value.getOrderKey();
                                                                            }
                                                                            return new KeyValue<String, OrderMsg>(newTenantOrderKey, value);
                                                                        }
                                                                    });
    
    
    
            final KTable<Windowed<String>, OrderMsg> orderGrouping = orderMsgStream.groupByKey(Serialized.with(Serdes.String(), orderMsgSerde))
                                                                                    .windowedBy(TimeWindows.of(windowTime).advanceBy(windowTime))
                                                                                    .reduce(new OrderMsgReducer());
    
    
            orderGrouping.toStream().map(new KeyValueMapper<Windowed<String>, OrderMsg, KeyValue<String, OrderMsg>>() {
                                                                        @Override
                                                                        public KeyValue<String, OrderMsg> apply(Windowed<String> key, OrderMsg value) {
                                                                            return new KeyValue<String, OrderMsg>(key.key(), value);
                                                                        }
                                                                    }).to("newone11", Produced.with(Serdes.String(), orderMsgSerde));
    

1 个答案:

答案 0 :(得分:0)

我意识到我已将StreamsConfig.CACHE_MAX_BYTES_BUFFERING_CONFIG设置为0,并将默认提交间隔设置为1000毫秒。改变这个值有助于我在某种程度上使窗口工作