一、背景说明:
有需求需要对数据进行统计,要求每隔5分钟输出最近1小时内点击量最多的前N个商品,数据格式预览如下:
543462,1715,1464116,pv,1511658000
662867,2244074,1575622,pv,1511658000
561558,3611281,965809,pv,1511658000
894923,3076029,1879194,pv,1511658000
834377,4541270,3738615,pv,1511658000
315321,942195,4339722,pv,1511658000
625915,1162383,570735,pv,1511658000
578814,176722,982926,pv,1511658000
....
最后统计输出结果如下:
==============2017-11-26 09:05:00.0==============
Top1 ItemId:5051027 Counts:3
Top2 ItemId:3493253 Counts:3
Top3 ItemId:4261030 Counts:3
Top4 ItemId:4894670 Counts:2
Top5 ItemId:3781391 Counts:2
==============2017-11-26 09:05:00.0==============
==============2017-11-26 09:10:00.0==============
Top1 ItemId:812879 Counts:5
Top2 ItemId:2600165 Counts:4
Top3 ItemId:2828948 Counts:4
Top4 ItemId:2338453 Counts:4
Top5 ItemId:4261030 Counts:4
==============2017-11-26 09:10:00.0==============
二、实现过程
-
实现思路:
①建立环境,设置并行度及CK。
②定义watermark策略及事件时间,获取数据并对应到JavaBean,筛选pv数据。
③第一次聚合,按商品id分组开窗聚合,使用aggregate算子进行增量计算。
④第二次聚合,按窗口聚合,使用ListState存放数据,并定义定时器,在watermark达到后1秒触发,对窗口数据排序输出。
⑤打印结果及执行。 -
代码细节说明:
2.1 、第一次聚合代码:
//第一次聚合
SingleOutputStreamOperator<ItemCount> aggregateDS = userBehaviorDS
.map(new MapFunction<UserBehavior, Tuple2<Long, Integer>>() {
@Override
public Tuple2<Long, Integer> map(UserBehavior value) throws Exception {
return new Tuple2<>(value.getItemId(), 1);
}})
.keyBy(data -> data.f0)
.window(SlidingEventTimeWindows.of(Time.hours(1), Time.minutes(5)))
.aggregate(new ItemCountAggFunc(), new ItemCountWindowFunc());
①第一次聚合这里将商品id进行提取并转换为Tuple2<id,1>的格式,再对id进行keyby后聚合,避免直接使用对应的JavaBean进行分组聚合提高效率:
②这里使用aggregate算子进行增量计算,Flink的window function来负责一旦窗口关闭, 去计算处理窗口中的每个元素。window function 是如下三种:
- ReduceFunction (增量聚合函数) 输入及输出类型得一致
- AggregateFunction(增量聚合函数)输入及输出类型可以不一致
- ProcessWindowFunction(全窗口函数)
ReduceFunction,AggregateFunction更加高效, 原因就是Flink可以对到来的元素进行增量聚合 .
ProcessWindowFunction 可以得到一个包含这个窗口中所有元素的迭代器, 以及这些元素所属窗口的一些元数据信息.
ProcessWindowFunction不能被高效执行的原因是Flink在执行这个函数之前, 需要在内部缓存这个窗口上所有的元素
2.2、重写AggregateFunction函数代码
public static class ItemCountAggFunc implements AggregateFunction<Tuple2<Long,Integer>,Integer,Integer>{
@Override
public Integer createAccumulator() {
return 0; }
@Override
public Integer add(Tuple2<Long, Integer> value, Integer accumulator) {
return accumulator+1; }
@Override
public Integer getResult(Integer accumulator) {
return accumulator; }
@Override
public Integer merge(Integer a, Integer b) {
return a+b; }
Flink实时计算:每5分钟输出最近1小时点击量TopN商品

该博客介绍了如何使用Apache Flink实现每5分钟统计最近1小时的商品点击量,并输出TopN商品。通过设置watermark策略处理乱序数据,使用SlidingEventTimeWindows进行滑动窗口聚合,自定义AggregateFunction进行计数,最后通过ProcessWindowFunction排序并输出结果。
最低0.47元/天 解锁文章
3199

被折叠的 条评论
为什么被折叠?



