1 map 或者source时继承对应的rich function,在其中的open方法中建立连接,对应的close方法中关闭连接。
2 window必须对应keyedstream,也就是说必须在keyby之后。之后在对应相应的增量函数比如ReduceFunction
, AggregateFunction
, FoldFunction
或 ProcessWindowFunction
。前两个函数执行效率更高,因为 Flink 可以在每个窗口中元素到达时增量地聚合。后两个FoldFunction
,ProcessWindowFunction
将获得一个窗口内所有元素的迭代器以及元素所在窗口的附加元信息。
private static class MyProcessWindowFunction extends
ProcessWindowFunction<Tuple2<String, Integer>, String, String, TimeWindow> {
@Override
public void process(String key, Context context,
Iterable<Tuple2<String, Integer>> input, Collector<String> out) {
3 windowall 对应的是没有分区的datastream流,其后也可以跟对应的ReduceFunction
, AggregateFunction
, FoldFunction
或 ProcessWindowFunction。
4 每个算子对应的watermark是所有输入多分区流相应的watermark中最小的一个。(每个输入的分区流数据都有一个自己的水位)
5 生成watermark也可以自定义内部类,重写相应的watermark生成函数,比如直接提取日志时间eventtime减去等待延迟时间为watermark, 一般继承的父类有两种,一类是
AssignerWithPeriodicWatermarks,周期性生成水印,另外一个是AssignerWithPunctuatedWatermarks没有周期性规律,打断生成水印。
private static class MyOwnWaterMark implements AssignerWithPeriodicWatermarks<Tuple3<String, Long, Integer>> {
private final long maxOutOfOrderness = 0; // 3 seconds
private long currentMaxTimestamp;
@Override
public long extractTimestamp(Tuple3<String, Long, Integer> element, long previousElementTimestamp) {
return timestamp;
}
@Override
public Watermark getCurrentWatermark() {
// return the watermark as current highest timestamp minus the out-of-orderness bound
return new Watermark(currentMaxTimestamp - maxOutOfOrderness);
}
6 watermark机制一般是为了window服务的,遇到一个时间戳的信息到达了窗口关闭时间,不应该立即触发窗口关闭计算,而是等待一段时间,等迟来的数据来了再窗口计算。
watermark表示timestamp小于水位线的数据都已经到达了,因此窗口触发实际上是由watermark来触发的。
7 一般比如写文件的sink task 并行度设置为1, 前面操作可以多个并行度。写文件sink如果多个并行度写一个文件会乱出问题。跟自己写线程池代码一样,多个线程的返回结果同意收集之后再统一写入一个文件。当然写入多个文件肯定是没有影响的。
8 Window Assigners(窗口分配器)
窗口分配器主要做的工作就是将一个元素分配到一个或多个窗口里,在第一个元素分配后,窗口才创建,换句话说,窗口里一个元素也没有,那这个窗口就不存在。