Flink 作业资源管理
目前,Flink是无法做到Job在运行时动态调整并行度的,不经历重启直接拉起新的Task实列进行运行,目前都是基于重启恢复机制来实现的,因为涉及到状态管理
Flnk 在资源管理中,资源的获取方式包含两种模式:
- Active 模式:主动式,Flink 可以主动的申请、释放资源(通过与资源管理框架集成,如:Yarn、Mesos)
- Reactive 模式:被动响应式,该模式由外部系统来进行分配,释放资源,Flink只是简单地对可用资源进行响应。(这种模式对于基于容器环境相当有意义,如K8S)
现在Flink的资源管理模式是Action 模式,有用户明确指定Job需要的资源,JobMaster 会像ResourceManager 去请求用户的指定的全量资源,当ResourceManager 无法满足JobManager 的申请需求时,该Job 将无法进行正常启动,它会陷入失败重启-》再次尝试申请的循环。
为了能够同时支持Active/Reactive 这两种模式,Flink 1.12.0 版本引入了申明式资源管理设计
该功能和原先最大的差别在于:JobMaster 不再去逐个请求Slot,二十申明需要的资源情况,对资源要求是弹性范围的,不是固定的。
弹性资源包含四个参数(min,targer,max,rs)
- min:执行job的最小资源
- target:jobMaster 期望获得的常规资源需求,它是可变的,这是扩缩容的主要出发机制。
- max: 最大资源期望
- rs: resource spc(资源描述信息)
动态调整:
将Flink任务部署运行在K8S容器上的,使用Flink Reactive Mode 响应模式,将Flink集群部署在K8s容器种,通过K8S的Pod 水平自动扩缩容器组件来实现Flink作业资源TaskManager的动态改变。
K8s 的Pod的水平自动缩放组件会监控所有的TaskManager Pods 的cpu 负载来相应的调整副本因子(replication factor)。当cpu 负载升高时,autoscaler 会增加TaskManage资源来平摊压力,当负载降低时,autoscaler会减少TaskManager资源
启动步骤
Filnk 在k8s 上部署flink 集群,主要包含以下几个步骤:
- Flink客户端使用Kubectl 或者K8s 的Dashboard 提交Flink 集群的资源描述文件,包含4-5个yaml文件.
- K8s Master 根据这些资源文件将请求分发给slave 节点,创建Flink Master Delpoyment、TaskManager、Deployment、ConfigMap、SVC四个角色.同事初始化Dispatcher和KubernetesResourceManager.并通过K8s 服务对外暴露Flink Master 端口
- Client 用户使用Flink run 的命令,通过指定Flink Master 的地址,将相应的任务提交上来,用户的jar 和jobGrapth 会在Flink Client 生成,通过SVC 传给Dispatcher.
- Dispatcher 收到JobGraph后,回味每个作业启动一个jobMaster,将jobGraph交给jobMaster进行调度.
- jobMaster 会向KubernetesResourceManager申请资源,请求slot
- KubernetesResourceManager从k8s 集群分配TaskManager.每个TaskManager 都是具有唯一标识的Pod KubernetesResourceManager会为TaskManager 生成一份新的配置文件,里面有Flink Master 的 service name 作为地址,保障在Flink Master failover后,TaskManager仍然可以重新连接上.
- K8S集群分配一个新的pod后,在上面启动TaskManager
- TaskManager 启动了后注册到SlotManager
- SlotManager 向TaskManager请求Slot
10.TaskManager 提供Slot 给JobManager,然后任务呗分配到Slot上级运行.
Flink on K8S 通信问题
-
POD 内部通信. 直接通过localhost相互访问就可以
-
同节点的POD 的通信. 通过默认的docker网桥互连容器直接通信就可
-
不同节点的POD 之间通信; 通过安装Flannel 组件,pod 的ip 分配由flannel 同一分配,通讯过程也是走flannel 的网桥
-
外部网络 与POD 之间通信; 使用Service 服务,通过lable 关联到后端的Pod 的容器
Service分配的ip叫 cluster ip ,这是一个固定的虚拟ip ,这个ip 只能在k8s 集群内部使用,如果service需要对外提供,只能使用Nodeport 方式映射到主机上,使用主机的ip 和端口和对外提供服务