前言
之前在 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 Windows10、《从0到1学习Flink》—— Flink 中的几种 Time 详解11、《从0到1学习Flink》—— Flink 读取 Kafka 数据写入到 ElasticSearch12、《从0到1学习Flink》—— Flink 项目如何运行?13、《从0到1学习Flink》—— Flink 读取 Kafka 数据写入到 Kafka14、《从0到1学习Flink》—— Flink JobManager 高可用性配置15、《从0到1学习Flink》—— Flink parallelism 和 Slot 介绍16、《从0到1学习Flink》—— Flink 读取 Kafka 数据批量写入到 MySQL17、《从0到1学习Flink》—— Flink 读取 Kafka 数据写入到 RabbitMQ18、《从0到1学习Flink》—— 你上传的 jar 包藏到哪里去了19、大数据“重磅炸弹”——实时计算框架 Flink20、《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 Once36、你公司到底需不需要引入实时计算引擎?
Flink 源码解析
知识星球里面可以看到下面文章
让我“好看”