Flink

Flink

环境搭建

  • 官网下载Flink压缩包

  • 解压

  • 进入bin启动,

    • windows:start-cluster.bat

    • Linux:start-cluster.sh

  • 浏览器访问localhost:8081

算子

  • map:接收一个数据,经过处理之后,就返回一个数据

    • 我们来看看map的源码 在这里插入图片描述 map需要接收一个MapFunction<T,R>的对象,其中泛型T表示传入的数据类型,R表示经过处理之后输出的数据类型

    • 我们继续往下点,看看MapFunction<T,R>的源码 在这里插入图片描述 这是一个接口,那么在代码中,我们就需要实现这个接口

  • flatmap:接收一个数据,可以返回多条数据

    • 源码分析

      在这里插入图片描述 我们发现,它需要传入一个FlatMapFunction的一个对象 在这里插入图片描述

      我们继续点进去,看看FlatMapFunction的源码,可以发现,FlatMapFunction<T,R>也是一个接口,并且接口里面的方法的返回值是一个Collector,也就是多个值的集合。

  • filter:过滤器,用来过滤数据。

    • 源码分析 我们看看filer的源码,继承子FilterFunction,可以看到,这次泛型就只有一个值了,因为filter只允许返回的数据<=原来的数据,所以只做过滤,并不能改变数据蕾西,没必要设置返回的类型

      image-20221012084223404

       

    • 我们继续点进去,看看FilterFunction的源码

      image-20221012084237588

       

      果不其然,也是一个接口,而里面的filter方法只有一个参数,并且返回的是一个boolean类型,若返回true则var1原样返回,若返回false,则var1会被过滤掉。

  • 分组聚合

    • 注意:任何的聚合操作都有默认的分组,聚合是在分组的基础上进行的。比如,对整体进行求和,那么分组就是整体。所以,在做聚合操作之前,一定要明确是在哪个分组上进行聚合操作

    • 注意:聚合操作,本质上是一个多对一(一对一是多对一的特殊情况)的操作。特别注意的是这个’一‘,可以是一个值(mean, sum等),同样也可以是一个对象(list, set等对象)

    • 分组(keyBy)

      • DataStream → KeyedStream:逻辑地将一个流拆分成不相交的分区,每个分区包含具有相同 key 的元素,在内部以 hash 的形式实现的。

        • 分组就是为了聚合操作做准备的,keyBy方法会将数据流按照hash实现,分别放在不同的分区,每个分区都可以进行聚合操作。

        • 我们可以用这个性质,计算每一个sensor温度的最大值,我们为此将文件修改:

          image-20221012084853972

           

        分组之后的图就是所有sensor_1在一个分区里,sensor_6,sensor_7,sensor_10在不同的三个分区,也就是有四个分区,而后三个分区中只有一条数据,所以最大值和最小值都只有一个

        • 在flink中,分组操作是由keyBy方法来完成的,我们来看看keyBy的源码

          image-20221012084904272

           

        可以发现,keyBy可以对对象和元组进行聚合。

    • 聚合

      • 这些算子可以针对 KeyedStream 的每一个支流做聚合。 ⚫ sum():对每个支流求和 ⚫ min():对每个支流求最小值 ⚫ max():对每个支流求最大值 ⚫ minBy() ⚫ maxBy() 我们来看看max()的源码

        image-20221012085039955

        这也是传一个属性名,也就是求对应的属性名的最大值。\

    • reduce自定义聚合

      • 在实际生产中,不可能让我们完成这么简单的操作就行了,所以我们需要更复杂的操作,而reduce就是满足这个条件,它可以让我们自定义聚合的方式。

      • 我们来看看reduce的源码

        image-20221012090058422

        reduce需要传入的是一个ReduceFunction的对象,我们再来看看ReduceFunction是个什么东西

        image-20221012090112410

         

        var1是当前这个分组的状态,var2是新加入的值,而reduce函数体就是我们要进行的操作,返回一个新的状态。 到这我就明白了,要是我们向实时获取最大温度的话,var1是之前的最大温度,通过var1和var2的比较就能实现。

        这一次的输出我们就得你好好研究一下了。

        image-20221012090914520

         

        从这块可以发现,我们获取的都是当前的时间戳,而且时间戳也在改变,这一点很好理解,但是下面这个数据就很诡异了。

        image-20221012090921627

        • 这两块的时间戳为什么没有改变呢?这需要我们再来看看reduce方法了,reduce方法是传入两个参数,第一个是当前的状态,第二个是新读取的值,通过方法体的操作返回一个最新的状态。

        • 仔细理解一下这句话,若我刚开始没有数据的时候,那么哪来的状态呢?所以reduce把接收到的第一个参数作为状态,其中sensor_6,7,8这三个分区只有一个数据,所以直接拿来当作状态。

  • 多流转换算子

    • 分流操作(Split 和 Select)

      • Split能将流中的数据按条件贴上标签,比如我把温度大于30度的对象贴上一个high标签,把温度低于30度的贴上一个low标签,标签可以贴多个。那么就把流中的数据,按照标签分类了(这里并没有分流)

        image-20221012091024013

      • Select是按照标签来分流

        image-20221012091035354

         

      split源码

      image-20221012091044698

       

      可以发现,返回的是一个SplitStream,需要传入一个选择器,我们看看OutputSeclector的源码

      image-20221012091050014

       

      传入value,返回这个value对应的标签,实现对这个value进行类似"分类"的操作。 select源码

      image-20221012091056442

       

      只需要接收一个或者多个标签就能返回包含那个标签对象的数据流。

  • 合流操作Connect 和 CoMap

    image-20221012091630346

    DataStream,DataStream → ConnectedStreams:连接两个保持他们类型的数 据流,两个数据流被 Connect 之后,只是被放在了一个同一个流中,内部依然保持各自的数据和形式不发生任何变化,两个流相互独立。

    image-20221012091659728

     

    ConnectedStreams → DataStream:作用于 ConnectedStreams 上,功能与 map和 flatMap 一样,对 ConnectedStreams 中的每一个 Stream 分别进行 map 和 flatMap处理。 类似于一国两制,看似两条流合并在了一起,其实内部依旧是按照自己的约定运行,类型并没有改变。

    connect源码

    image-20221012091710897

    将当前调用者的流和参数中的流合并,返回一个ConnectedStreams<T,R>类型

    image-20221012091717221

    我们再来看看ConnectionStreams<T,R>中的map方法,其中要传的是一个CoMapFunction<IN1,IN2,R>的对象,最重要的就是这个类,我们来看看这个类

    image-20221012091723840

    这个CoMapFunction<IN1,IN2,R>和之前的MapFunction不太一样,这里要重写的方法有两个,map1和map2,一个是针对IN1的,一个是针对IN2的,R就是返回类型。 这下全明白了,在这个方法内部,对这两条流分别操作,合成一条流。

  • 多条流合并(union)

    之前我们只能合并两条流,那我们要合并多条流呢?这里我们就需要用到union方法。

    image-20221012092234272

     

    Connect 与 Union 区别: Union 之前两个流的类型必须是一样,Connect 可以不一样,在之后的 coMap中再去调整成为一样的。 Connect 只能操作两个流,Union 可以操作多个。 若我们给出以下代码:

    high.union(low,all);

    那么high,low,all三条流都会合并在一起。

 

