Flink之流的转换

ProcessFuncion处理函数

  • 功能
    • 拥有富函数功能
      • 生命周期方法
      • 状态编程
    • 对元素的处理功能processElement, 在不同的处理函数中,该方法的名字略有区别
    • 定时器编程
      • TimeService:定时服务,可以用于注册定时器,删除定时器
      • ontimer():定时器触发后会自动调用该方法,我们将需要完成的工作写到该方法中
    • 侧输出流
  • 分类
    • processFunction: 普通流DataStream调用
    • keyedProcessFunction: KeyedStream, 经过Keyby的数据流
    • ProcessWindowFunction:按键分区经过window操作的数据流,WindowedStream,全窗口函数
    • ProcessAllWindowFunction:非按键分区的window数据流调用
    • CoProcessFunction:ConnectedStreams, 由两个数据流经过connect后得到的,没有经过keyby时调用
    • ProcessJoinFunction:IntervalJoined , 两个流经过IntervalJoin后得到的流
    • BroadcastProcessFunction:一个普通流connect广播流后得到,之后调用process需要传入该Function
    • KeyedBroadcastProcessFunction: 一个keyby流connect广播流后得到

常用流之间的转换关系

  • SingleOutputDataSteam是继承自DataStream的。
  • window操作必须是基于keyby流
  • 特殊流经过reduce, aggreagate,process, apply等聚合操作后就变为SingleOutputDataStream

processFunction的定时器方法

定时服务 和定时器

  • TimerService:定时服务,用于注册定时器,删除定时
    • long currentProcessingTime():获取当前的处理时间
    • registerProcessingTimer(): 注册处理时间定时器
    • registerEventTimeTimer():注册事件时间定时器
    • currentWatermark():获取当前水位线
    • deleteEventTimeTimer():注册事件时间定时器
  • Timer:定时器,在未来的某个时间注册一个事件,定时器触发,会执行定义的事件
  • ontimer(): 定时器触发以后,会自动调用该方法
  • 注意:
    • 要定时先keyby, 设置定时器必须基于一个keyby流
    • 同一个key在注册多个相同时间的定时器,未来之后触发一次,不同的key注册相同时间的定时器,每个key都会触发一次。

TopN 实现

java 复制代码
/**
 * title:
 *
 * @Author 浪拍岸
 * @Create 11/12/2023 下午3:19
 * @Version 1.0
 *
 * 实时统计一段时间的热门URL
 * 例如:10秒内最热门的两个URL链接,并且每5秒更新一次
 *
 * 方案1:不进行keyby操作,将所有URL数据统一往一个窗口
 * 中收集,并且使用全量聚合,等到窗口触发计算时,在处理函数中
 * 对窗口内所有数据进行汇总处理
 *
 */
public class Flink03_TopN {
    public static void main(String[] args) {
        //1.创建运行环境
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

        //默认是最大并行度
        env.setParallelism(1);

        SingleOutputStreamOperator<Event> ds = Flink06_EventSource.getEventSource(env)
                .assignTimestampsAndWatermarks(
                        WatermarkStrategy.<Event>forBoundedOutOfOrderness(Duration.ZERO)
                                .withTimestampAssigner(
                                        (event, ts) -> event.getTs()
                                )
                );

        ds.print("input");

        ds.windowAll(
//                TumblingEventTimeWindows.of(Time.seconds(10))
                SlidingProcessingTimeWindows.of(Time.seconds(10), Time.seconds(5))
        ).process(
                new ProcessAllWindowFunction<Event, String, TimeWindow>() {
                    @Override
                    public void process(ProcessAllWindowFunction<Event, String, TimeWindow>.Context context, Iterable<Event> elements, Collector<String> out) throws Exception {
                        //统计每个URL的点击次数

                        long start = context.window().getStart();
                        long end = context.window().getEnd();

                        HashMap<String, Long> urlCountMap = new HashMap<>();

                        for (Event element : elements) {
                            Long count = urlCountMap.getOrDefault(element.getUrl(), 0L);
                            urlCountMap.put(element.getUrl(), count+1);
                        }

                        //将map结构转换为list
//                        ArrayList<UrlUserCount> urlCountList = new ArrayList<>(urlCountMap.size());

                        List<UrlUserCount> urlUserCountList = urlCountMap.entrySet().stream().map(
                                entry -> new UrlUserCount(entry.getKey(), entry.getValue(), start, end)
                        ).collect(Collectors.toList());

                        urlUserCountList.sort(
                                new Comparator<UrlUserCount>() {
                                    @Override
                                    public int compare(UrlUserCount o1, UrlUserCount o2) {
                                        return Long.compare(o2.getCount(), o1.getCount());
                                    }
                                }
                        );

                        //取topN
                        StringBuilder result = new StringBuilder("*******************************\n");
                        for (int i = 0; i < Math.min(2,urlUserCountList.size()); i++) {
                            UrlUserCount urlUserCount = urlUserCountList.get(i);
                            result.append("TOP."+(i+1)+" "+urlUserCount+"\n");

                        }
                        result.append("*****************************************\n");
                        //输出
                        out.collect(result.toString());
                    }
                }
        ).print();


        try {
            env.execute();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
相关推荐
pele10 分钟前
PHP源码运行受主板供电影响吗_供电相数重要性说明【技巧】
jvm·数据库·python
sinat_3834373610 分钟前
CSS如何实现元素悬浮在页面底部_利用fixed定位与底部间距
jvm·数据库·python
gmaajt41 分钟前
mysql如何备份与恢复函数定义_mysql mysqldump导出存储对象
jvm·数据库·python
阿丰资源1 小时前
基于SpringBoot的在线视频教育平台的设计与实现(附源码+数据库+文档,一键运行)
数据库·spring boot·后端
qq_460978401 小时前
Python爬虫怎么模拟手机端抓取_设置手机型号User-Agent字符串
jvm·数据库·python
m0_617881425 小时前
如何高效进行堆叠分类器的超参数调优:解决 GridSearchCV 卡顿问题
jvm·数据库·python
编程自留地5 小时前
项目sql语句
前端·数据库·sql
m0_588758486 小时前
如何高效批量删除SQL数据_使用脚本分段删除降低压力
jvm·数据库·python
abc123456sdggfd6 小时前
Layui表单验证失败时如何修改默认弹出的Tips气泡颜色
jvm·数据库·python
Bert.Cai6 小时前
MySQL TRIM()函数详解
数据库·mysql