「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开发者文档

相关推荐
Dev7z5 小时前
基于图像处理与数据分析的智能答题卡识别与阅卷系统设计与实现
图像处理·人工智能·数据分析
权泽谦5 小时前
Java 在机器学习中的应用:基于 DL4J 与 Weka 的完整实战案例
java·机器学习·数据挖掘
onebound_noah6 小时前
电商图片搜索:技术破局与商业落地,重构“视觉到交易”全链路
大数据·前端·网络·人工智能·重构·php
权泽谦7 小时前
脑肿瘤分割与分类的人工智能研究报告
人工智能·分类·数据挖掘
n***63278 小时前
Python大数据可视化:基于大数据技术的共享单车数据分析与辅助管理系统_flask+hadoop+spider
大数据·python·信息可视化
Michelle80238 小时前
24大数据 while循环
大数据·python
xuehaikj9 小时前
【甲状腺病理AI】基于YOLO11-SOEP的甲状腺乳头状癌病理特征识别与分类系统研究
人工智能·分类·数据挖掘
Hello.Reader9 小时前
从 CDC 到实时数据流Flink SQLServer CDC Connector 实战
大数据·sqlserver·flink
TG:@yunlaoda360 云老大11 小时前
谷歌云Flink 核心组成及生态发展:实时数据处理的下一代引擎
大数据·flink·googlecloud
JavaBoy_XJ11 小时前
电商系统中ES检索技术设计和运用
大数据·elasticsearch·搜索引擎