Flink 从0到1学习 —— 如何使用 Side Output 来分流?

Posted zhisheng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Flink 从0到1学习 —— 如何使用 Side Output 来分流?相关的知识,希望对你有一定的参考价值。

前言

之前在  讲过 Flink 使用连续的 Split 会有问题,当时提供了几种解决方法,有一种方法就是使用 Side Output 来进行,当时留了个余念,那么就在这篇文章详细的讲一波,教大家如何使用 Side Output 来分流。

Side Output

通常我们在处理数据的时候,有时候想对不同情况的数据进行不同的处理,那么就需要把数据流进行分流。比如我们在那篇文章里面的例子:需要将从 Kafka 过来的告警和恢复数据进行分类拆分,然后在对每种数据再分为告警数据和恢复数据。

如果是使用 filter 来进行拆分,也能满足我们的需求,但每次筛选过滤都要保留整个流,然后通过遍历整个流来获取相应的数据,显然很浪费性能。假如能够在一个流里面就进行多次输出就好了,恰好 Flink 的 Side Output 则提供了这样的功能。

如何使用?

要使用 Side Output 的话,你首先需要做的是定义一个 OutputTag 来标识 Side Output,代表这个 Tag 是要收集哪种类型的数据,如果是要收集多种不一样类型的数据,那么你就需要定义多种 OutputTag。例如:如果我要将告警/恢复的数据分为机器、容器、中间件等的数据,那么我们起码就得定义三个 OutputTag,如下:

private static final OutputTag<AlertEvent> middleware = new OutputTag<AlertEvent>("MIDDLEWARE") {
};
private static final OutputTag<AlertEvent> machine = new OutputTag<AlertEvent>("MACHINE") {
};
private static final OutputTag<AlertEvent> docker = new OutputTag<AlertEvent>("DOCKER") {
};

然后呢,你可以使用下面几种函数来处理数据,在处理数据的过程中,进行判断将不同种类型的数据存到不同的 OutputTag 中去。

  • ProcessFunction

  • KeyedProcessFunction

  • CoProcessFunction

  • ProcessWindowFunction

  • ProcessAllWindowFunction

比如:

//dataStream 是总的数据流
SingleOutputStreamOperator<AlertEvent, AlertEvent> outputStream = dataStream.process(new ProcessFunction<AlertEvent, AlertEvent>() {
    @Override
    public void processElement(AlertEvent value, Context ctx, Collector<AlertEvent> out) throws Exception {
        if ("MACHINE".equals(value.type)) {
            ctx.output(machine, value);
        } else if ("DOCKER".equals(value.type)) {
            ctx.output(docker, value);
        } else if ("MIDDLEWARE".equals(value.type)) {
            ctx.output(middleware, value);
        } else {
            //其他的业务逻辑
            out.collect(value);
        }
    }
})

好了,既然上面我们已经将不同类型的数据进行放到不同的 OutputTag 里面了,那么我们该如何去获取呢?你可以使用 getSideOutput 方法来获取不同 OutputTag 的数据,比如:

//机器相关的告警&恢复数据
outputStream.getSideOutput(machine).print();

//容器相关的告警&恢复数据
outputStream.getSideOutput(docker).print();

//中间件相关的告警&恢复数据
outputStream.getSideOutput(middleware).print();

这样你就可以获取到 Side Output 数据了。

另外你还可以看下我在 Github 放的一个完整 demo 代码: https://github.com/zhisheng17/flink-learning/blob/master/flink-learning-examples/src/main/java/com/zhisheng/examples/streaming/sideoutput/Main.java

总结

本文讲了如何使用 Side Output 来进行分流,比较简单,大家可以稍微阅读一下 demo 代码就可以很清楚了解。

END


关注我

Flink 从0到1学习 —— 如何使用 Side Output 来分流?


Flink 实战




































Flink 源码解析

Flink 从0到1学习 —— 如何使用 Side Output 来分流?

知识星球里面可以看到下面文章


让我“好看” 

以上是关于Flink 从0到1学习 —— 如何使用 Side Output 来分流?的主要内容,如果未能解决你的问题,请参考以下文章

《从0到1学习Flink》—— Flink 项目如何运行?

Flink 源码解析 —— 如何获取 StreamGraph?

《从0到1学习Flink》—— Flink 写入数据到 ElasticSearch

《从0到1学习Flink》—— Flink 写入数据到 Kafka

Flink 源码解析 —— 项目结构一览

Flink 源码解析 —— Flink JobManager 有什么作用?