0

Flink模式 - 小白QAQ555

 1 year ago
source link: https://www.cnblogs.com/yl555/p/17209775.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Per-job Cluster

该模式下,一个作业一个集群,作业之间相互隔离。

在Per-Job模式下,集群管理器框架用于为每个提交的Job启动一个 Flink 集群。Job完成后,集群将关闭,所有残留的资源也将被清除。

此模式可以更好地隔离资源,因为行为异常的Job不会影响任何其他Job。另外,由于每个应用程序都有其自己的JobManager,因此它将记录的负载分散到多个实体中。

场景:Per-Job模式适合长期运行的Job,这些Job可以接受启动延迟的增加以支持弹性。

资源管理器支持:Yarn

Application

与per-job 模式相比,在Application 模式下,main() 方法在集群上而不是在客户端执行。

场景:任务启动较慢,适合于长时间运行的大型任务。

资源管理器支持:Yarn、Native kubernetes

Session

该模式下,作业共享集群资源。Session 模式提交的应用都在该集群里执行,会导致资源的竞争。

该模式优势是无需为每一个提交的任务花费精力去分解集群。但是,如果Job异常或是TaskManager 宕掉,那么该TaskManager运行的其他Job都会失败。除了影响到任务,也意味着潜在需要更多的恢复操作,重启所有的Job,会并发访问文件系统,会导致该文件系统对其他服务不可用。此外,单集群运行多个Job,意味着JobManager更大的负载。

场景:该模式适合于对启动延迟要求较高且运行时间较短的作业,例如交互式查询。任务提交速度快,适合频繁提交运行的短时间任务。

资源管理器支持:Standalone、Yarn、Native kubernetes

Flink on kubernetes

Standalone

Standalone模式需要在任务启动时就确定TaskManager的数量,不能像Yarn一样,可以在任务启动时申请动态资源。

很多时候任务需要多少个TaskManager事先并不知道,TaskManager设置少了,任务可能跑不起来,多了又会造成资源浪费,需要在任务启动时才能确定需要多少个TaskMananger。

Standalone Application kubernetes

需要先将用户代码都打到镜像里面,然后根据该镜像来部署一个flink集群运行用户代码。

每提交一个任务,单独启动一个集群运行该任务,运行结束集群被删除,资源也被释放。

Standalone Session kubernetes

在Session模式下,先启动一个Flink集群,然后向该集群提交任务,所有任务共用JobManager。

Native kubernetes

Flink 的 Client 内置了一个 K8s Client,可以借助 K8s Client 去创建 JobManager,当 Job 提交之后,如果对资源有需求,JobManager 会向 Flink 自己的 ResourceManager 去申请资源。这个时候 Flink 的 ResourceManager 会直接跟 K8s 的 API Server 通信,将这些请求资源直接下发给 K8s Cluster,告诉它需要多少个 TaskManger,每个 TaskManager 多大。当任务运行完之后,它也会告诉 K8s Cluster 释放没有使用的资源。相当于 Flink 用很原生的方式了解到 K8s Cluster 的存在,并知晓何时申请资源,何时释放资源。

Native Kubernetes Application

native kubernetes下,application模式相当于提交任务时调k8s api自动拉起一个flink集群跑该应用,然后跑完就删除集群。

这种模式比较适合对启动时间不敏感、且长时间运行的作业。不适合对任务启动时间比较敏感的场景。

优点:隔离性比较好,任务之间资源不冲突,一个任务单独使用一个 Flink 集群;相对于 Flink session 集群而且,资源随用随建,任务执行完成后立刻销毁资源,资源利用率会高一些。

缺点:需要提前指定 TaskManager 的数量,如果 TaskManager 指定的少了会导致作业运行失败,指定的多了仍会降低资源利用率;资源是实时创建的,用户的作业在被运行前,需要先等待以下过程。

