了解一个系统当然是先从整体的架构开始(难道不应该是quick start吗?):

Flink Architecture

如上图,Flink这个分布式流批统一计算框架也是典型的主从架构,JobManager是主,TaskManager是从。JobManager其实是一个统称,其内部根据功能拆分成了3个大模块:

  • ResourceManager:如其名,就是做资源管理的。Flink里面资源是以TaskManager提供的Slot形式存在的,所以其实就是管理Slot的。TaskManager启动后会向ResourceManager报告自己的slot情况,并且通过心跳和通知机制定期更新。之所以把这个模块单独出来,是因为资源管理框架已经很多了(但功能、实现、使用又有差异),比如YARN、Mesos、Kubernetes。所以单独出来以后,方便分别实现支持不同框架的ResourceManager 。另外,ResourceManager在设计上:(1)是无状态的,因为它的数据都是别人主动报告给它的,所以重启后可以重新获取。不过有的实现可能会有一点状态。(2)故障后不影响已经在运行的任务。ResourceManager一个集群只有一个**。
  • JobMaster:JobMaster主要负责Job的调度运行、Checkpoint/Savepoint的触发、故障恢复等。每个Job都有一个自己的JobMaster
  • Dispatcher:Dispatcher的主要任务是接收Client提交上来的任务(这里的任务就是Job),然后为该任务创建JobMaster,之后将任务交给JobMaster去调度管理。所以Dispatcher自身并不会运行用户的代码,而且它提供的功能基本都是以http服务的形式向外暴露的,所以长期看,社区想把这个模块演变成一个Gateway,这样对于一些安全要求高的场景,这个模块就可以作为代理放在防火墙之外或对外网暴露(当然需要加认证),目前Flink WebUI的功能也是在该组件里面的。不考虑standby的情况下,Dispatcher一个集群只有一个

注意

  1. 这里JobManager和JobMaster可能容易混淆,在早期版本,很多地方(包括官方文档)把JobMaster也称为JobManager,所以如果看一些旧的文档,一定要注意说的JobManager是指广义的JobManager(即包含ResourceManager、JobMaster、Dispatcher)还是狭义的JobManager(即只指JobMaster)。甚至有些时期的文档把广义的JobManager称为JobMaster,把JobMaster称为JobManager
  2. 注意区分“任务”这个词指的是Job还是组成Job的Task,本文中的任务基本都指的是Job。

所以,一个flink任务提交流程就是图中所示的6步:

  1. 用户通过Client(比如命令行 flink run和Web UI)提交任务到Dispatcher;
  2. Dispatcher为该任务创建JobMaster;
  3. JobMaster向ResourceManager申请资源(即Slot);
  4. 此时如果没有资源,并且ResourceManager有动态创建TaskManager的能力(有的部署方式有,有的部署方式没有,后面介绍),ResourceManager就会创建TaskManager;没有动态创建TaskManager能力的部署方式,则需要先部署好TaskManager;
  5. TaskManager创建好之后,向ResourceManager注册自己的资源;
  6. ResourceManager分配资源后,该资源的所有者TaskManager就会向JobMaster提供资源。

Flink集群管理目前支持Standalone、YARN、Mesos、Kubernetes几种方式,不同的部署模式下,上面JobManager里面的组件的存在形式可能会有一些差异。

这部分的实现是在flink-runtime这个模块里面的,而且代码里面的命名和上面讲的大多是能直接对应上的,这部分是Flink的核心,设计也比较优雅,如果想深入源码了解Flink的内部运行机制,这个runtime模块自然是首选。

最后说一下这个Client,它虽然不是Flink运行期的一部分,但却是提交任务的窗口,凡是可以向集群提交任务的“工具”都可以称之为Client。截止目前,主要有如下Client:

  • Scala Shell(bin/start-scala-shell.sh
  • SQL Client(bin/sql-client.sh
  • CommandLine(bin/flink
  • RESTful
  • Web
  • Python Shell(bin/pyflink-shell.sh

以上内容基于目前最新的Flink 1.12.0版本。更多细节可参考: