Flink中API的使用

一、Source

        预定义Source          

                基于本地集合的source(Collection-based-source)

                基于文件的source(File-based-source)

                基于网络套接字(socketTextStream)

        自定义Source

 在flink最常见的创建DataStream方式有四种:

        使用env.fromElements(),这种方式也支持Tuple,自定义对象等复合形式

        使用env.fromCollection(),这种方式支持多种Collection的具体类型,如List,Set,Queue

        使用env.generateSequence()方法创建基于Sequence的DataStream --已经废弃了

        使用env.fromSequence()方法创建基于开始和结束的DataStream

二、Transformation-转换算子

 map、FlatMap、Filter、KeyBy、Reduce --sum

KeyBy流处理中没有groupBy而是KeyBy

 KeySelector对象可以支持元组类型,也可以支持POJO[Entry、JavaBean]

 元组类型

        单个字段keyBy

//用字段位置(已经被废弃)
wordAndOne.keyBy(0)

//用字段表达式
wordAndOne.keyBy(v -> v.f0)

        多个字段keyBy

//用字段位置
wordAndOne.keyBy(0, 1);

//用KeySelector
wordAndOne.keyBy(new KeySelector<Tuple2<String, Integer>, Tuple2<String, Integer>>() {
    @Override
    public Tuple2<String, Integer> getKey(Tuple2<String, Integer> value) throws Exception {
        return Tuple2.of(value.f0, value.f1);
    }
});

类似于sql中的group by

select sex,count(1) from student group by sex;
group by 后面也可以跟多个字段进行分组,同样 keyBy 也支持使用多个列进行分组

Reduce --sum的底层是reduce

三、 union和connect-合并和连接

union可以合并多个同类型的流

将多个DataStream 合并成一个DataStream

【注意】:union合并的DataStream的类型必须是一致的

 注意:union可以取并集,但是不会去重

 connect

 connect可以连接2个不同类型的流(最后需要处理后再输出)

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

和union类似,但是connect只能连接两个流,两个流之间的数据类型可以不同,对两个流的数据可以分别应用不同的处理逻辑。

Side Outputs侧道输出-----可以分流

 物理分区

 1) Global Partitioner

 2)Shuffle Partitioner

根据均匀分布随机划分元素

 3) Broadcast Partitioner

 发送到下游所有的算子实例,是将上游的所有数据,都给下游的每一个分区一份

 4)Rebalance Partitioner --重分区 【重点】

 

通过循环的方式依次发送到下游的task

数据倾斜: 某一个分区数据量过大。

 解决方案:可以对分区数据进行重分区rebalance。

 

5) Forward Partitioner 

 发送到下游对应的第一个task,保证上下游算子并行度一致,即上有算子与下游算子是1:1的关系

 

四、Sink

flink在批处理中常见的sink

  1. print 打印
  2. writerAsText 以文本格式输出
  3. writeAsCsv 以csv格式输出
  4. writeUsingOutputFormat 以指定的格式输出
  5. writeToSocket 输出到网络端口
  6. 自定义连接器(addSink)

连接器Connectors 

JDBC Connector

该连接器可以向JDBC 数据库写入数据

https://nightlies.apache.org/flink/flink-docs-release-1.13/zh/docs/connectors/datastream/jdbc/

使用java操作jbdc时,需要的依赖

<dependency>
  <groupId>org.apache.flink</groupId>
  <artifactId>flink-connector-jdbc_2.11</artifactId>
  <version>${flink.version}</version>
</dependency>

<!--假如你是连接低版本的,使用5.1.49-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.25</version>
        </dependency>

 五、Window

Flink 认为 Batch 是 Streaming 的一个特例,所以Flink 底层引擎是一个流式引擎,在上面实现了流处理和批处理。而窗口(window)就是从 Streaming 到 Batch 的一个桥梁。Flink 提供了非常完善的窗口机制。

https://nightlies.apache.org/flink/flink-docs-release-1.13/zh/docs/dev/datastream/operators/windows/

window有如下的控制属性

        

窗口的长度(大小): 决定了要计算最近多长时间的数据

