「Flink」算子主要方法介绍

背景:

上期文章主要讲了Flink项目搭建的一些方法,其中对于数据流的处理很大一部分是通过算子来进行计算和处理的,算子也是Flink中功能非常庞大,且很重要的一部分。

算子介绍:

算子在Flink的开发者文档中是这样介绍的:通过算子能将一个或多个 DataStream 转换成新的 DataStream,在应用程序中可以将多个数据转换算子合并成一个复杂的数据流拓扑。这简单总结就有点类似于Flink的一些API,来对数据流进行操作处理。

算子介绍目录:

主要介绍几个在日常开发中,比较常用的几个算子方法:

1.FlatMap

2.Filter

3.Window

4.join

5.coGroup

1.FlatMap

flatMap是输入一个元素同时产生零个、一个或多个元素。通常在日常开发中用于对于数据流的初步处理和合并,将数据流转换成我们希望输入的数据格式

方法举例:

arduino 复制代码
dataStream.flatMap(new FlatMapFunction<String, String>() {
    @Override
    public void flatMap(String value, Collector<String> out)
        throws Exception {
        for(String word: value.split(" ")){
            out.collect(word);
        }
    }
});

日常使用举例:

java 复制代码
/// 将binglog获取的dataChangInfo格式转换成OrderInfo业务格式
dataStream1.flatMap(new FlatMapFunction<DataChangeInfo, OrderInfo>() {
    @Override
    public void flatMap(DataChangeInfo dataChangeInfo, Collector<OrderInfo> collector) throws Exception {
        OrderInfo orderInfo = JSONObject.parseObject(dataChangeInfo.getAfterData(), OrderInfo.class);
        log.info("订单数据:{}", orderInfo);
        collector.collect(orderInfo);
    }
});
2.Filter

对数据流进行过滤操作,将一些脏数据或者我们不希望流入的数据进行排除处理 使用举例:

java 复制代码
/// 筛选出订单状态小于等于40的订单数据
orderInfoSingleOutputStream.filter(new FilterFunction<OrderInfo>() {
    @Override
    public boolean filter(OrderInfo orderInfo) throws Exception {
        if (orderInfo.getStatus() <= 40){
            return true;
        }
        return false;
    }
});
3.Window

Window 根据某些特征(例如,最近 5 秒内到达的数据)对每个 key Stream 中的数据进行分组。就类似于上期文章所讲述的窗口,具体介绍可以查看上期文章「Flink」Flink项目搭建方法介绍

less 复制代码
/// 先通过keyby设置主键
/// 然后设置一个以事件时间为标定,设一个5秒的窗口
dataStream
  .keyBy(value -> value.f0)
  .window(TumblingEventTimeWindows.of(Duration.ofSeconds(5))); 
4.Join

根据指定的 key 和窗口 join 两个数据流。 这个方法通常用在两个数据流需要通过某个key值进行合并的时候,比如订单主表和订单副表需要通过orderId进行数据合并的时候,进行数据处理。

方法举例:

scss 复制代码
dataStream.join(otherStream)
    .where(<key selector>).equalTo(<key selector>)
    .window(TumblingEventTimeWindows.of(Duration.ofSeconds(3)))
    .apply (new JoinFunction () {...});

日常使用举例:

scss 复制代码
DataStream<OrderOutputInfo> outputInfoDataStream = orderInfoSingleOutputStream
        .join(orderCodeInfoSingleOutputStream)
        .where(OrderInfo::getId)
        .equalTo(OrderCodeInfo::getId)
        .window(TumblingProcessingTimeWindows.of(Time.seconds(10)))
        .apply(new JoinFunction<OrderInfo, OrderCodeInfo, OrderOutputInfo>() {
            @Override
            public OrderOutputInfo join(OrderInfo orderInfo, OrderCodeInfo orderCodeInfo) throws Exception {
                OrderOutputInfo orderOutputInfo = new OrderOutputInfo();
                orderOutputInfo.setId(orderInfo.getId());
                orderOutputInfo.setStatus(orderInfo.getStatus());
                orderOutputInfo.setCode(orderCodeInfo.getCode());
                orderOutputInfo.setCreate_time(orderInfo.getCreate_time());
                log.info("输出数据:{}", orderOutputInfo);
                return orderOutputInfo;
            }
        });

通过断点,其实可以发现,数据并不是按照一批一批进行输出的,而是根据key,进行一条一条的输出的,这个需要注意写入库的方法,以免对数据库写入产生较大的压力。 然后该方法会发现一个弊端,那就是如果不在事件窗口期输入的,那么无法匹配到对应的数据行,那么就会出现数据无法输出,数据丢失的情况,使用outside,官方推荐的侧输出,也无法有效输出,这时候比较推荐下面这个方法Cogroup,可以通过自定义的方法进行对未匹配的数据进行输出报错;

