Transformation各算子可以对Flink数据流进行处理和转化,是Flink流处理非常核心的API。

map

map算子对一个DataStream中的每个元素使用用户自定义的map函数进行处理,每个输入元素对应一个输出元素,最终整个数据流被转换成一个新的DataStream。输出的数据流DataStream[OUT]类型可能和输入的数据流DataStream[IN]不同。

flink map flatmap flink map flatmap区别_flink map flatmap

如业务需求可以对一些数据进行拼接字符,倍数扩大等场景使用。

我们可以重写MapFunctionRichMapFunction来自定义map函数:

我们新建一个map实现MapFunction接口并重写方法。我们实现的方法很简单就是将数据流中的元素拼接一段字符串。

flink map flatmap flink map flatmap区别_flink_02

将其作为参数传递到stream的map方法中。

但是运行时报错了

flink map flatmap flink map flatmap区别_java_03

这块我也研究了半天/(ㄒoㄒ)/~~,此处需要注意的是,map()方法传入的参数需要严格指定泛型,来适应上下文环境,否则就会报错。因为我们做出修改。

flink map flatmap flink map flatmap区别_java_04

运行后打印正常

flink map flatmap flink map flatmap区别_flink_05

filter

filter算子对每个元素进行过滤,过滤的过程使用一个filter函数进行逻辑判断。对于输入的每个元素,如果filter函数返回True,则保留,如果返回False,则丢弃。filter的输入和输出数据类型一致。

flink map flatmap flink map flatmap区别_flink_06

flink map flatmap flink map flatmap区别_flink map flatmap_07

flatMap

对于map()来说,实现MapFunction也只是支持一对一的转换。
那么有时候你需要处理一个输入元素,但是要输出一个或者多个输出元素的时候,就可以用到flatMap()。

有一个输出时,完全可以当作map来用

flink map flatmap flink map flatmap区别_flink map flatmap_08

flink map flatmap flink map flatmap区别_数据_09

flatMap支持一种特殊的数据类型Tuple

Tuple

Java API提供了Tuple1到Tuple25的类。Tuple的每个字段可以是任意的Flink支持的数据类型。关于Tuple中的数据访问,可以通过tuple.f4或者使用getter方法:tuple.getField(int position) 位置索引从0开始,比如一个Tuple2就可以理解为一个map但是相同的key不会重复,或者就是一个实体类。

flink map flatmap flink map flatmap区别_flink map flatmap_10

flink map flatmap flink map flatmap区别_flink map flatmap_11

flink map flatmap flink map flatmap区别_flink map flatmap_12

flink map flatmap flink map flatmap区别_flink_13

 我们也可以在此基础上进行汇总求和

flink map flatmap flink map flatmap区别_flink_14

flink map flatmap flink map flatmap区别_数据_15

flink map flatmap flink map flatmap区别_数据_16

注意,虽然flatMap可以完全替代mapfilter,但Flink仍然保留了这三个API,主要因为mapfilter的语义更明确,更明确的语义有助于提高代码的可读性。map可以表示一对一的转换,代码阅读者能够确认对于一个输入,肯定能得到一个输出;filter则明确表示发生了过滤操作。

keyBy

flink map flatmap flink map flatmap区别_flink_17

DataStream  ->  KeyedStrem 逻辑的将一个流拆分成不相交的分区,每个分区包含具有相同key的元素,在内部以hash的方式实现的

滚动聚合算子

这些算子可以针对KeyedStrem的每一个直流做聚合

 sum()

 min()

 max()

 minBy()

 maxBy()

flink map flatmap flink map flatmap区别_flink map flatmap_18

对于单一的基本类型的数据流,根本就无法进行分组操作。

所以我们创建一组简单的实体数据流进行keyBy操作。

flink map flatmap flink map flatmap区别_字段_19

flink map flatmap flink map flatmap区别_字段_20

keyBy参数类型有两种 int 和 string,而int类型的参数只适用于类型为tuple的数据,而我们的数据为pojo,所以需要传入string类型的字段。

flink map flatmap flink map flatmap区别_数据_21

还有一点值得注意的地方就是这两种方法的返回值的输出泛型是tuple类型

flink map flatmap flink map flatmap区别_flink_22

这是为什么呢?因为仔细观察keyBy的参数是(int...fields),说明可以传入多个参数。按多个key进行分组。多个key可能类型都不一样所以没法指定具体的分组后类型。所以就包装成了tuple类型返回。

flink map flatmap flink map flatmap区别_数据_23

max只是将实体中的max字段进行修改,其他字段并没有发生修改,优势会有歧义。

所以我们可以使用maxBy()

flink map flatmap flink map flatmap区别_数据_24

整个数据实体都发生了改变。

flink window

flink map flatmap flink map flatmap区别_flink_25

flink map flatmap flink map flatmap区别_flink map flatmap_26

flink map flatmap flink map flatmap区别_java_27

flink map flatmap flink map flatmap区别_java_28

flink time

flink map flatmap flink map flatmap区别_java_29

flink state

flink map flatmap flink map flatmap区别_字段_30

checkpoint

flink map flatmap flink map flatmap区别_flink map flatmap_31

savepoint

flink map flatmap flink map flatmap区别_flink_32