Flink Data sink
sink 下沉,在flink数据处理过程中是为了将数据沉淀下来,换句话说,flink通过data source接入数据,然后在flink进行相关计算,然后操作后将计算后的数据结果sink到某个地方。
Data transformation
一般flink数据从source作为数据源,然后经过Transformation,所谓的transformation 就是数据转换的各种操作,有Map / FlatMap / Filter / KeyBy / Reduce / Fold / Aggregations / Window / WindowAll / Union / Window join / Split / Select / Project 等,操作很多,可以将数据转换为自己想要的数据。
- map
相对比较简单的转换之一,其中数据是个数据流,输出也是个数据流,举例:
SingleOutputStreamOperator<Student> map = student.map(new MapFunction<Student, Student>() {
@Override
public Student map(Student value) throws Exception {
Student s1 = new Student();
s1.id = value.id;
s1.name = value.name;
s1.password = value.password;
s1.age = value.age + 5;
return s1;
}
});
简单将每个对象中age数据+5
- FlatMap
采用一条记录并输出0个,1个或多个记录。
SingleOutputStreamOperator<Student> flatMap = student.flatMap(new FlatMapFunction<Student, Student>() {
@Override
public void flatMap(Student value, Collector<Student> out) throws Exception {
if (value.id % 2 == 0) {
out.collect(value);
}
}
});
- Fliter
函数根据条件判断出结果
SingleOutputStreamOperator<Student> filter = student.filter(new FilterFunction<Student>() {
@Override
public boolean filter(Student value) throws Exception {
if (value.id > 95) {
return true;
}
return false;
}
});
- KeyBy
KeyBy 在逻辑上是基于 key 对流进行分区。在内部,它使用 hash 函数对流进行分区。它返回 KeyedDataStream 数据流。
KeyedStream<Student, Integer> keyBy = student.keyBy(new KeySelector<Student, Integer>() {
@Override
public Integer getKey(Student value) throws Exception {
return value.age;
}
});
- Reduce
Reduce 返回单个的结果值,并且 reduce 操作每处理一个元素总是创建一个新值。常用的方法有 average, sum, min, max, count,使用 reduce 方法都可实现。
SingleOutputStreamOperator<Student> reduce = student.keyBy(new KeySelector<Student, Integer>() {
@Override
public Integer getKey(Student value) throws Exception {
return value.age;
}
}).reduce(new ReduceFunction<Student>() {
@Override
public Student reduce(Student value1, Student value2) throws Exception {
Student student1 = new Student();
student1.name = value1.name + value2.name;
student1.id = (value1.id + value2.id) / 2;
student1.password = value1.password + value2.password;
student1.age = (value1.age + value2.age) / 2;
return student1;
}
});
- Fold
Fold 通过将最后一个文件夹流与当前记录组合来推出 KeyedStream。 它会发回数据流。
KeyedStream.fold("1", new FoldFunction<Integer, String>() {
@Override
public String fold(String accumulator, Integer value) throws Exception {
return accumulator + "=" + value;
}
})
- Aggregations
DataStream API 支持各种聚合,例如 min,max,sum 等。 这些函数可以应用于 KeyedStream 以获得 Aggregations 聚合
KeyedStream.sum(0)
KeyedStream.sum("key")
KeyedStream.min(0)
KeyedStream.min("key")
KeyedStream.max(0)
KeyedStream.max("key")
KeyedStream.minBy(0)
KeyedStream.minBy("key")
KeyedStream.maxBy(0)
KeyedStream.maxBy("key")
- Window
Window 函数允许按时间或其他条件对现有 KeyedStream 进行分组。
inputStream.keyBy(0).window(Time.seconds(10));
Flink 定义数据片段以便(可能)处理无限数据流。 这些切片称为窗口。 此切片有助于通过应用转换处理数据块。 要对流进行窗口化,我们需要分配一个可以进行分发的键和一个描述要对窗口化流执行哪些转换的函数
要将流切片到窗口,我们可以使用 Flink 自带的窗口分配器。 我们有选项,如 tumbling windows, sliding windows, global 和 session windows。 Flink 还允许您通过扩展 WindowAssginer 类来编写自定义窗口分配器。 这里先预留下篇文章来讲解这些不同的 windows 是如何工作的。
- WindowAll
windowAll 函数允许对常规数据流进行分组。 通常,这是非并行数据转换,因为它在非分区数据流上运行。
与常规数据流功能类似,我们也有窗口数据流功能。 唯一的区别是它们处理窗口数据流。 所以窗口缩小就像 Reduce 函数一样,Window fold 就像 Fold 函数一样,并且还有聚合。
inputStream.keyBy(0).windowAll(Time.seconds(10));
- Union
Union 函数将两个或多个数据流结合在一起。 这样就可以并行地组合数据流。 如果我们将一个流与自身组合,那么它会输出每个记录两次。
inputStream.union(inputStream1, inputStream2, ...);
- Window join
可以通过一些 key 将同一个 window 的两个数据流 join 起来
inputStream.join(inputStream1)
.where(0).equalTo(1)
.window(Time.seconds(5))
.apply (new JoinFunction () {...});
- Split
此功能根据条件将流拆分为两个或多个流。 当您获得混合流并且您可能希望单独处理每个数据流时,可以使用此方法。
SplitStream<Integer> split = inputStream.split(new OutputSelector<Integer>() {
@Override
public Iterable<String> select(Integer value) {
List<String> output = new ArrayList<String>();
if (value % 2 == 0) {
output.add("even");
}
else {
output.add("odd");
}
return output;
}
});
- select
此功能允许您从拆分流中选择特定流
SplitStream<Integer> split;
DataStream<Integer> even = split.select("even");
DataStream<Integer> odd = split.select("odd");
DataStream<Integer> all = split.select("even","odd");
- Project
函数允许您从事件流中选择属性子集,并仅将所选元素发送到下一个处理流
DataStream<Tuple4<Integer, Double, String, String>> in = // [...]
DataStream<Tuple2<String, String>> out = in.project(3,2);
参考文档
http://www.54tianzhisheng.cn/2018/11/04/Flink-Data-transformation/