简介

Change Data Capture(变更数据获取)

 基于查询的CDC基于Binlog的CDC
开源产品 Sqoop、Kafka JDBC Source Canal、MAxwell、Debezium
执行模式 Batch批处理 Streaming流处理
是否可以捕获所有数据变化
延迟性 高延迟 低延迟
是否增加数据库压力

常见CDC:

image-20221010084318911

技术演变

Sqoop:

基于查询的CDC

image-20221010083045197

 

DataX:

加强版的Sqoop,基于查询的CDC

image-20221010083014991

Canal:

canal server

只能从MySQL接入数据

基于binlog的CDC,模拟从节点从主节点获取binlog,老版本提供java的client。新版本通过内部的adapter

image-20221010083152977

Debezium:

基于kafka实现。

image-20221010083817051

传统CDC的ETL方案:

需要依赖各种第三方工具,学习和维护成本大

采集的数据处理的链条较长,时效性差,出问题的概率大

image-20221010085534042

image-20221010085552365

 

基于Flink CDC的ETL方案:

封装debezium

image-20221010085742089

image-20221010090133855

可能会出现的问题:

image-20221010090402226

使用方法

  • 在flink中创建表和数据库中的表建立关系

  • 创建采集完成后flink中的表和目标表的关系

  • 创建数据处理逻辑,可以使用flink中的各种算子

  • 执行以上创建好的SQL

Flink SQL CDC

 

 

posted on 2022-11-22 11:17  太阳当空照```  阅读(77)  评论(0)    收藏  举报

导航