查看原文
其他

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

zhisheng zhisheng 2021-09-05

前言

之前在 Flink 从0到1学习—— Flink 不可以连续 Split(分流)? 讲过 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 代码就可以很清楚了解。

本文地址是:http://www.54tianzhisheng.cn/2019/08/18/flink-side-output/

END


关注我


公众号(zhisheng)里回复 面经、ES、Flink、 Spring、Java、Kafka、监控 等关键字可以查看更多关键字对应的文章

Flink 实战

1、《从0到1学习Flink》—— Apache Flink 介绍
2、《从0到1学习Flink》—— Mac 上搭建 Flink 1.6.0 环境并构建运行简单程序入门
3、《从0到1学习Flink》—— Flink 配置文件详解
4、《从0到1学习Flink》—— Data Source 介绍
5、《从0到1学习Flink》—— 如何自定义 Data Source ?
6、《从0到1学习Flink》—— Data Sink 介绍
7、《从0到1学习Flink》—— 如何自定义 Data Sink ?
8、《从0到1学习Flink》—— Flink Data transformation(转换)
9、《从0到1学习Flink》—— 介绍 Flink 中的 Stream Windows
10、《从0到1学习Flink》—— Flink 中的几种 Time 详解
11、《从0到1学习Flink》—— Flink 读取 Kafka 数据写入到 ElasticSearch
12、《从0到1学习Flink》—— Flink 项目如何运行?
13、《从0到1学习Flink》—— Flink 读取 Kafka 数据写入到 Kafka
14、《从0到1学习Flink》—— Flink JobManager 高可用性配置
15、《从0到1学习Flink》—— Flink parallelism 和 Slot 介绍
16、《从0到1学习Flink》—— Flink 读取 Kafka 数据批量写入到 MySQL
17、《从0到1学习Flink》—— Flink 读取 Kafka 数据写入到 RabbitMQ
18、《从0到1学习Flink》—— 你上传的 jar 包藏到哪里去了
19、大数据“重磅炸弹”——实时计算框架 Flink
20、《Flink 源码解析》—— 源码编译运行
21、为什么说流处理即未来?
22、OPPO数据中台之基石:基于Flink SQL构建实数据仓库
23、流计算框架 Flink 与 Storm 的性能对比
24、Flink状态管理和容错机制介绍
25、原理解析 | Apache Flink 结合 Kafka 构建端到端的 Exactly-Once 处理
26、Apache Flink 是如何管理好内存的?
27、从0到1学习Flink》——Flink 中这样管理配置,你知道?
28、从0到1学习Flink》——Flink 不可以连续 Split(分流)?
29、Flink 从0到1学习—— 分享四本 Flink 的书和二十多篇 Paper 论文
30、360深度实践:Flink与Storm协议级对比
31、Apache Flink 1.9 重大特性提前解读
32、如何基于Flink+TensorFlow打造实时智能异常检测平台?只看这一篇就够了
33、美团点评基于 Flink 的实时数仓建设实践
34、Flink 灵魂两百问,这谁顶得住?
35、一文搞懂 Flink 的 Exactly Once 和 At Least Once
36、你公司到底需不需要引入实时计算引擎?

Flink 源码解析



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


让我“好看” 

: . Video Mini Program Like ,轻点两下取消赞 Wow ,轻点两下取消在看

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存