Flink Transformation - 转换算子全面解析
一、引言
在Flink的数据流处理中,转换算子(Transformation Operators)扮演着极为关键的角色。它们能够对输入的数据流进行各种处理和转换操作,以满足不同的业务需求。本文将详细介绍Flink中常见的转换算子,包括map
、flatMap
、filter
、keyBy
、reduce
、union
、connect
以及各种物理分区算子,并结合代码示例进行深入讲解。
二、常用转换算子
(一)map算子
map
算子用于将一个数据流中的每个元素进行一对一的转换。例如,假设有如下数据,我们可以将其转换为一个LogBean
对象并输出。首先,读取本地文件的方式如下:
DataStream<String> lines = env.readTextFile("./data/input/flatmap.log");
假设LogBean
类有相应的字段定义(例如String field1; String field2;
等),map
算子的使用示例如下:
DataStream<LogBean> logBeanStream = lines.map(new MapFunction<String, LogBean>() {
@Override
public LogBean map(String line) throws Exception {
// 解析line并创建LogBean对象
LogBean logBean = new LogBean();
// 设置LogBean的各个字段值
return logBean;
}
});
(二)FlatMap算子
FlatMap
算子将数据流中的每个元素转换为零个、一个或多个元素。例如,读取flatmap.log
文件中的数据,如“张三,苹果手机,联想电脑,华为平板”,可以转换为“张三有苹果手机”“张三有联想电脑”“张三有华为平板”等。代码演示如下:
DataStream<String> lines = env.readTextFile("./data/input/flatmap.log");
DataStream<String> resultStream = lines.flatMap(new FlatMapFunction<String, String>() {
@Override
public void flatMap(String line, Collector<String> collector) throws Exception {
String[] items = line.split(",");
for (int i = 1; i < items.length; i++) {
collector.collect(items[0] + "有" + items[i]);
}
}
});
(三)Filter算子
Filter
算子用于根据指定的条件过滤数据流中的元素。例如,读取a.log
文件中的访问日志数据,过滤出访问IP是83.149.9.216
的访问日志:
DataStream<String> lines = env.readTextFile("./data/input/a.log");
DataStream<String> filteredStream = lines.filter(new FilterFunction<String>() {
@Override
public boolean filter(String line) throws Exception {
// 解析line获取IP并判断是否为目标IP
String ip = parseIPFromLine(line);
return "83.149.9.216".equals(ip);
}
});
(四)KeyBy算子
在流处理中,KeyBy
算子类似于批处理中的groupBy
,用于按照指定的键对数据进行分组。KeySelector
对象可以支持元组类型,也可以支持POJO(如Entry
、JavaBean
)。
- 元组类型:
- 单个字段
keyBy
:例如,对于一个包含Tuple2<String, Integer>
类型的数据流,如果要按照第一个字段(String
类型)进行分组,可以这样写:
- 单个字段
DataStream<Tuple2<String, Integer>> tupleStream =...;
KeyedStream<