5.CoGroup

根据指定的 key 和窗口将两个数据流组合在一起。 CoGroup和Join是个类似的方法,但是CoGroup的数据处理方法里面可以有迭代器,然后在实际数据处理过程中可以通过判断迭代器,从而实现对于未匹配成功的订单进行打印输出。

方法举例:

scss 复制代码
dataStream.coGroup(otherStream)
    .where(0).equalTo(1)
    .window(TumblingEventTimeWindows.of(Duration.ofSeconds(3)))
    .apply (new CoGroupFunction () {...});

日常使用举例:

scss 复制代码
orderInfoSingleOutputStream.coGroup(orderCodeInfoSingleOutputStream)
        .where(OrderInfo::getId)
        .equalTo(OrderCodeInfo::getId)
        .window(TumblingProcessingTimeWindows.of(Time.seconds(10)))
        .apply(new CoGroupFunction<OrderInfo, OrderCodeInfo, OrderOutputInfo>() {
            @Override
            public void coGroup(Iterable<OrderInfo> iterable, Iterable<OrderCodeInfo> iterable1, Collector<OrderOutputInfo> collector) throws Exception {
                if(iterable.iterator().hasNext() && iterable1.iterator().hasNext()){
                    OrderInfo orderInfo = iterable.iterator().next();
                    OrderCodeInfo orderCodeInfo = iterable1.iterator().next();
                    System.out.println("匹配成功的订单ID:" + orderInfo.getId() + "  订单创建时间:" + orderInfo.getCreate_time() + "  status " + orderInfo.getStatus());
                    System.out.println("=============================");
                    OrderOutputInfo orderOutputInfo = new OrderOutputInfo();
                    orderOutputInfo.setId(orderInfo.getId());
                    orderOutputInfo.setStatus(orderInfo.getStatus());
                    orderOutputInfo.setCode(orderCodeInfo.getCode());
                    orderOutputInfo.setCreate_time(orderInfo.getCreate_time());

                    collector.collect(orderOutputInfo);

                }else if(iterable.iterator().hasNext() && !iterable1.iterator().hasNext()){
                    OrderInfo order = iterable.iterator().next();
                    System.out.println("订单未找到匹配的订单-----------Code:"+ order.getId());

                } else  if(!iterable.iterator().hasNext() && iterable1.iterator().hasNext()){
                    OrderCodeInfo orderCodeInfo = iterable1.iterator().next();
                    System.out.println("未找到匹配的Code订单-----------Code:" + orderCodeInfo.getId() );
                }
            }
        });

数据输出日志: 可以看到数据也是一条条匹配后输出,无法匹配的数据也会在窗口结束后进行输出展示或告警。

总结:

以上几个算子方法就是平时日常开发中比较常用且好用的方法,大家可以结合各自的业务场景,进行挑选使用。

相关链接

Flink

Flink开发者文档

相关推荐
老蒋新思维2 分钟前
创客匠人峰会深度解析:知识变现的 “IP 资产化” 革命 —— 从 “运营流量” 到 “沉淀资产” 的长期增长逻辑
大数据·人工智能·网络协议·tcp/ip·创始人ip·创客匠人·知识变现
老蒋新思维19 分钟前
创客匠人峰会洞察:IP 信任为基,AI 效率为翼,知识变现的可持续增长模型
大数据·网络·人工智能·网络协议·tcp/ip·创始人ip·创客匠人
玖日大大23 分钟前
ModelEngine 可视化编排实战:从智能会议助手到企业级 AI 应用构建全指南
大数据·人工智能·算法
TDengine (老段)29 分钟前
TDengine 数据缓存架构及使用详解
大数据·物联网·缓存·架构·时序数据库·tdengine·涛思数据
hans汉斯44 分钟前
【软件工程与应用】基于大数据的应急救援云平台构建应用研究
大数据·数据库·人工智能·物联网·系统架构·云计算·汉斯出版社
测试人社区-千羽1 小时前
自动化缺陷修复的建议生成:赋能软件测试新范式
运维·人工智能·自然语言处理·分类·数据挖掘·自动化·ux
秋刀鱼 ..1 小时前
2026生物神经网络与智能优化国际研讨会(BNNIO 2026)
大数据·python·计算机网络·数学建模·制造
AI优秘企业大脑1 小时前
增长智能体助力企业智慧转型
大数据·人工智能
正在走向自律1 小时前
时序数据库选型指南,从大数据视角看新一代列式存储引擎的核心优势
大数据·时序数据库·iotdb·国产数据库
机器学习之心HML1 小时前
TCN-BiLSTM回归+特征贡献SHAP分析+新数据预测+多输出,MATLAB代码
matlab·数据挖掘·回归