Flink是一个分布式处理流式或者批量数据的系统,适用于多种数据处理应用,如实时分析,历史数据处理,迭代算法等,将它们转化为拥有流水机制和容错机制的数据流进行处理。
优势
Apache Flink 同时支持流式及批量分析应用,即批流一体,所以Flink在实时数仓和实时ETL中有天然的优势:
- 状态管理,实时数仓里面会进行很多的聚合计算,这些都需要对于状态进行访问和管理,Flink 支持强大的状态管理
- 表义能力,Flink 提供极为丰富的多层次 API,包括Stream API、Table API及Flink SQL
- 生态完善,实时数仓的用途广泛,Flink 支持多种存储(HDFS、ES 等);
- 批流一体,Flink 已经在将流计算和批计算的 API 进行统一
相对于Spark Streaming,有以下优势
- 架构
- Spark Streaming的架构是基于Spark的,本质是微批处理,可以把Spark Streaming理解为时间维度上的 Spark DAG
- Flink 程序启动后,会根据用户的代码处理成逻辑执行计划
StreamGraph
,然后优化成优化的逻辑执行计划JobGraph
,JobManager会根据JobGraph
生成物理执行计划ExecutionGraph
。当很多个ExecutionGraph
分布在集群中,就会形成一张网状的拓扑结构
- 容错
- 对于Spark Streaming 任务,我们可以配置对应的 checkpoint。当任务出现 failover 的时候,会从 checkpoint 重新加载,使得数据不丢失。但是这个过程会导致原来的数据重复处理,不能做到精确一次处理语义
- Flink基于两阶段提交实现了精确一次处理语义
事件驱动
事件驱动型应用是一类具有状态的应用,它从一个或多个事件流提取数据,并根据到来的事件触发计算、状态更新或其他外部动作。在传统架构中,我们需要读写远程事务型数据库,比如MySQL。在事件驱动应用中数据和计算不会分离,状态保存在本地,所以具有更高的吞吐和更低的延迟。
Flink 的以下特性完美的支持了事件驱动型应用:
- 高效的状态管理,Flink 自带的 State Backend可以很好的存储中间状态信息
- 丰富的窗口支持,Flink 支持包含滚动窗口、滑动窗口及其他窗口
- 多种时间语义,Flink 支持 Event Time、Processing Time 和 Ingestion Time
- 不同级别的容错,Flink 支持 At Least Once 或 Exactly Once 容错级别
架构
部署模式
- 本地模式
- Local
- 模拟cluster集群,仅启动JobManager完成应用的运行
- Local
- 集群模式
- Standalone
- 部署相对简单,可以支持小规模,少量的任务运行
- 缺少系统层面对集群中Job的管理,容易遭成资源分配不均匀
- 资源隔离相对简单,任务之间资源竞争严重
- Yarn
- Yarn-cluster
- 一个Flink任务提交对应一个Yarn的application,任务之间不会有影响
- Yarn-session
- 创建session以后,Yarn会启动一个ApplicationMaster和指定数目的Container。本质上ApplicationMaster扮演的是JobManager的角色,Contaienr扮演的是TaskManager的角色,类似于启动一个Flink的集群
- 之后提交所有的Flink任务在指定的Yarn application运行,Yarn application的失败将会导致所有运行在其上的Flink任务的失败
- Yarn-cluster
- Standalone
- 云模式
- 部署在云服务器上
Runtime层
Runtime层以JobGraph的形式接收程序并执行
- Client: Client 根据用户传入的参数选择使用Yarn-cluster模式、Standalone模式还是Yarn-session模式将 Flink程序转化为数据流图,提交给JobManager去执行
- JobManager
- 集群管理者,协调JobGraph的分布式执行
- 负责调度任务、协调 checkpoints、协调故障恢复、收集 Job 的状态信息,并管理 Flink 集群中的从节点 TaskManager
- TaskManager
- 实际负责执行计算的 Worker,在其上执行Flink Job的一组Task。维护缓冲池以缓冲或物化流,并维护网络连接以在算子之间交换数据流
- 所在节点的管理员,负责把该节点上的服务器信息比如内存、磁盘、任务运行情况等向JobManager汇报
API&LIB层
DataSet
用于处理有限数据集即批处理,而DataStream
用于处理无界数据流即流处理。DataStream API
和DataSet API
均通过单独的编译过程生成JobGraphs,即由有状态算子连接的数据流DAG,交由下层Runtime层去执行。
Flink自带了一些用于特定领域的库,这些库会生成DataSet API
和DataStream API
程序。目前,FlinkML
用于机器学习,Gelly
用于图计算,而Table
用于SQL操作。
资源和资源组
在 Flink 集群中,一个TaskManger就是一个 JVM 进程,并且会用独立的线程来执行Task。如下图所示,每个TaskManger中含有固定的slot,体现了其并发执行能力,slot为运行Task的容器,起到了内存隔离的作用,对 CPU 不起作用。那么运行在同一个 JVM 的 task 可以共享TCP连接,减少网络传输,在一定程度上提高了程序的运行效率,降低了资源消耗。
slot共享
Flink 还允许将不能形成算子链的两个操作放在一个slot中执行。一些简单的map和filter算子所需要的资源不多,但是有些算子比如window、group by则需要更多的计算资源才能满足计算所需。资源需求大的算子可以共用其他的slot,提高整个集群的资源利用率。比如下图中的flatmap和key&sink放在一个slot里执行以达到资源共享的目的。
算子链
这么做是因为 Flink 本身提供了非常有效的任务优化手段,因为 task 是在同一个线程中执行,那么可以有效减少线程间上下文的切换,并且减少序列化/反序列化带来的资源消耗,从而在整体上提高任务的吞吐量,是对执行效率的优化
符合以下条件的算子将合并为算子链
- 上下游算子的并行度相同
下游算子的输入StreamEdge只能有一个
- 上下游算子实例处于同一个 Slotsharing Group中(之后再提)
- 下游节点的连接策略为ALWAYS(可以与上下游链接,
map
、flatmap
、filter
等默认是ALWAYS) - 上游节点的连接策略为ALWAYS或HEAD(只能与下游链接,不能与上游链接,Source默认是HEAD)
- 上下游算子之间没有数据shuffle
- 没有禁用算子链
REFERENCE
- CARBONE P, KATSIFODIMOS A, EWEN S, 等. Apache flink: Stream and batch processing in a single engine[J]. Bulletin of the IEEE Computer Society Technical Committee on Data Engineering, IEEE Computer Society, 2015, 36(4).
- flink官方文档
文档信息
- 本文作者:wzx
- 本文链接:https://masterwangzx.com/2020/04/21/flink/
- 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)