本文收拾自字节跳动根底架构工程师刘畅,在 Flink Forward Asia 生产实践专场的分享。字节跳动具有业界抢先的 Flink 流式核算使命规划。随着云原生年代的到来,咱们开端探索将线上的 Flink 使命从 Hadoop 搬迁到 Kubernetes,使得作业云原生化运转。本篇首要从字节跳动 Flink 大规划云原生化实践布景、处理计划、生产实践、未来展望四个方向展开介绍。

一、布景介绍

资源办理演进

字节跳动 Flink 大规模云原生化实践

字节跳动的大数据资源办理架构,以及 Flink 的布置演进,大致能够分为三个阶段。

第一阶段,彻底根据 YARN 的离线资源办理。大规划运用 YARN 办理的大数据集群,有用提高了 Flink 的资源运用率,并降低了资源运营、运维等方面的本钱。于此一起,针对 Flink 的特性,对 YARN 做了许多定制研制,如支撑 Gang 调度等。在此阶段,Flink集群已经到达了相当大的规划。

第二阶段,离线资源混部阶段。经过构建 YARN 和 K8s 混合布置集群,进一步提高在线和离线的整体资源运用率。并经过混部技能计划,使集群/单机资源利用率都得到显著提高。更高的单机利用率,意味着需求更完好的隔离手段,因此逐渐开端推进 Flink 的容器化布置并获得了相应成效。

第三阶段,彻底的云原生化布置。在线负载和离线负载不再运用不同的架构进行办理,真实完结了技能栈共同和资源池共同,Flink 的云原生化也在逐渐构建完善。

云原生的优势

字节跳动 Flink 大规模云原生化实践

云原生化简直是业界共同的开展趋势,那么为什么要选择云原生 K8s 作为共同的资源办理底座呢?

  • 高效运维。K8s 供给灵敏的负载创立和办理,无论是在线负载仍是 Flink 大数据负载,都能够快捷完结继续开发、集成和布置。
  • 资源共池。共同的云原生底座减少了根底设施开支,也进一步提高了资源流通功率。在新年、双11等大型活动场景下,在离线资源能够高效、灵活地相互转化;在资源利用率方面,整个数据中心的利用率能够得到更全面、充沛的提高,降本增效
  • 生态繁荣。K8s 具有简直最活跃的生态圈,它经过供给规范化的接口界说,促进了各个层次的生态开展,无论是根底运维设施、上层运用办理仍是底层的网络、存储等办理中都有十分多的可选计划,Flink 的云原生化也为未来的计划运用供给了便利。

Flink 事务规划

字节跳动 Flink 大规模云原生化实践

字节跳动具有业界抢先的 Flink 事务规划,现在 Flink 每天运转的作业数稀有百万个,占有资源量数百万核,总的集群规划节点也到达了上万台,如此大规划的 Flink 负载意味着彻底的 Flink 云原生化并不是一件轻松的作业,关于关键问题的考虑请阅读下面的内容。

关键问题

字节跳动 Flink 大规模云原生化实践

Flink 的大规划云原生化有几个关键问题需求考虑。

  • Flink 作业的布置办理,是 Standalone 的静态布置仍是 K8s Native 动态布置,是否运用 Operator ?
  • 在 K8s 上如何完结 Flink 作业的租户级别资源管控,在作业提交时进行管控,仍是在 Pod 创立时进行管控?
  • 如何支撑 Flink 的调度需求?在 Flink 作业提交或重启时,许多的 Pod 创立是否引起调度瓶颈?
  • 大规划作业的架构搬迁,周边才能如何建设,需求重整旗鼓,仍是尽可能复用?

二、处理计划

布置计划

关键问题:Flink 如安在 K8s 上运转?

第一种,Standalone 布置形式。这种形式下,Flink 作业依靠的一切资源,都由作业提交用户建议创立。其原理和运用比较简单,但存在资源利用功率低,Failover 本钱高级问题。

第二种,Kubernetes Native 布置形式。这是现在社区比较推荐的布置形式,Jobmanager 能够依据作业的需求自主创立 Taskmanager Pod,但彻底的 Native 布置形式仍然存在一些问题:

  • 没有完好的生命周期状况描绘和办理;
  • 批调度对接本钱高;
  • 短少大局视角,不容易进行一些大局的调控。

