流/批/OLAP 一体的 Flink 引擎介绍 | 青训营笔记
这是我参与「第四届青训营 」笔记创作活动的第2天
重点内容:
一、Flink概述
1、为什么需要流式计算?
大数据的实时性带来价值更大,比如:
-
监控场景:如果能实时发现业务系统的健康状态
-
实时推荐:比如在抖音,如果可以根据用户的行为数据发掘用户的兴趣、偏好,就能向用户推荐更感兴趣的内容
-
金融风控:如果实时监测出异常交易的行为,就能及时阻断风险的发生
2、Flink为什么能脱颖而出
流式计算框架对比:
| Storm | Spark Streaming | Flink | |
|---|---|---|---|
| Streaming Model | Native | mini-batch | Native |
| 一致性保证 | At Least/Most Once | Exactly-Once | Exactly-Once(精确一次的计算语义) |
| SEE | 低延迟(毫秒级) | 延迟较高(秒级) | 低延迟(毫秒级) |
| 吞吐 | Low | High | High |
| 容错 | ACK | RDD Based Checkpoint | Checkpoint ( Chandy-Lamport) |
| StateFul | No | Yes ( DStream ) | Yes (Operator) |
| SQL支持 | No | Yes | Yes |
Flink的特点:
-
精确一次的计算语义
-
状态容错
-
Dataflow编程模型、windows等高阶需求支持友好
-
流批一体
二、Flink整体架构
1、Flink分层架构
图一:
-
SDK层:目前主要有三类SQL/Table、DataStream、Python
-
执行引擎层(Runtime层):Runtime层提供统一的DAG,用来描述数据处理的流水线,不管是流还是批,都会转换为DAG图,调度层再把DAG转换成分布式环境下的Task,Task之间通过Shuffle传输数据
-
状态存储层:负责存储算子的状态信息
-
资源调度层:目前Flink可以指出部署在多种环境
2、Flink整体架构
一个Flink集群,主要包含以下两个核心组件
1、JobManager (JM):协调 Flink 应用程序的分布式执行。它决定何时调度下一个 task(或一组 task)、对完成的 task 或执行失败做出反应、协调 checkpoint、并且协调从失败中恢复等等。这个进程由三个不同的组件组成:
- Dispatcher:接受作业,拉起JobManager来执行作业,并在JobMaster挂掉之后恢复作业。
- JobMaster:管理一个job的整个生命周期,会向ResourceManager申请slot,并将task调度到对应TM上。
- ResourceManage:负责slot资源的管理和调度,Task manager拉起之后会向RM注册。
2、TaskManager (TM):执行作业流的 task,并且缓存和交换数据流。在TaskManager中资源调度的最小单位是 task slot。TaskManager 中 task slot 的数量表示并发处理 task 的数量。一个 Slot只能运行同一个task的subTask
图二:
3、Flink如何做到流批一体
(一)做到流批一体相比于单独使用批流两套系统的优点:
-
1.做到流批一体人力成本比较低,而使用批、流两套系统,相同逻辑需要开发两遍
-
2.单独使用批流两套系统会导致数据链路冗余--本身计算内容是一致的,由于是两套链路,相同逻辑需要运行两遍,产生一定的资源浪费,而流批一体可以很好的解决这个问题
-
3.单独使用批流两套系统会导致据口径不一致--两套系统、两套算子、两套UDF,通常会产生不同程度的误差,这些误差会给业务方带来非常大的困扰,使用流批一体可以很好的解决业务方的困扰
(二)为什么可以做到流批一体
站在Flink的角度,Everything is Streams,无边界数据集是一种数据流,一个无边界的数据流可以按时间切段成一个个有边界的数据集,所以有界数据集(批式数据)也是一种数据流。
因此,不管是有边界的数据集(批式数据)还是无边界数据集,Flink都可以天然地支持,这是 Flink支持流批一体的基础。并且Flink在流批一体上,从上面的API到底层的处理机制都是统一的,是真正意义上的流批一体。
主要从下面几个模块进行流批一体:
-
SQL层
-
DataSteam API层统一,批和流都可以使用DataSteam API开发
-
Schedler层架构统一,支持流批场景(主要负责将作业的DAG转化为在分布式环境中可以执行的Task)
在Flink1.12版本前,支持两种调度模式:
| 模式 | 特点 | 场景 |
|---|---|---|
| EAGER | 申请一个作业所需的所有资源,同时调度这个作业的所有task,task之间采用pipeline通信 | Stream作业场景 |
| LAZY | 先调度上游,等待上游产生护具或结束后再调度下游,类似Spark的STAGE执行模式 | Batch作业场景 |
-
Failover Recovery层架构统一,支持流批场景
-
Shuffle Service层架构统一,根据不同场景选择不同服务
实际上,分布式计算中所有涉及到上下游衔接的过程,都可以理解为Shuffle.
针对不同的分布式计算框架,Shufle通常有几种不同的实现:
1、基于文件的Pull Based Shuffle.具有较高容错性,适合大规模批处理作业,容错性更好。比如spark或MR。
2、基于Pipeline的Push Based Shuffle,具有低延时高性能,比如Flink,Storm。
流和批Shuffle之间的差异:
1、Shuffle的生命周期:流作业Shuffle数据与Task绑定,批作业和Shuffle是解耦的
2、Shuffle数据存储介质:流作业的Shuffle存储在内存,批作业的Shuffle存储在磁盘
3、Shuffle的部署方式:流作业的Shuffle服务和计算节点部署在一起,可以减少网络开销,从而减少延迟,批作业不同
在Streaming和OLAP场景:
- 为了性能的需要,通常会使用基于Pipeline的Shuffle模式
在Batch场景
- 一般会选取Blocking的 Shuffle模式
为了统一Flink在 Streaming和 Batch模式下的Shuffle架构,Flink 实现了一个 Pluggable的 ShuffleService框架,抽象出一些公共模块。
三、Flink架构优化
三种场景对比:
| 流式计算 | 批式计算 | 交互式分析(OLAP) | |
|---|---|---|---|
| SQL | Yes | Yes | Yes |
| 实时性 | 高、处理延退毫秒级别 | 低 | 高、查询延退在秒级但要求高并发查询 |
| 容错能力 | 高 | 中,大作业失败重跑代价高 | 没有,失败重试即可 |
| 状态 | Yes | No | No |
| 准确性 | Exactly Once 要求高,重跑需要恢复之前的状态 | Exactly Once 失败重跑即可 | Exactly Once 失败重跑即可 |
| 扩展性 | Yes | Yes | Yes |
通过前面的分析,可以发现:
-
1.批式计算是流式计算的特例,Everything is Streams,有界数据集(批式数据)也是一种数据流、 一种特殊的数据流
-
2.而OLAP计算是一种特殊的批式计算,它对并发和实时性要求更高,其他情况与普通批式作业没 有特别大区别。
所以Flink可以做到流/批/OLAP 一体的
注:
图片来源
图一:青训营