一、flink是什么?

Apache Flink是一个框架和分布式处理引擎,用于无界和有界数据流上的有状态计算。Flink被设计成可以在所有常见的集群环境中运行,以内存中的速度和任何规模执行计算;

Flink运行模式 flink-runtime-web_高可用


二、flink on yarn作业提交流程

1、未引入 Dispatcher 的架构

客户端提交 JobGraph 以及依赖 jar 包到 YarnResourceManager

接着 Yarn ResourceManager 分配第一个 container 以此来启动 AppMaster

Application Master 中会启动一个 FlinkResourceManager 以及 JobManager

JobManager 会根据 JobGraph 生成的 ExecutionGraph 以及物理执行计划向 FlinkResourceManager 申请 slot

FlinkResoourceManager 会管理这些 slot 以及请求

如果没有可用 slot 就向 Yarn 的 ResourceManager 申请 container

container 启动以后会注册到 FlinkResourceManager

最后 JobManager 会将 subTask deploy 到对应 container 的 slot 中去

Flink运行模式 flink-runtime-web_Flink运行模式_02


YARN without Dispatcher2、引入 Dispatcher 的架构

YARN with Dispatcher

Flink运行模式 flink-runtime-web_zookeeper_03


会增加一个过程,就是 Client 会直接通过 HTTP Server 的方式,然后用 Dispatcher 将这个任务提交到 Yarn ResourceManager 中,同时运行Web UI。。

在一些案例中,Dispatcher 是可选的(Yarn)或者不兼容的(kubernetes)。

引入 Dispatcher 的原因是:

一些集群管理器需要一个中心化的作业生成和监控实例。
实现 Standalone 模式下 JobManager 的角色,等待作业提交。
ResourceManger
ResourceManager 的主要任务是:

请求新的 TaskManager (或者更细粒度的 slot),方式是直接将资源池的 TaskManager 分配给作业或启动新的 container (如果资源池没有足够资源)再将其分配给作业。
发送错误提醒消息给 JobManager 和 TaskManager。
缓存 TaskManager (container) 以便重复利用,并将一段时间未使用的空闲资源归还给集群。
ResourceManager 的资源级别或许是 TaskManager 级别,或许是 slot 级别(大概率是 slot 级别),但对于 ResourceManager 来说区别很小: 一个是维护可用 TaskManager 的映射,另外一个是维护可用 slot 的映射。

TaskManager
TaskManager 会与 ResouceManager 和 JobManager 两者联系。一方面,它会告诉 ResourceManager 自身的可用资源;另一方面,它需要和与 JobManager 联系以在它的 slot 上执行 task。TaskManager 需要向以上两者报告心跳。

TaskManger 和 ResourceManager 的交互
TaskManager 初始化时需要先在 ResourceManager 注册。如果与 ResourceManager 的连接断开,TaskManager 会重新注册并报告它的可用资源。
对 ResourceManager 的每次心跳会附上自己的可用 slot 信息,这样 ResourceManager 可以保持获得最新的可用资源信息。作为补充,当一个 slot 变为可用时 TaskManager 会直接通知 ResourceManager 以避免心跳带来的延迟。
TaskManager 关于哪些 slot 被哪个 JobManager 持有的视图是最为可靠的,ResourceManager 会根据 TaskManager 的心跳和通知来得出自己的资源视图。
ResourceManager 会告诉 TaskManager 将一个 slot 交给指定的 JobManager,然后 TaskManager 会按要求将 slot 提供给那个 JobManager。如果 slot 没有被接受,TaskManager 会通知 ResourceManager 这个 slot 实际上是可用的。
ResourceManager 会告诉 TaskManager 退出程序。
TaskManager 和 JobManager 的交互
TaskManager 按照 ResourceManager 吩咐将 slot 提供给 JobManager。这个 slot 会和 JobManager 绑定知道 JobManager 释放它。
TaskManager 会监视所有持有它的 slot 的 JobManager,与一个 JobManager 的连接断开会导致 master-failure 恢复(当前的方式是取消所有来自这个 JobManager 的 task )。
JobManager 可以且只可以在分配给它的 slot 上部署 task。
当与一个 JobManager 断开连接,TaskManager 会尝试在新的 JobManager (通过 HA leader 查找来获取)上重新注册这些 slot。经过一段过渡时间后,TaskManager 会释放这些 slot 来令它们恢复可用状态。如果备用的 JobManager 没有在这段时间内接手这些 slot,那么它需要重新向 ResourceManager 申请资源。
JobManager SlotPool
JobManager 有一个 SlotPool 来暂存 TaskManager 提供给它并被接受的 slot。JobManager 的调度器从这个 SlotPool 获取资源,因此即使 ResourceManager 不可用 JobManager 仍然可以使用已经分配给它的 slot。

