1.0 Flink的简介
-
Flink是什么
- Apache Flink is a framework and distributed processing engine for stateful computations over unbounded and bounded data streams. 快速灵巧
-
为什么选择Flink
- 流数据更真实地反映了我们的生活方式
- 传统的数据架构是基于有限数据集的(因为批处理数据更简单)
- 我们的目标是低延迟 高吞吐 结果的准确性和良好的容错性
-
lambda架构:先快速的得到一个近似的结果 在用batch layer慢一点得到正确的结果
-
流(stream)和微批(micro-batching) 底层的架构不一样
问题:如果要开始 处理 一开始 没有想过要处理的的数据,没有太大的办法.
因为flink是替代原架构的spark streaming的部分
2.0 快速上手
- 批处理
- 流处理(并行度 运行时的概念)
- 每一步是一个并行度还是怎么样 这是一个问题 可以往下看 在回头来看看
3.0 Flink部署
3.1 Standalone
晚上再测试一下
单节点的standalone 还有 多节点的standalone的 都需要测试的
3.2 Yarn模式
- Session-cluster : 适合规模小 执行时间短的作业
- Per-Job-cluster : 适合规模大 长时间运行的作业
Session-cluster模式:
开启命令: ./yarn-session.sh -s 2 -jm 1024 -tm 1024 -nm test -d
启动命令: ./flink run -c com.atguigu.wc.StreamWordCount FlinkTutorial-1.0-SNAPSHOT-jar-with- dependencies.jar --host localhost –port 7777
Per-Job-cluster:比启动yarn-session 直接
3.3 Kubernetes部署
略
4.0 Flink运行架构
什么是solt 怎么划分的
4.1 Flink运行时的组件
JobManager TaskManager ResourceManager Dispatcher
资源就是TaskManager上的slots
4.2 任务提交流程
抽象的任务提交(下图):
4.3 任务调度原理
- 怎么实现并行计算
- 同时处理 有两个map(数据并行)
- 并行的任务,需要占用多少slot
- 一个任务的最大的并行度
- 一个流处理程序,到底包含多少个任务
4.3.5 任务链
两个要求:one to one 和 要相同的并行度
5.0 Flink 流处理API
5.1 Environment
- 底层调用的代码不一样 但是使用的时候 我们直接使用getExecutionEnvironment即可
5.2 Source
5.3 Transform
- map
- flatMap
- Filter
- KeyBy(键控流) : DataStream–>KeyedStream
- 滚动聚合算子(针对的是每一个key , Rolling Aggregation) : sum() min() max() minBy() maxBy()
- 其中min 和 minBy 的区别就是: minBy会保存下除了相关字段的其他条件 ; 但是min不会,只会关注相关字段
- Reduce (一般聚合)
- split 和 select (分流)
- Connext 和 CoMap|CoFlatMap (合流) 其实就是两个判断条件,但是这两个条件都是以流的形式存在,所以需要这两个流合并
- 连接两条流(两条路不一定要一样的结构) 也只能是两条流 连接两条流之后就已经变成ConnectedStream类型
- Union(可以处理多条流 连接的流的类型必须是一样的 )
5.4 支持的数据类型
- 基础数据类型
- Java和scala元组(Tuples)
- scale样例类(case classes)
- Java简单对象(POJOS)
- 其他(Arrays Lists Maps Enums)
5.5 实现UDF函数–更细粒度的控制流
- 函数类(Function Classes)
- Flink暴露了所有udf函数的接口
- 匿名函数(Lambda Functions)
- 富函数(Rich Functions)
- 可以获取运行环境的上下文和状态,并拥有一些生命周期的方法(状态编程)
5.6 Sink
- kafka
- Redis
- ElasticSearch
- JDBC 自定义sink
https://github.com/wushengran/FlinkTutorial.git
6.0 Flink中的Window
总结 :
-
主要就是Flink中的窗口函数的使用 可以使用简单的timewindow 来进行滚动或者滑动窗口 或者 countwindow 还是比较简单的 (也可以使用window() 比较一般的方法 具体的方法可以在代码上查看)
-
然后还有一些可以使用的其他api
-
重要的有两点 第一: 当开窗的时候 后面一定需要使用Window function 来进行聚合 (增量聚合函数 或 全窗口函数)
6.1 Window
- window是一种切割无限数据为有限块进行处理的手段
- 因为我们真实情况中,对数据其实是有时间有要求的(譬如 1 个月 一年)
- 这个时候的数据是还没有过来的,数据来了之后,判断时间,放入不同的桶里面
- window 类型:
- CountWindow :
- 滚动计数窗口
- 滑动计数窗口
- TimeWindow :
- 滚动时间窗口(Tumbling Windows)
- window size
- 特点:时间对齐,窗口长度固定,没有重叠(数据只属于一个窗口)
- 范围是 前闭后开"[ )"
- 相当于特殊的滑动窗口(size=slide)
- 滑动时间窗口(Sliding Windows)
- window size 和 window slide
- 特点:时间对齐,窗口长度固定,可以有重叠
- window size 有几个window slide 那么数据就同时属于几个窗口
- 会话窗口(Session Windows)
- session gap
- 特点:时间无对齐
- 当两个数据之间的时间间隔大于等于window gap的时候,后一个数据就属于新的窗口
- window(EventTimeSessionWindows.withGap(Time.second(10)))
- 滚动时间窗口(Tumbling Windows)
- CountWindow :
- 上述的方法都可以使用window的一般函数来进行调用
6.2 Window API
-
window()接收的输入参数是一个 window Assigner 之后用窗口函数来返回成为DataStream
-
window Function
- 增量聚合函数
- 来一个处理一次,保留当前状态
- (sum|max|reduceFunction|aggregateFunction)
- 全窗口函数
- 先收集所有的数据,等到计算的时候才会遍历所有数据*(相当于把所有的数据存储为状态)*
- apply(可以拿到Windows的信息)|process
- 增量聚合函数
-
其他API
- trigger() —— 触发器,定义 window 什么时候关闭,触发计算并输出结果
- evitor() —— 移除器,定义移除某些数据的逻辑
- allowedLateness() —— 允许处理迟到的数据(触发计算但是不关闭窗口 快速的输出一个结果 但是之后时间允许继续更新数据)
- sideOutputLateData() —— 将迟到的数据放入侧输出流
- getSideOutput() —— 获取侧输出流
7.0 时间语义与watermark
总结 :
- 操作方式简单来讲就是先引入eventtime
env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- 再对DataStream进行操作(引入watermark)
dataStream.assignTimestampsAndWatermarks(new BoundedOutOfOrdernessTimestampExtractor[](Time.second(1)){
override def extractTimestamp(element: SensorReading): Long = {
element.timestamp * 1000
}
})
7.1 Flink中时间语义
- Event time : 事件事件 , 最有意义
- Ingestion time : 数据进入Flink的时间
- Processing time : 处理数据的时间
7.2 EventTime的引入
val env = StreamExecutionEnvironment.getExecutionEnvironment
// 从调用时刻开始给env创建的每一个stream追加时间特征
env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
7.3 WaterMark
7.4 EventTime在window中的使用
- 乱序 : Flink接收到的事件的先后顺序不是严格按照时间的Event Time顺序排序的(事件时间的语义下才有意义)
- Watermark(水位线) : 相当于延迟关窗的时机 做到了关窗和放数据的分离
- watermark的传递 : 上游的多个watermark传递到这里时,选用最小的watermark ; 传递到下游的时候,全部发送一样的watermark
- 周期性和非周期性的watermark
- watermark的设定 : maxOutOfOrderness 可能设定的不是特别理想 但是还是需要有一个权衡 一般的话 可以先调成小一点
flink里面的思想 : 你需要自己做权衡
7.4.1 offset 间隔的起始
底层有公式 " timestamp - (timestamp