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);
        }
    }
}
相关推荐
liangsheng_g8 分钟前
Spring事务传播行为分派与挂起恢复源码实战
数据库·sql·spring
CIO_Alliance14 分钟前
AI微调系列(2)| QLoRA:一张卡微调700亿参数,显存是怎么省下来的
大数据·人工智能·深度学习·ai·企业ai转型·企业cio联盟
蓝速科技22 分钟前
信创终端 POC 测试实战与选型避坑指南丨蓝速科技
运维·数据库·人工智能·科技·自然语言处理
远航计算机33 分钟前
网站被 AI 收录要多久?从被抓取到被引用的完整时间表
大数据·人工智能·aigc
风哥2号37 分钟前
数据库教程FGMT29‑Linux平台MySQL5.7安装配置与管理入门
数据库
来了就不要走1 小时前
亿数平台怎么样:亿象生态与数实融合路径观察
大数据·人工智能·区块链
杨云龙UP1 小时前
MySQL Host is blocked because of many connection errors 导致 JDBC 连接失败排查与解决
linux·运维·网络·数据库·sql·mysql·登录失败
Q26433650232 小时前
【有源码】基于文本挖掘的消费者金融投诉主题发现与风险预警研究,基于Python的CFPB消费者投诉数据可视化分析系统
大数据·hadoop·机器学习·数据挖掘·spark·毕业设计·课程设计
南京兴帝文化传媒有限公司2 小时前
本地生活服务GEO优化案例:宁国瑜伽馆地图关键词布局与AI问答优化路径
大数据·人工智能·生活·geo 优化·ai搜索获客
数字新视界2 小时前
国产化动环技术提升数据中心监控效率与安全性
大数据·人工智能·数据中心·微模块机房·模块化机房