窗口的间隔: 决定了每隔多久计算一次

举例:每隔10min,计算最近24h的热搜词,24小时是长度,每隔10分钟是间隔。

Flink的窗口算子为我们提供了方便易用的API,我们可以将数据流切分成一个个窗口,对窗口内的数据进行处理。本文将介绍如何在Flink上进行窗口的计算。

一个Flink窗口应用的大致骨架结构如下所示:

l Keyed Window --键控窗口

// Keyed Window
stream
        .keyBy(...)              <-  按照一个Key进行分组
        .window(...)            <-  将数据流中的元素分配到相应的窗口中
        [.trigger(...)]            <-  指定触发器Trigger(可选)
        [.evictor(...)]            <-  指定清除器Evictor(可选)
        .reduce/aggregate/process/apply()      <-  窗口处理函数Window Function

l Non-Keyed Window

// Non-Keyed Window
stream
        .windowAll(...)         <-  不分组,将数据流中的所有元素分配到相应的窗口中
        [.trigger(...)]            <-  指定触发器Trigger(可选)
        [.evictor(...)]            <-  指定清除器Evictor(可选)
        .reduce/aggregate/process()      <-  窗口处理函数Window Function

 window的分类

        

Window可以分成两类:

CountWindow:按照指定的数据条数生成一个Window,与时间无关。

滚动计数窗口,每隔N条数据,统计前N条数据

滑动计数窗口,每隔N条数据,统计前M条数据

TimeWindow:按照时间生成Window。(重点)

滚动时间窗口,每隔N时间,统计前N时间范围内的数据,窗口长度N,滑动距离N

滑动时间窗口,每隔N时间,统计前M时间范围内的数据,窗口长度M,滑动距离N

会话窗口,按照会话划定的窗口

 

 基于时间的滑动和滚动窗口 [重点]

滚动窗口- TumblingWindow概念

假设有个红绿灯,提出个问题:统计1分钟内通过的汽车数量

每隔1分钟,统计这1分钟内通过汽车的数量。窗口长度是1分钟,时间间隔是1分钟,所以这样的窗口就是滚动窗口

滑动窗口– SlidingWindow概念

每隔1分钟,统计前面2分钟内通过的车辆数

对于这个需求我们可以看出,窗口长度是2分钟,每隔1分钟统计一次,窗口长度和时间间隔不相等,并且是大于关系,就是滑动窗口

窗口的长度(大小) > 窗口的间隔 : 如每隔5s, 计算最近10s的数据 【滑动窗口】 

窗口的长度(大小) = 窗口的间隔: 如每隔10s,计算最近10s的数据 【滚动窗口】

窗口的长度(大小) < 窗口的间隔: 每隔15s,计算最近10s的数据 【没有名字,不用】

滚动窗口:窗口长度= 滑动距离

滑动窗口:窗口长度!= 滑动距离

 windows Function窗口函数

窗口函数的分类:

        

全量函数:窗口先缓存所有元素,等到触发条件后对窗口内的全量元素执行计算。

l增量函数:窗口保存一份中间数据,每流入一个新元素,新元素与中间数据两两合一,生成新的中间数据。

 增量聚合函数:

 

实现方法(常见的增量聚合函数如下):
reduce(reduceFunction)
aggregate(aggregateFunction)
sum()
min()
max()

reduce接受两个相同类型的输入,生成一个同类型输出,所以泛型就一个 <T>
maxBy、minBy、sum这3个底层都是由reduce实现的
aggregate的输入值、中间结果值、输出值它们3个类型可以各不相同,泛型有<T, ACC, R>

 全量聚合函数:

 

 

实现方法
apply(windowFunction)
process(processWindowFunction)

全量聚合: 窗口需要维护全部原始数据,窗口触发进行全量聚合。
ProcessWindowFunction一次性迭代整个窗口里的所有元素,比较重要的一个对象是Context,可以获取到事件和状态信息,这样我们就可以实现更加灵活的控制,该算子会浪费很多性能,主要原因是不增量计算,要缓存整个窗口然后再去处理,所以要设计好内存。

后续还在整理中! 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值