Flink是一个分布式系统,要求有效地分配和管理计算资源以执行流式应用程序。它集成了所有常见的集群资源管理器,如Hadoop YARN和Kubernetes,但也可以设置为作为standalone甚至库运行。
本节概述了Flink的体系结构,并描述了其主要组件如何交互以执行应用程序以及从故障中恢复。
Flink运行时由两种类型的进程组成:一个JobManager和一个或多个TaskManager。
Client 不是运行时和程序执行的一部分,而是用于准备数据流并将其发送到JobManager。之后,Client 可以断开连接(分离模式),或者保持连接以接收进度报告(附加模式)。Client 要么作为触发执行的Java/Scala程序的一部分运行,要么在命令行进程/bin/flink run ...
中运行
JobManager和TaskManager可以通过各种方式启动:直接在机器上作为standalone启动,在容器中启动,或者由YARN等资源框架管理。TaskManager连接到JobManager,宣布自己可用,并被分配工作。
JobManager 有许多与协调Flink应用程序的分布式执行相关的职责:它决定何时安排下一个任务(或一组任务),对已完成或执行失败的任务做出反应,协调检查点,并协调故障恢复等。该进程由三个不同的组件组成:
至少有一个JobManager。一个高可用性设置可能有多个JobManager,其中一个始终是leader,其他则是备用(standby)(请参阅高可用性(HA))。
TaskManager(也称为worker)执行数据流任务,缓冲和交换数据流。
必须始终至少有一个TaskManager。TaskManager中资源调度的最小单位是任务槽(task slot)。任务槽的数量表示并发处理任务的数量。请注意,可能在一个任务槽中执行多个Operator
对于分布式执行,Flink 将算子的 subtasks 链接成 tasks。每个task由一个线程执行。将将operator链接成task是一种有用的优化:它减少了线程切换和缓冲的开销,并在降低延迟的同时提高了整体吞吐量。可以配置链接行为;请参阅chaining docs查看详细信息。
下图中的示例数据流由五个Subtask执行,因此由五个并行线程执行
每个worker(TaskManager)都是一个JVM进程,可以在单独的线程中执行一个或多个子任务。为了控制单个TaskManager接受的任务数,就有了所谓的task slot(至少一个)。
每个 task slot 表示TaskManager的固定资源子集。例如,具有三个slot 的TaskManager会将其托管内存的1/3专用于每个插槽。划分资源意味着subtask不会与其他作业的subtask争夺托管内存,而是有一定数量的保留托管内存。请注意,这里没有进行CPU隔离;当前slot仅隔离任务的托管内存。
通过调整task slot 的数量,用户可以定义如何将subtask彼此隔离。每个TaskManager有一个slot 意味着每个任务组都在一个单独的JVM中运行(例如,可以在一个独立的容器中启动)。拥有多个slot 意味着更多的subtask共享同一JVM。同一JVM中的任务共享TCP连接(通过多路复用)和心跳消息。它们还可以共享数据集和数据结构,从而减少每个任务的开销。
默认情况下,Flink允许subtask共享slot ,即使它们是不同task的subtask ,只要来自同一job即可。结果就是,一个slot可以容纳job的整个管道。允许这种“slot共享”有两个主要好处:
main()
方法在集群上运行,而不是在client运行。job提交是一个一步到位的过程: 你不需要先启动Flink集群,然后向现有集群会话提交job ,相反,你将应用程序逻辑和依赖项打包到一个可执行的作业JAR包中,集群入口点(ApplicationClusterEntryPoint
) 负责调用main()
方法来提取JobGraph。这允许你像Kubernetes上的任何其他应用程序一样部署Flink应用程序。Flink应用程序集群的生命周期因此与Flink应用的生命周期绑定。以前,Flink会话集群也称为session mode
下的Flink集群。
https://nightlies.apache.org/flink/flink-docs-master/docs/concepts/flink-architecture/