共计 8099 个字符,预计需要花费 21 分钟才能阅读完成。
1. 前言
Apache Flink 是一个分布式流解决引擎,它提供了丰盛且易用的 API 来解决有状态的流解决利用,并且在反对容错的前提下,高效、大规模的运行此类利用。通过反对事件工夫 (event-time)、计算状态(state) 以及恰好一次 (exactly-once) 的容错保障,Flink 迅速被很多公司驳回,成为了新一代的流计算解决引擎。
2020 年 2 月 11 日,社区公布了 Flink 1.10.0 版本, 该版本对性能和稳定性做了很大的晋升,同时引入了 native Kubernetes 的个性。对于 Flink 的下一个稳固版本,社区在 2020 年 4 月底解冻新个性的合入,预计在 2020 年 5 月中旬会推出 Flink 1.11,在新版本中将重点引入新个性,以扩容 Flink 的应用场景。
1.1 Flink 为什么抉择 Kubernetes
Kubernetes 我的项目源自 Google 外部 Borg 我的项目,基于 Borg 多年来的优良实际和其超前的设计理念,并凭借泛滥寒门、大厂的背书,时至今日,Kubernetes 曾经成长为容器治理畛域的事实标准。在大数据及相干畛域,包含 Spark,Hive,Airflow,Kafka 等泛滥出名产品正在迁往 Kubernetes,Apache Flink 也是其中一员。
Flink 抉择 Kubernetes 作为其底层资源管理平台,起因包含两个方面:
1)Flink 个性:流式服务个别是常驻过程,常常用于电信网品质监控、商业数据即席剖析、实时风控和实时举荐等对稳定性要求比拟高的场景;
2)Kubernetes 劣势:为在线业务提供了更好的公布、管理机制,并保障其稳固运行,同时 Kubernetes 具备很好的生态劣势,能很不便的和各种运维工具集成,如 prometheus 监控,支流的日志采集工具等;同时 K8S 在资源弹性方面提供了很好的扩缩容机制,很大水平上进步了资源利用率。
1.2 Flink on Kubernetes 的倒退历史
在 Flink 的晚期发行版 1.2 中,曾经引入了 Flink Session 集群模式,用户得以将 Flink 集群部署在 Kubernetes 集群之上。
随着 Flink 的逐步遍及,越来越多的 Flink 工作被提交在用户的集群中,用户发现在 session 模式下,工作之间会相互影响,隔离性比拟差,因而在 Flink 1.6 版本中,推出了 Per Job 模式,单个工作独占一个 Flink 集群,很大的水平上进步了工作的稳定性。
在满足了稳定性之后,用户感觉这两种模式,没有做到资源按需创立,往往须要凭用户教训来当时指定 Flink 集群的规格,在这样的背景之下,native session 模式利用而生,在 Flink 1.10 版本进入 Beta 阶段,咱们减少了 native per job 模式,在资源按需申请的根底上,进步了利用之间的隔离性。
本文依据 Flink 在 Kubernetes 集群上的运行模式的趋势,顺次剖析了这些模式的特点,并在最初介绍了 Flink operator 计划及其劣势。
2. Flink 运行模式
本文首先剖析了 Apache Flink 1.10 在 Kubernetes 集群上曾经 GA(生产可用)的两种部署模式,而后剖析了处于 Beta 版本的 native session 部署模式和行将在 Flink 1.11 公布的 native per-job 部署模式,最初依据这些部署模式的利弊,介绍了以后比拟 native kubernetes 的部署形式,flink-operator。
咱们正在应用的 Flink 版本曾经很好的反对了 native session 和 native per-job 两种模式,在 flink-operator 中,咱们也对这两种模式也做了反对。
接下来将依照以下程序剖析了 Flink 的运行模式,读者能够联合本身的业务场景,考量适宜的 Flink 运行模式。
- Flink session 模式
- Flink per-job 模式
- Flink native session 模式
- Flink native per-job 模式
这四种部署模式的优缺点比照,能够用如下表格来概括,更多的内容,请参考接下来的详细描述。
2.1 Session Cluster 模式
2.1.1 原理简介
Session 模式下,Flink 集群处于长期运行状态,当集群的 Master 组件接管到客户端提交的工作后,对工作进行剖析并解决。用户将 Flink 集群的资源形容文件提交到 Kubernetes 之后,Flink 集群的 FlinkMaster 和 TaskManager 会被创立进去,如下图所示,TaskManager 启动后会向 ResourceManager 模块注册,这时 Flink Session 集群曾经准备就绪。当用户通过 Flink Clint 端提交了 Job 工作时,Dispatcher 收到该工作申请,将申请转发给 JobMaster,由 JobMaster 将任务分配给具体的 TaskManager。
2.1.2 特点剖析
这种类型的 Flink 集群,FlinkMaster 和 TaskManager 是以 Kubernetes deployment 的模式长期运行在 Kubernetes 集群中。在提交作业之前,必须先创立好 Flink session 集群。多个工作能够同时运行在同一个集群内,工作之间共享 K8sResourceManager 和 Dispatcher,然而 JobMaster 是独自的。这种形式比拟适宜运行短时作业、即席查问、工作提交频繁、或者对工作启动时长比拟敏感的场景。
长处:作业提交的时候,FlinkMaster 和 TaskManager 曾经筹备好了,当资源短缺时,作业可能立刻被调配到 TaskManager 执行,无需期待 FlinkMaster,TaskManager,Service 等资源的创立;
毛病:1)须要在提交 Job 工作之前先创立 Flink 集群,须要提前指定 TaskManager 的数量,然而在提交工作前,是难以精准把握具体资源需要的,指定的多了,会有大量 TaskManager 处于闲置状态,资源利用率就比拟低,指定的少了,则会有任务分配不到资源,只能等集群中其余作业执行实现后,开释了资源,下一个作业才会被失常执行。
2) 隔离性比拟差,多个 Job 工作之间存在资源竞争,相互影响;如果一个 Job 异样导致 TaskManager crash 了,那么所有运行在这个 TaskManager 上的 Job 工作都会被重启;进而,更坏的状况是,多个 Jobs 工作的重启,大量并发的拜访文件系统,会导致其余服务的不可用;最初一点是,在 Rest interface 上是能够看到同一个 session 集群里其他人的 Job 工作。
2.2 Per Job Cluster 模式
顾名思义,这种形式会专门为每个 Job 工作创立一个独自的 Flink 集群,当资源形容文件被提交到 Kubernetes 集群, Kubernetes 会顺次创立 FlinkMaster Deployment、TaskManagerDeployment 并运行工作,工作实现后,这些 Deployment 会被主动清理。
2.2.1 特点剖析
长处:隔离性比拟好,工作之间资源不抵触,一个工作独自应用一个 Flink 集群;绝对于 Flink session 集群而且,资源随用随建,工作执行实现后立即销毁资源,资源利用率会高一些;
毛病:须要提前指定 TaskManager 的数量,如果 TaskManager 指定的少了会导致作业运行失败,指定的多了仍会升高资源利用率;资源是实时创立的,用户的作业在被运行前,须要先期待以下过程:
· Kubernetes scheduler 为 FlinkMaster 和 TaskManager 申请资源并调度到宿主机上进行创立;
· Kubernetes kubelet 拉取 FlinkMaster、TaskManager 镜像,并创立出 FlinkMaster、TaskManager 容器;
· TaskManager 启动后,向 Flink ResourceManager 注册。
这种模式比拟适宜对启动工夫不敏感、且长时间运行的作业。不适宜对工作启动工夫比拟敏感的场景。
2.3 Native Session Cluster 模式
2.3.1 原理剖析
- Flink 提供了 Kubernetes 模式的入口脚本 kubernetes-session.sh,当用户执行了该脚本之后,Flink 客户端会生成 Kubernets 资源形容文件,包含 FlinkMaster Service,FlinkMasterDeloyment,Configmap,Service 并设置了 owner reference,在 Flink 1.10 版本中,是将 FlinkMaster Service 作为其余资源的 Owner,也就意味着在删除 Flink 集群的时候,只须要删除 FlinkMaster service,其余资源则会被以及联的形式主动删除;
- Kubernetes 收到来自 Flink 的资源形容申请后,开始创立 FlinkMaster Service,FlinkMaster Deloyment,以及 Configmap 资源,从图中能够看到,随同着 FlinkMaster 的创立,Dispatch 和 K8sResMngr 组件也同时被创立了,这里的 K8sResMngr 就是 Native 形式的外围组件,正是这个组件去和 Kubernetes API server 进行通信,申请 TaskManager 资源;以后,用户曾经能够向 Flink 集群提交工作申请了;
- 用户通过 Flink client 向 Flink 集群提交工作,flink client 会生成 Job graph,而后和 jar 包一起上传;当工作提交胜利后,JobSubmitHandler 收到了申请并提交给 Dispatcher 并生成 JobMaster, JobMaster 用于向 KubernetesResourceManager 申请 task 资源;
- Kubernetes-Resource-Manager 会为 taskmanager 生成一个新的配置文件,蕴含了 service 的地址,这样当 Flink Master 异样重建后,能保障 taskmanager 通过 Service 依然能连贯到新的 Flink Master;
- TaskManager 创立胜利后注册到 slotManager,这时 slotManager 向 TaskManager 申请 slots,TaskManager 提供本人的闲暇 slots,工作被部署并运行;
2.3.2. 特点剖析
之前咱们提到的两种部署模式,在 Kubernetes 上运行 Flink 工作是须要当时指定好 TaskManager 的数量,然而大部分状况下,用户在工作启动前是无奈精确的预知该工作所需的 TaskManager 数量和规格。
指定的多了会资源节约,指定的少了会导致工作的执行失败。最基本的起因,就是没有 Native 的应用 Kubernetes 资源,这里的 Native,能够了解为 Flink 间接与 Kuberneter 通信来申请资源。
这种类型的集群,也是在提交工作之前就创立好了,不过只蕴含了 FlinkMaster 及其 Entrypoint(Service),当工作提交的时候,Flink client 会依据工作计算出并行度,进而确定出所需 TaskManager 的数量,而后 Flink 内核会间接向 Kubernetes API server 申请 taskmanager,达到资源动态创建的目标。
- 长处:绝对于前两种集群而言,taskManager 的资源是实时的、按需进行的创立,对资源的利用率更高,所需资源更精准。
- 毛病:taskManager 是实时创立的,用户的作业真正运行前, 与 Per Job 集群一样, 仍须要先期待 taskManager 的创立, 因而对工作启动工夫比拟敏感的用户,须要进行肯定的衡量。
2.4 Native Per Job 模式
在以后的 Apache Flink 1.10 版本里,Flink native per-job 个性尚未公布,预计在后续的 Flink 1.11 版本中提供,咱们能够提前一览 native per job 的个性。
2.4.1 原理剖析
当工作被提交后,同样由 Flink 来向 kubernetes 申请资源,其过程与之前提到的 native session 模式类似,不同之处在于:
- Flink Master 是随着工作的提交而动态创建的;
- 用户能够将 Flink、作业 Jar 包和 classpath 依赖打包到本人的镜像里;
- 作业运行图由 Flink Master 生成,所以无需通过 RestClient 上传 Jar 包(图 2 步骤 3)。
2.4.2. 特点剖析
native per-job cluster 也是工作提交的时候才创立 Flink 集群,不同的是,无需用户指定 TaskManager 资源的数量,因为同样借助了 Native 的个性,Flink 间接与 Kubernetes 进行通信并按需申请资源。
- 长处:资源按需申请,适宜一次性工作,工作执行后立刻开释资源,保障了资源的利用率;
- 毛病:资源是在工作提交后开始创立,同样意味着对于提交工作后对延时比拟敏感的场景,须要肯定的衡量;
3. Flink-operator
3.1 简介
剖析以上四种部署模式,咱们发现,对于 Flink 集群的应用,往往须要用户自行保护部署脚本,向 Kubernetes 提交各种所需的底层资源形容文件(Flink Master,TaskManager,配置文件,Service)。
在 session cluster 下,如果集群不再应用,还须要用户自行删除这些的资源,因为这类集群的资源应用了 Kubernetes 的垃圾回收机制 owner reference,在删除 Flink 集群的时候,须要通过删除资源的 Owner 来进行及联删除,这对于不相熟 Kubernetes 的 Flink 用户来说,就显得不是很敌对了。
而通过 Flink-operator,咱们能够把 Flink 集群形容成 yaml 文件,这样,借助 Kubernetes 的申明式个性和协调控制器,咱们能够间接治理 Flink 集群及其作业,而无需关注底层资源如 Deployment,Service,ConfigMap 的创立及保护。
以后 Flink 官网还未给出 flink-operator 计划,不过 GoogleCloudPlatform 提供了一种基于 kubebuilder 构建的 flink-operator 计划。接下来,将介绍 flink-operator 的装置形式和对 Flink 集群的治理示例。
3.2 Flink-operator 原理及劣势
当 Fink operator 部署至 Kubernetes 集群后,FlinkCluster 资源和 Flink Controller 被创立。其中 FlinkCluster 用于形容 Flink 集群,如 JobMaster 规格、TaskManager 和 TaskSlot 数量等;Flink Controller 实时处理针对 FlinkCluster 资源的 CRUD 操作,用户能够像治理内置 Kubernetes 资源一样治理 Flink 集群。
例如,用户通过 yaml 文件形容冀望的 Flink 集群并向 Kubernetes 提交,Flink controller 剖析用户的 yaml,失去 FlinkCluster CR,而后调用 API server 创立底层资源, 如 JobMaster Service, JobMaster Deployment,TaskManager Deployment。
通过应用 Flink Operator,有如下劣势:
1. 治理 Flink 集群更加便捷
flink-operator 更便于咱们治理 Flink 集群,咱们不须要针对不同的 Flink 集群保护 Kubenretes 底层各种资源的部署脚本,惟一须要的,就是 FlinkCluster 的一个自定义资源的形容文件。创立一个 Flink session 集群,只须要一条 kubectl apply 命令即可,下图是 Flink Session 集群的 yaml 文件,用户只须要在该文件中申明冀望的 Flink 集群配置,flink-operator 会主动实现 Flink 集群的创立和保护工作。如果创立 Per Job 集群,也只须要在该 yaml 中申明 Job 的属性,如 Job 名称,Jar 包门路即可。通过 flink-operator,上文提到的四种 Flink 运行模式,别离对应一个 yaml 文件即可,十分不便。
apiVersion: flinkoperator.k8s.io/v1beta1kind: FlinkClustermetadata: name: flinksessioncluster-samplespec: image: name: flink:1.10.0 pullPolicy: IfNotPresent jobManager: accessScope: Cluster ports: ui: 8081 resources: limits: memory: "1024Mi" cpu: "200m" taskManager: replicas: 1 resources: limits: memory: "2024Mi" cpu: "200m" volumes: - name: cache-volume emptyDir: {} volumeMounts: - mountPath: /cache name: cache-volume envVars: - name: FOO value: bar flinkProperties: taskmanager.numberOfTaskSlots: "1"
2. 申明式
通过执行脚本命令式的创立 Flink 集群各个底层资源,须要用户保障资源是否顺次创立胜利,往往随同着辅助的查看脚本。借助 flink operator 的控制器模式,用户只需申明所冀望的 Flink 集群的状态,剩下的工作全副由 Flink operator 来保障。在 Flink 集群运行的过程中,如果呈现资源异样,如 JobMaster 意外进行甚至被删除,Flink operator 都会重建这些资源,主动的修复 Flink 集群。
3. 自定义保留点
用户能够指定 autoSavePointSeconds 和保留门路,Flink operator 会主动为用户定期保留快照。
4. 主动复原
流式工作往往是长期运行的,甚至 2-3 年不进行都是常见的。在工作执行的过程中,可能会有各种各样的起因导致工作失败。用户能够指定工作重启策略,当指定为 FromSavePointOnFailure,Flink operator 主动从最近的保留点从新执行工作。
5. sidecar containers
sidecar 容器也是 Kubernetes 提供的一种设计模式,用户能够在 TaskManager Pod 里运行 sidecar 容器,为 Job 提供辅助的自定义服务或者代理服务。
6. Ingress 集成
用户能够定义 Ingress 资源,flink operator 将会主动创立 Ingress 资源。云厂商托管的 Kubernetes 集群个别都有 Ingress 控制器,否则须要用户自行实现 Ingress controller。
7. Prometheus 集成
通过在 Flink 集群的 yaml 文件里指定 metric exporter 和 metric port,能够与 Kubernetes 集群中的 Prometheus 进行集成。
最初
通过本文,咱们理解了 Flink 在 Kubernetes 上运行的不同模式,其中 Native 模式在资源按需申请方面比较突出,借助 kubernetes operator,咱们能够将 Flink 集群当成 Kubernetes 原生的资源一样进行 CRUD 操作。限于篇幅,本文次要剖析了 Flink 在 Kubernetes 上的运行模式的区别,后续将会有更多的文章来对 Flink 在 Kubernetes 上的最佳实际进行形容,敬请期待。
参考文档
Kubernetes native integration
https://docs.google.com/docum…
Flink operator 应用文档
https://github.com/tkestack/f…
【腾讯云原生】云说新品、云研新术、云游新活、云赏资讯,扫码关注同名公众号,及时获取更多干货!!