flink on native kubernetes application模式:提交任务示例
./bin/flink run-application --target kubernetes-application
-Dkubernetes.namespace=flink-native-kubernetes
-Dkubernetes.cluster-id=flink-application-cluster
-Dkubernetes.jobmanager.service-account=flink
-Dkubernetes.container.image=flink:1.14.2
-Dkubernetes.rest-service.exposed.type=NodePort
-Djobmanager.heap.size=1024m
-Dkubernetes.jobmanager.cpu=1
-Dkubernetes.taskmanager.cpu=2
-Dtaskmanager.memory.process.size=1024m
-Dtaskmanager.numberOfTaskSlots=2
local:///opt/flink/examples/batch/WordCount.jar
应用镜像构建方式:
`FROM flink:1.14.2
 RUN mkdir -p $FLINK_HOME/usrlib
 COPY my-flink-job.jar $FLINK_HOME/usrlib/my-flink-job.jar`

Native Kubernetes Session

native kubernetes下,session模式是提前调k8s api启动一个常驻的flink集群,然后客户端提交任务时,调k8s api自动起一个taskmanager pod 运行任务,然后等任务运行完之后,这个taskmanager的任务pod会被销毁。

flink on native kubernetes session模式:

1、kubectl create namespace flink-session-cluster

2、kubectl create serviceaccount flink -n flink-session-cluster

3、kubectl create clusterrolebinding flink-role-binding-flink --clusterrole=edit --serviceaccount=flink-session-cluster:flink

启动session集群:
4、./bin/kubernetes-session.sh \
 -Dkubernetes.namespace=flink-session-cluster \
-Dkubernetes.jobmanager.service-account=flink \
 -Dkubernetes.cluster-id=flink-session-cluster \
 -Dkubernetes.rest-service.exposed.type=NodePort  \
-Dkubernetes.container.image=flink:1.14.2

flink on native kubernetes session模式:提交任务示例
./bin/flink run -d --target kubernetes-session  \
-Dkubernetes.namespace=flink-session-cluster  \
-Dkubernetes.cluster-id=flink-session-cluster \
 -Dkubernetes.jobmanager.service-account=flink \
-Dkubernetes.rest-service.exposed.type=NodePort \
/opt/flink-1.14.2/examples/batch/WordCount.jar

Flink on K8s :

优点:

Flink 在 K8s 上最简单的方式是以 Standalone 方式进行部署。这种方式部署的好处在于不需要对 Flink 做任何改动,同时 Flink 对 K8s 集群是无感知的,通过外部手段即可让 Flink 运行起来。

缺点:

  • 无论 Operator、Helm Chart 或者是直接使用 Kubectl Yaml 的方式,Flink 都感知不到 K8s 的存在。
  • 目前主要使用静态的资源分配。需要提前确认好需要多少个 TaskManager,如果 Job 的并发需要做一些调整,TaskManager 的资源情况必须相应的跟上,否则任务无法正常执行。
  • 用户需要对一些 Container、Operator 或者 K8s 有一些最基本的认识,这样才能保证顺利将 Flink 运行到 K8s 之上。
  • 对于批处理任务,或者想在一个 Session 里提交多个任务不太友好。无法实时申请资源和释放资源。因为 TaskManager 的资源是固定的,批处理任务可能会分多个阶段去运行,需要去实时地申请资源、释放资源,当前也无法实现。如果需要在一个 Session 里跑多个 Job 并且陆续运行结束当前也无法实现。
  • 如果维持一个比较大的 Session Cluster,可能会资源浪费。但如果维持的 Session Cluster 比较小,可能会导致 Job 跑得慢或者是跑不起来。

基于这几点,社区推进了一个 Native 的集成方案。让Flink 原生的感知到下层 Cluster 的存在。Native 是相对于 Flink 而言的,借助 Flink 的命令就可以达到自治的一个状态,不需要引入外部工具就可以通过 Flink 完成任务在 K8s 上的运行。

生产环境上推荐:

Flink on YARN(pre-job、application)、Flink on Native Kubernetes Appliation;

Flink on Kubernetes 需考虑的问题:

日志问题

日志需要通过k8s的pod日志排查。如果出现节点宕机,pod飘移到别的节点,日志获取困难。

应用jar包问题

flink on k8s的application模式需要将jar包以及依赖放在镜像里启动。

应用依赖问题

有依赖的任务,无法通过客户端获取信息。k8s不支持pre-job模式。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK