如何在不延迟flink的情况下发出处理事件的结果

时间:2019-06-26 18:26:02

标签: apache-flink flink-streaming

我们正在考虑将flink用于一个用例,但不确定flink是否适合它。这是我的用例。当事件e1到达时,我们需要对其进行处理并发出结果。源和接收器与该讨论无关,但是您可以将消息队列服务视为源和接收器。事件的整个处理独立于其他事件。因此,在处理事件e1时,我们不需要e2或任何其他事件。作为处理的一部分,我们需要执行下图所示的步骤1,步骤2,步骤3,步骤4。请注意,步骤2和步骤3应该并行进行。

enter image description here

事件的处理延迟对我们至关重要。因此,我需要在该元素处理完成后立即发出结果,而不是等待某些窗口超时。由于我对Flink的了解有限,所以我只能想到以下方法

DataStream<Map<String, Object>> step1 = env.addSource(...);
DataStream<Map<String, Object>> step2 = step1.map(...);
DataStream<Map<String, Object>> step3 = step1.map(...);

现在,如何合并步骤2和步骤3的结果并发出结果?在这个简单的示例中,我只有两个合并的蒸汽,但也可以大于两个。我可以结合流。我可以使用唯一的事件ID来对与特定事件相关的中间步骤的输出进行分组。

DataStream<Map<String, Object>> mergedStream = step1.union(step2).keyBy(...);

但是如何发出结果呢?理想情况下,我想说“从步骤2和步骤3获得特定键的输出后立即发射结果”,而不是“每30毫秒发射一次结果”。后者有两个问题:它可能会发出部分结果并且有延迟。有什么方法可以指定前者吗? 我正在探索Flink,但是如果它解决了我的用例,我愿意考虑其他选择。

1 个答案:

答案 0 :(得分:2)

在步骤1中,添加一个事件ID。然后,在合并之后,使用事件ID键入流,并使用RichFlatMapFunction将步骤2和3的结果组合回到单个事件中。如果步骤2和3发出EnrichedEvent类型的事件,则步骤4可以是:

static class FanIn extends RichFlatMapFunction<EnrichedEvent, EnrichedEvent> {
    private transient ValueState<EnrichedEvent> enrichmentResponseState;

    @Override
    public void flatMap(EnrichedEvent value, Collector<EnrichedEvent> out) throws Exception {
        EnrichedEvent response = enrichmentResponseState.value();

        if (response != null) {
            response = response.combine(value);
        } else {
            response = value;
        }

        if (response.isComplete()) {
            out.collect(response);
            enrichmentResponseState.clear();
        } else {
            enrichmentResponseState.update(response);
        }
    }

    @Override
    public void open(Configuration config) {
        ValueStateDescriptor<EnrichedEvent> fanInStateDescriptor =
            new ValueStateDescriptor<>( "enrichmentResponse",
                TypeInformation.of(new TypeHint<EnrichedEvent>() {})
            );

        enrichmentResponseState = getRuntimeContext().getState(fanInStateDescriptor);
    }
}

然后,将合并的最终结果发送到接收器很简单。