除此之外,Flink 布置也能够调配运用 Operator,现在 Operator 一般针对负载单独定制,未来进行多种负载混部时,就需求布置多套 Operator,这无疑加大了运维上的本钱。

布置计划

字节跳动 Flink 大规模云原生化实践

为了更便利的办理 Flink 等大数据负载,字节自研了一个共同的大数据 Operator Arcee。如图所示,Arcee 运转在 K8s 底座之上,向上能够一起支撑 Flink 的流式和批式作业。Arcee 的中心才能首要包含作业生命周期办理、作业资源办理和一些引擎的定制功用等。

字节跳动 Flink 大规模云原生化实践

Arcee 的中心设计思路是,两级作业办理。Arcee 学习了 YARN 的两级办理形式,即中心办理服务 AM,首要担任创立和保护大数据作业,再由 AM 创立保护核算 Worker。对应到 Flink 作业中就是由 Arcee 创立 JM,JM 创立所需的 TM。这种办理形式,一方面能够有用办理和表达大数据作业状况,定制造业办理战略。另一方面也能够保证核算引擎对核算作业运转有充沛的掌握才能,有才能按需调整资源运用。

字节跳动 Flink 大规模云原生化实践

Arcee 整体架构

如图所示,Arcee Operator 内部包含了六个模块:

  • Arcee CRD,Arcee 界说了 ArceeApplication 和 ArceeCommand 两种资源类型。ArceeApplication 用于描绘详细的作业,ArceeCommand 描绘用于作业的操作;
  • Webhook 模块,首要用于 Application / Pod 的装备注入和校验;
  • Application Manager 担任作业的生命周期办理;
  • PodSetManager 是作业资源办理;
  • EngineManager 是引擎办理,用于完结一些引擎定制才能;
  • Schedulermanager 是调度器对接层,用于完结 Flink 等大数据作业与批调度器的对接。

根据这幅图,作业完好的提交流程是当上层建议 Flink 作业提交时,作业提交渠道调用 Flink Client,并填上所需的参数向 K8s 提交作业。在 Arcee 形式下,Flink Client 运用内置的 Arcee Client 创立 Flink Arceeapplication,由 Webhook 预处理后提交到 Apiserver。接下来,由 Arcee Controller 收到 Application 的创立事情,Arcee applicationManager 生成对应的作业状况,并依据 Application 内的描绘创立 JM,并由 JM 依据 Job 创立所需的 TM,Arcee 会继续监听一切 TM 的创立,相同也会进行相关装备的注入。Application 内 JM、TM 的一切 Pod 都会保护在 Arcee 的 PodsetManager 中,用于资源运用核算,并向其他模块供给相关信息。

字节跳动 Flink 大规模云原生化实践

以上能够发现,Flink 运用 Arcee 的布置形式和 K8s Native 布置形式有相似之处。Flink on Arcee 在一定程度上能够认为是 Flink Native 布置形式的改进。详细的差异如下:

  • Jobmanager 的创立和生命周期办理,由 JobManager Development 担任完结。JM 启动后,Resource Manager模块能够直接和 K8s API Server 进行通讯,完结 TaskManager Pod 的创立和销毁作业。在这种架构下,关于 K8s 来说,JM 和 TM 简直是彻底独立两部分资源。

字节跳动 Flink 大规模云原生化实践

Flink on Arcee 的架构有如下不同:

  • Flink Client 中的 K8s Client 替换成 Arcee Client;
  • 担任办理 JM 负载的组件由 Controller Manager 变成 Arcee Operator;
  • 担任拉起 Jobmanager 的 Deployment 变成了Arcee Application;
  • JM 和 TM 从各自独立变成具有共同的 Application 进行保护。

字节跳动 Flink 大规模云原生化实践

Arcee 供给的详细功用

  • 作业生命周期办理:Arcee 供给了一个细粒度的作业状况机叫做作业资源状况。经过作业资源状况,能够知道作业的资源创立处于什么阶段,此外也能够反映作业的运转终态及 Flink 的内部状况。Arcee 也供给了多种 Failover战略,用户能够依据状况定制重启战略,现在能够支撑 Never、Always、Onfailure 多种重启战略,支撑装备最大重启次数,支撑底层反常失败探查。

字节跳动 Flink 大规模云原生化实践

  • 调度屏蔽:关于 Flink 大数据作业来说,往往需求调配运用批调度器。批调度器与一般的调度器不同的点在于,批调度器运用的时分 需求额定创立批调度单元,并继续观察批调度端元的状况。现在,业界没有给出一个规范的批调度处理形式。Arcee 屏蔽了底层调度细节,核算引擎自身不需求关怀调度器的接入方法,Arcee 的作业资源办理模块能够完结调度对接。

资源办理计划

关键问题:如何完结 Flink 作业的租户资源管控?如何完结高功能的批调度?

字节跳动 Flink 大规模云原生化实践

租户的资源管控最中心的才能是集群资源的公平分配。此外还需求供给租户内的高/低优作业排队与抢占。Flink 的大数据负载和在线负载的不同点在于在线负载中 Pod 的创立简直彻底是用户建议的,创立所需资源量也是创立前明确的。但可动态调整的大数据负载不同,一是 Pod 的创立时间不确定,二是所需资源量不确定。这也就需求提前为用户划分资源并进行管控,防止某个作业占满集群。

除此之外,批调度才能也是 Flink 云原生需求处理的重要问题。首要,Flink 流式作业一般需求 All-or-Nothing 的调度才能,不然可能会呈现资源死锁。其次,许多的 Pod 创立要求调度器具有很高的调度吞吐才能。最终,字节跳动内部,Flink 曩昔在 YARN 上有许多调度定制才能,如真实负载均匀,大局黑名单等。这些都是经过实践能有用优化 Flink 运转的战略,搬迁至 K8s 后仍然保留了下来。

资源办理计划

字节跳动 Flink 大规模云原生化实践

为了处理租户资源管控问题和批调度相关问题,经过研制一个根据云原生的高功能资源办理调度器—— GRO 调度器,完结集群资源的管控。

GRO 在 K8s 上增加了“行列”和“作业”的界说,其中行列对应了 Queue CRD,是 Quota 资源配额的笼统;作业对应了 PodGroup CRD,描绘了一个“作业”调度单元,标识多个 Pod 属于同一个调集。别的 GRO 还供给了一个作业信息核算界说-OpJob CRD,用于供给细粒度的作业资源计量及状况信息。

字节跳动 Flink 大规模云原生化实践

在问题介绍部分提到了 Flink 负载的两个特点—— Pod 创立时间不确定、所需资源量不确定。在这两个特点下,调度器是最适合做租户管控的组件。

GRO Scheduler 参阅 YARN 等大数据调度器,在 Pod 放置的根底上增加了 Quota 管控。首要,GRO 会经过一切行列的 Min(保证资源)、Max(资源上限)属性将集群资源公平地分配给各个行列。接下来,再依据不同调度战略(优先级调度、Gang 调度等),将行列资源分配给行列内的各个调度单元,再进一步分配给作业界的各 Pod,经过以上调度流程就能够在 K8s 上完结较细致的租户资源管控。

调度器的实质作业是资源调度,GRO Scheduler 具有 Flink 负载所需求的批调度才能。首要,GRO 支撑 Gang 调度,能够供给 All-or-Nothing 调度语义,并在此根底上完结了调度快速失败功用,用于防止Flink作业长时间等候。其次,GRO具有高调度吞吐才能,在支撑杂乱调度战略的前提下,调度吞吐功能仍然能够到达每秒上千 Pod。最终,GRO 具有丰厚的放置才能。除了支撑大部分原生功用外,还支撑真实负载均匀、GPU 同享、微拓扑调度等大数据场景的高级战略。

渠道计划

关键问题:不同架构下作业&行列办理如何切换?

字节跳动 Flink 大规模云原生化实践

无论底层运用的是什么资源办理架构,作业和行列的基本办理操作在用户和上层渠道看来大体是共同的。首要包含作业查询/ Kill,行列的创立/扩缩容等。此外,作业的 Webshell 登录、日志查询等周边服务,在不同架构下运用不同的组件完结对应功用。但一些依靠上层元数据完结的功用如权限控制等,在架构搬迁前后也需求对应完结。那么就需求根据新架构,考虑将上层渠道进行从头接入仍是复用原有架构的数据和才能,打平前后接入差异?显然,如果能打平差异,做到上层事务渠道的无感接入是最优的计划。

渠道计划

字节跳动 Flink 大规模云原生化实践

为了完结前后架构根底办理和周边才能的打平,构建了一套前后复用的资管架构渠道计划——Megatron 离线调度用户渠道,首要是为了便利多事务渠道查询接入,缓解底层 YARN 的查询压力。以上的定位和功用设计使 Megatron 成为最适合做架构屏蔽的渠道。不仅为多种事务渠道供给共同的接口,也具有较完好的作业和行列办理才能。其中,首要功用有作业同步、行列办理、数据查询、权限管控等。因此,Megatron 针对新的云原生底座进行了适配,成为了一个为 YARN 和 Kubernetes 一起供给简单快捷且共同的离线核算资源及作业办理渠道。

三、生产实践

字节跳动 Flink 大规模云原生化实践

Flink 云原生化在字节跳动的生产实践情况。现在,流式通道使命,Streaming SQL,Streaming Java 等流式使命,都已完结云原生构架的适配。包含抖音、电商、推荐在内的简直一切 Flink 事务,都已完结了新架构的接入。此外,这一整套架构也已完结了产品化的进程。

字节跳动 Flink 大规模云原生化实践

在作业搬迁方面的实践,关于上层用户来说,作业的架构搬迁看起来就是一次行列切换。作业提交服务会经过 Megatron 查询行列的属性,并主动生成对应的提交参数。Arcee 层面也尽可能的为用户屏蔽环境因素,此外 Flink 引擎在前后架构适配上,也做了十分多的改造作业,包含 Classloader 的差异兼容等。

为了加快公司内架构搬迁的发展,构建了一套主动搬迁流程。经过定期梳理待搬迁的作业列表,并按照一定频率触发作业的行列切换重启,Quota 渠道会相应的进行搬迁前行列的缩容和后续行列的继续扩容,机器就会从老架构集群搬迁至新架构集群。在实践的搬迁过程中,主动化搬迁能够到达接近 1000 /天的作业搬迁速度。

字节跳动 Flink 大规模云原生化实践

在 Flink on K8s 的环境中,日志和监控目标也是十分重要的,它能够帮助咱们观察整个集群、容器、使命的运转情况,依据日志和监控快速定位问题并及时处理。所以也在 Flink 云原生化的过程中逐渐构建了一套 Trace 系统。Flink 供给了事务目标,单机的 Metrics Collector 组件供给了物理机目标和容器目标。在日志方面,经过每个 Node 上运转的 Log Agent 采集指定路径的日志主动上传至日志渠道进行解析查询。一切的目标和日志,都能够根据 Megatron 的渠道化实时查询,也供给了详细的数据表,用户能够依据需求进行更高阶的查询,比如制造报表,作业调优,作业反常发现等。

字节跳动 Flink 大规模云原生化实践

在上量过程中,除了才能的构建也进行了生产上的优化。能够分为针对控制面的管控优化和 Flink 运转的运转优化。在管控优化方面,对 K8s Client 进行了拆分和参数调优,防止不同的 Apiserver 操作相互干扰。运用异步多线程处理方法提高系统自身作业的处理吞吐,经过优化与 Apiserver 的交互频率,尽可能减少不必要的资源操作。

在压测中,咱们发现与 Apiserver 的交互是作业处理流程中开支最大的一环。经过交互优化,一方面减小了 Apiserver 的压力,另一方面也减少了 Apiserver 交互带来的处理开支。在运转优化方面,构建起了 Region 级别的唯一性检测,用来防止 Flink 作业的双跑。在远端资源下载方面,经过运用 P2P 进行下载加快,此外还参阅 YARN 完结了资源的同享复用,减轻整体的下载压力。云原生的布置计划使得 Flink 能够运用更高阶的隔离才能,经过引入 Sidecar 的布置形式,将资源消耗较大的组件集成在 Flink Pod 中,用来防止这些组件对机器上的其他作业产生影响。

四、未来展望

字节跳动 Flink 大规模云原生化实践

未来的作业将首要围绕三个方面。

  • 多云架构的设计落地和根据多云的容灾才能构建;
  • 资源的弹性混部,一起进行资源调优,在保证 Flink 运转质量的一起进一步提高资源利用率;
  • 功能和集群规划上的继续提高,未来将不断提高 Controller、调度器等的处理才能,用于支撑像容灾类的极高吞吐要求场景,并支撑更大规划的集群。