Flink是一个分布式系统,需要有效分配和管理计算资源才能执行流应用程序。Flink同时提供了支撑流计算和批计算的接口,以下是对Flink架构的详细解析:
一、架构分层
Flink的架构体系基本上可以分为三层,由上往下依次是:
- API&Libraries层:作为分布式数据处理框架,Flink在此基础之上抽象出不同的应用类型的组件库,如基于流处理的CEP(复杂事件处理库)、SQL&Table库,和基于批处理的FlinkML(机器学习库)、Gelly(图处理库)等。API层包括构建流计算应用的DataStream API和批计算应用的DataSet API,两者都提供给用户丰富的数据处理高级API,例如Map、FlatMap操作等,同时也提供比较低级的Process Function API,用户可以直接操作状态和时间等底层数据。
- Runtime核心层:该层主要负责对上层不同接口提供基础服务,也是Flink分布式计算框架的核心实现层,支持分布式Stream作业的执行、JobGraph到ExecutionGraph的映射转换、任务调度等。它将DataSteam(流作业)和DataSet(批作业)转成统一的可执行的Task Operator,达到在流式引擎下同时处理批量计算和流式计算的目的。
- 物理部署层:该层主要涉及Flink的部署模式。目前Flink支持多种部署模式,包括本地、集群(Standalone/YARN)、云(GCE/EC2)、Kubenetes。Flink能够支持不同平台的部署,用户可以根据需要选择对应的部署模式。
二、组件构成
Flink整个系统主要由两个组件组成,分别为JobManager和TaskManager,Flink架构也遵循Master-Slave架构设计原则,JobManager为Master节点,TaskManager为Worker(Slave)节点。
-
Client:
- 作用:Client 是 Flink 应用程序提交的入口点。它负责将用户编写的 Flink 应用程序打包成 JAR 文件,并提交给 JobManager。
- 功能:Client 负责将用户编写的 Flink 程序转换成一个 JobGraph(作业图),然后将这个 JobGraph 提交给 JobManager。Client 还可以用来监控作业的状态和获取日志信息。
-
JobManager:
- 作用:JobManager 是 Flink 集群的主控节点,负责协调和管理整个集群的资源分配、作业调度和容错。
- 功能:
- ResourceManager:负责Flink集群中的资源提供、回收、分配。它管理task slots,这是Flink集群中资源调度的单位。Flink为不同的环境和资源提供者(例如YARN、Kubernetes和standalone部署)实现了对应的ResourceManager。
- JobMaster:负责管理和协调单个作业的执行。每个作业都有一个对应的 JobMaster。
- Dispatcher:提供了一个REST接口,用来提交Flink应用程序执行,并为每个提交的作业启动一个新的JobMaster。同时,它也会运行Flink WebUI,用来提供作业执行信息。
- Checkpoint Coordinator:负责触发和协调 Checkpoint 操作,以保证状态的一致性和容错性。
-
TaskManager:
- 作用:TaskManager 是 Flink 集群的工作节点,负责执行具体的任务。
- 功能:
- Slot:TaskManager 中的资源单位,每个 Slot 可以运行一个 Task(子任务)。TaskManager 可以有多个 Slot,每个 Slot 可以看作是一个独立的 JVM 线程。
- Task:实际执行计算逻辑的任务。一个 Task 可以是 Source、Transformation 或 Sink。
- Network Stack:负责 Task 之间的数据交换和通信。
- Buffer Management:管理内存中的缓冲区,用于暂存数据和优化数据传输。
此外,Client不是运行时和程序执行的一部分,而是用于准备数据流并将其发送给JobManager。之后,客户端可以断开连接(分离模式),或保持连接来接收进程报告(附加模式)。
三、运行原理
- 当用户提交作业的时候,提交脚本会首先启动一个Client进程负责作业的编译与提交。Client首先将用户编写的流式处理代码编译为一个JobGraph,还会进行一些检查或优化等工作,例如判断哪些Operator可以Chain到同一个Task中(合并)。
- 然后,Client将产生的JobGraph提交到集群中执行。此时有两种情况:一种是类似于Standalone这种Session模式,AM(Flink Master白框中的组件)会预先启动,此时Client直接与Dispatcher建立连接并提交作业即可;另一种是Per-Job模式,AM不会预先启动,此时Client将首先向资源管理系统(如Yarn、K8S)申请资源来启动AM,然后再向AM中的Dispatcher提交作业。
- 作业到Dispatcher后,Dispatcher会首先启动一个JobManager组件,然后JobManager会向ResourceManager申请资源来启动作业中具体的任务。
- ResourceManager选择到空闲的Slot之后,就会通知相应的TaskManager“将该Slot分配给JobManager XX”,TaskManager进行相应的记录后,会向JobManager进行注册。JobManager收到TaskManager注册上来的Slot后,就可以实际提交Task了。
- TaskManager收到JobManager提交的Task之后,会启动一个新的线程来执行该Task。Task启动后就会开始进行预先指定的计算,并通过数据Shuffle模块互相交换数据。
总结
-
作业提交:
- 用户通过 Client 提交 Flink 作业。
- Client 将作业转换成 JobGraph 并提交给 JobManager。
-
资源分配:
- JobManager 的 ResourceManager 负责分配 TaskManager 的 Slot。
- JobManager 的 Dispatcher 接收 JobGraph 并创建 JobMaster。
-
作业调度:
- JobMaster 将 JobGraph 转换成 ExecutionGraph,并分配给 TaskManager 的 Slot。
- TaskManager 执行具体的 Task。
-
数据流处理:
- Task 之间通过网络栈进行数据交换。
- Task 执行具体的计算逻辑,如 Map、Filter、Reduce 等。
-
容错和 Checkpoint:
- JobManager 的 Checkpoint Coordinator 触发 Checkpoint 操作。
- TaskManager 执行 Checkpoint,保存状态到外部存储。
- 如果发生故障,Flink 可以从最近的 Checkpoint 恢复作业状态,继续处理数据。
四、核心特性
- 流处理和批处理统一:同时支持高吞吐、低延迟、高性能。Flink 提供了统一的 API 来处理流数据和批数据,使得开发者可以使用相同的代码来处理不同类型的数据。
- 状态管理:Flink 提供了强大的状态管理功能,支持多种状态后端(如内存、RocksDB 等),并提供了高效的 Checkpoint 机制来保证状态的一致性和容错性。
- Exactly-Once 语义:Flink 支持 Exactly-Once 语义,确保每条记录只被处理一次,即使在故障恢复的情况下也是如此。
- 支持事件时间(Event Time)概念:Flink 支持基于事件时间的时间窗口处理,确保在乱序事件的情况下也能得到正确的处理结果。
- 支持有状态计算。
- 支持高度灵活的窗口(Window)操作。
- 基于轻量级分布式快照(Snapshot)实现的容错。
- 基于JVM实现独立的内存管理。
- Save Points(保存点)。
- 多层级API。
- 灵活的部署:Flink 可以部署在多种环境中,包括 YARN、Kubernetes、Mesos 以及 standalone 模式。
五、部署模式
Flink支持多种部署模式,包括:
- 本地模式。
- 集群模式:可以是Standalone模式或基于YARN的模式。
- 云模式:如GCE、EC2等。
- Kubernetes模式。
其中,Session模式是先有Flink集群后再提交任务,任务在客户端提交运行,提交的多个作业共享Flink集群。Per-Job模式和Application模式都是提交Flink任务后创建集群。Per-Job模式通过客户端提交Flink任务,每个Flink任务对应一个Flink集群,每个任务有很好的资源隔离性。Application模式是在JobManager上执行main方法,为每个Flink的Application创建一个Flink集群,如果该Application有多个任务,这些Flink任务共享一个集群。
六、Flink 的应用场景
- 实时数据分析:如日志分析、用户行为分析、实时报表等。
- 事件驱动应用:如实时推荐系统、欺诈检测、实时报警系统等。
- ETL 流程:数据抽取、转换和加载,支持从多种数据源读取数据并写入多种数据目标。
- 流处理:如流式 ETL、流式机器学习、流式图处理等。
总的来说,Flink架构是一个高度模块化、可扩展和灵活的分布式处理引擎,能够处理无边界和有边界的数据流,满足各种实时和批处理需求。