当 SlotPool 无法满足一个资源请求时,它会向 ResourceManager 请求新的 slot。这时如果 ResourceManager 不可用,或者 ResourceManager 拒绝了请求,或者请求超时,都会导致 slot 请求失败。

SlotPool 会将未使用的 slot 归还给 ResourceManager。一个 slot 被视为未使用的标准是当作业已经完全处于运行状态时它未被使用。

Dispatcher
Dispathcer 是在新设计里引入的一个新概念。Dispatcher 会从 client 端接受作业提交请求并代表它在集群管理器上启动作业。

三、Standalone 模式的架构总览

常驻 JobManager 的角色目前是一个“本地的 Dispatcher”进程,它会在内部生成作业以及 JobManager。而 ResourceManager 会一直存活,处理 TaskManager 的注册。对于高可用配置,会有多个 dispatcher 进程竞争 leader,类似于目前的 JobManager。

Flink运行模式 flink-runtime-web_zookeeper_04


Standalone 架构

四、资源分配详解
首先需要了解一系列概念:

ResourceID: TaskManager (container) 的唯一 ID。

RmLeaderID: ResourceManager 的 Leader 的任期识别符,用于识别来自新旧 ResourceManager leader 的请求(旧 leader 可能不知道自己已经不是 leader)。

JobID: 作业在一个生命周期的唯一 ID。

JmLeaderID: JobManager 的唯一 ID,也是一个任期识别符,每当 JobManager 接受一个作业这个 ID 就会改变,用于识别来自新旧 JobManager leader 的请求(旧 leader 可能不知道自己已经不是 leader)。

AllocationID: 一次 slot 分配的 ID,由每次 JobManager 请求资源时创建,不会因为重试请求而变化,用于识别 ResourceManager 的回覆和识别对 TaskManager 发出的部署请求。

Profile: 申请的资源的简介,包括 CPU 核数、内存、磁盘等资源。

1、请求新的 TaskManager 的 slot 分配流程

请求新的 TaskManager 的 slot 分配流程

Flink运行模式 flink-runtime-web_flink_05


消息丢失的处理方法:消息(4)或消息(6)的丢失会以重试消息(4)的方式处理。ResourceManager 不会请求重复的实例,因为已经有 slot 分配给相应的 AllocationID,或者有处理中的请求是对应那个 AllocationID。如果那个 slot 在重试之前就已经被释放了,那么会导致一个多余的 container,它最终将作为未使用的 container 被释放。

消息(10)丢失会以 TaskManager 重新注册的方式处理。ResourseID 会帮助识别重复的注册请求。

消息(12)丢失会以简单重试的方式处理。重复的分配资源请求会被 JobManager 识别出来,后者会拒绝请求或者接受注册但随后作为未使用资源释放。

消息(13)丢失并不要紧,因为随后的 TaskManager 心跳也会携带相同内容。

消息(14)丢失会导致 TaskManager 不断重试,这可以通过(AllocationID, ResourceID)二元组来识别。

2、来自缓存 TaskManager 的 slot 分配流程

来自缓存 TaskManager 的 slot 分配流程

Flink运行模式 flink-runtime-web_flink_06


消息丢失的处理方法和上文一样。

上述的 slot 分配流程达到了如下的目的:

TaskManager 和 JobManager 维护重要的 slot 可用性和保留信息,ResourceManager 只有临时信息,扮演了经纪人的角色。
ResourceManager 应该总是先将 slot 标记为被占用,然后 TaskManager 上的 slot 才实际被分配出去,因此不会尝试将一个已经被占用的 slot 分配出去。对应的异常是 ResourceManager 端的请求 timeout,这因为 TaskManager 拒绝对一个被占用的 slot 的再次分配。
五、进程崩溃处理
1、TaskManager 崩溃
由于 TaskManager 分别向 ResourceManager 和 JobManager 报告心跳,因此两者都可以检测到 TaskManager 崩溃。

在 ResourceManager 端:

通过 TaskManager 心跳超时来检测 TaskManager 崩溃。
在 YARN/Mesos 模式,额外通过集群管理器检测进程崩溃。
将崩溃的 TaskManager 从存活列表清除。
通知持有该 TaskManager 的 slot 的 JobManager。
启动相同配置的 TaskManager 作为替代。
在 JobManager 端:

通过 TaskManager 心跳超时来检测 TaskManager 崩溃。
可能会额外收到来自 ResourceManager 的关于 TaskManager 崩溃的通知。
将该 TaskManager 的 slot 从 SlotPool 移除。
将该 TaskManager 运行的所有 Task 标记为失败,执行常规的 Task 恢复。
如果没有足够多的资源来达到配置的并行度,缩小作业的规模。
TaskManager 上会丢失的数据:

正在执行的算子的状态,需要在 Task 重启时从 checkpoint 恢复。
TaskManager 的恢复操作:

重启的 TaskManager 会寻找 ResourceManager,注册并提供它的 slot。
2、ResourceManager 崩溃
TaskManager 需要向 ResourceManager 报告心跳,JobManager 需要向 ResourceManager 申请和归还资源,因此两者都可以检测到 ResourceManager 的崩溃。

在 TaskManager 端:

通过报告心跳超时来检测 ResourceManager 崩溃。
高可用配置下,zookeeper 会通知 TaskManager ResourceManager leader 切换。
TaskManager 重新进入注册循环,但是不需要取消 Task。
在注册完成后,TaskManager 向新的 ResourceManager 报告当前可用的 slot 以及已经被占用的 slot 是被哪个 JobManager 占用。
在 JobManager 端:

通过与 ResouceManager 的心跳检测到对方崩溃。
高可用配置下,zookeeper 会通知 JobManager ResourceManager leader 切换。
JobManager 等待新的 ResourceManager 变为可用(leader 选举完成会有通知),然后重新请求所有正在处理中的资源分配请求。
ResourceManager 会丢失的数据:

当前活跃的 container。这可以通过集群管理器恢复。
可用的 slot。这可以通过 TaskManager 重新注册恢复。
已经分配给 JobManager 的 slot。这也可以通过 TaskManager 重新注册恢复。
正在处理的 slot 分配。这不会被恢复,JobManager 会重新对这部分 slot 进行资源请求。
3、JobManager 崩溃
JobManager 的崩溃同样也可以被另外两者检测到。

在 TaskManager 端:

通过心跳超时检测到 JobManager 崩溃。
高可用配置下,zookeeper 会通知 TaskManager Jobmanager leader 切换。
TaskManager 执行 master 崩溃恢复,即清楚所有的来自该 JobManager 的 Task。
TaskManager 尝试在新的 JobManager 上注册自己,一段时间后会超时。
如果一段时间后仍没有成功在新 JobManager 上注册,TaskManager 会将这些 slot 释放并告知 ResourceManager。
在 ResourceManager 端:

通过心跳检测到 JobManager 崩溃。
高可用配置下,zookeeper 会通知 ResourceManager JobManager leader 切换。
可选地,告知 TaskManager JobManager 崩溃的消息。
JobManager 会丢失的数据:

JobGraph 和作业依赖库。这可以通过持久化存储恢复。
已经完成的 checkpoint。这可以通过 HA checkpoint 存储(zookeeper)恢复。
Task 的执行情况。所有的 Task 都被重置为 checkpoint 的时间点。
已经注册的 TaskManager。通过 TaskManager 重新注册和 ResourceManager 重新分配资源恢复。
JobManager 的恢复操作:

获取 leader 状态。
向 ResourceManager 注册自己(以获取 TaskManager 崩溃的通知)。
从最近的 checkpoint 恢复正在运行的作业。
4、JobManager 和 ResourceManager 同时崩溃
TaskManager 处理常规的 JobManager 崩溃。
TaskManager 尝试提供 slot 给恢复的 JobManager,一段时间后超时。
TaskManager 不断循环尝试向 ResourceManager 注册自己。
5、TaskManager 和 ResourceManager 同时崩溃
JobManager 不能通过 ResourceManager 的通知得知 TaskManager 的崩溃,但仍可以通过 TaskManager 的心跳发现。
正在处理的资源分配请求会超时(或者直接被 JobManager 取消,因为 ResourceManager 已经不可用),新的资源分配请求会在 ResourceManager 复活时再发送。
JobManager 需要减小作业规模,因为一些 slot 已经随 TaskManager 丢失了。