Flink双窗口拆分合并
问题抽象: Flink单窗口数据量过大,导致窗口聚合过慢。
例子: 统计某个国家,某个城市的实时订单数。
痛点: 某"国家_城市"下订单数过大,比如百万级甚至千万级,导致窗口聚合时间过长,过慢。
解决方案: 先拆分,然后分别计算,后汇总。拆分可以按照订单尾号拆分(选择尾号可以达到负载均衡,解决数据倾斜问题)。
创作于“惊天小蚂蚁”,转载请注明出处,谢谢!
SingleOutputStreamOperator<OrderModel> inStream = null;// todo 自定义源
inStream
.flatMap(new FlatMapFunction<OrderModel, Tuple2<String, OrderModel>>() {
@Override
public void flatMap(OrderModel oneOrder, Collector<Tuple2<String, OrderModel>> out) throws Exception {
// todo 数据拆分: "国家_城市_订单尾号" 需要从oneOrder提取
out.collect(new Tuple2("国家_城市_订单尾号", oneOrder));
}
})// 拆分逻辑
.assignTimestampsAndWatermarks("todo 自己实现")//添加水印
.keyBy(0)//按照key聚合 即国家_城市_订单尾号
.timeWindow(Time.seconds(60L))//60s一个窗口
.process(new ProcessWindowFunction() {
@Override
public void process(Object o, Context context, Iterable elements, Collector out) throws Exception {
// todo 个窗口:计算某个尾号该分钟总订单数
}
})
.keyBy("国家_城市") // 国家_城市
.window(ProcessingTimeSessionWindows.withGap(Time.seconds(5L)))//session 窗口,5秒钟容忍时间
.process(new ProcessWindowFunction() {
@Override
public void process(Object o, Context context, Iterable elements, Collector out) throws Exception {
// todo 第二个窗口:做汇总。实时订单总数=0号尾号订单数量+1号尾号订单数量+...+9号尾号订单数量
}
});
相关文章