前面说了很多关于flink的windows相关原理的内容,今天讲一个flink的window相关操作的一个实战内容吧。
首先,回顾一下Spark Streaming的windows操作,实际上就是在将微批增加若干倍(窗口大小处以批处理大小),这样就形成了窗口,那对于与kafka的结合这种方式,原理我在星球的源码里也说过了,实际上并没有真实的去kafka取数据,而是计算了offset,这种情况下,实际上窗口计算的时候并没有一批次缓存全部数据,当然基于receiver那种就不行了因为是blockrdd,receiver直接接受了数据。
而对于flink 与kafka的区别也说过,flink是数据在拓扑图里流动,那么窗口操作也是增量的计算。实际上有时候我们可能想要针对一整个窗口计算,然后灵活的控制时间及窗口状态,flink神奇就神奇在可以很容易实现我们的操作。
神奇的ProcessWindowFunction。
ProcessWindowFunction一次性迭代整个窗口里的所有元素,比较重要的一个对象是Context,可以获取到事件和状态信息,这样我们就可以实现更加灵活的控制,这实际上是process的主要特点吧。该算子会浪费很多性能吧,主要原因是不增量计算,要缓存整个窗口然后再去处理,所以要设计好内存。
牛叉的地方是ProcessWindowFunction可以结合 ReduceFunction, AggregateFunction, 或者 FoldFunction来做增量计算。
本文就举一个简单的例子,主要是实现针对窗口的分组统计功能。
package org.datastream.windows;
import org.apache.flink.api.common.functions.FoldFunction;
import org.apache.flink.api.common.restartstrategy.RestartStrategies;
import org.apache.flink.api.common.serialization.SimpleStringSchema;
import org.apache.flink.api.java.tuple.Tuple2;