2022年,火山引擎云原生计算团队在云原生大数据领域进行了诸多探索与实践。基于此,云原生计算与 DataFun 联合出品了云原生大数据知识地图,从理念概述、架构介绍、功能详述、场景及价值等方面对云原生大数据进行了详细解读。
在 DataFun 五周年庆知识地图发布会上,云原生大数据知识地图正式发布。火山引擎云原生计算资深产品专家迟慧在会上进行了深度讲解。
关注「字节跳动云原生计算」公众号,后台回复“知识地图”获取高清版
随着行业的快速发展和业务的高速迭代,数据量也呈爆炸式增长,传统的大数据架构在资源利用、高效运维、可观测性等方面存在诸多不足,已经越来越无法适应当下的发展需求。具体来讲,传统大数据架构主要存在以下几方面的问题:
- 传统大数据组件繁多,安装运维复杂,在生产使用中需要大量的人力支持;
- 在线业务和大数据业务各自使用独立的资源池,使得资源流转困难,利用率低,成本上升;
- 传统大数据架构没有 CICD 机制,缺少测试和质量控制流程;
- 传统大数据缺少开箱即用的高可用、多租户、日志、监控、告警、认识、授权、审计、计费等能力。
云原生大数据是大数据平台新一代架构和运行形态,是一种以平台云原生化部署、计算云原生调度、存储统一负载为特点,可以支持多种计算负载,计算调度更弹性,存储效能更高的大数据处理和分析平台。云原生大数据带来了大数据在使用和运维方面的巨大变化,从以下三个角度来看:
-
业务层面:传统模式下,业务独立占用资源,在业务高峰时段占用全部资源,但在低谷时段资源占用率可能只有20%-30%;云原生模式下的业务是混部的,比如在线和离线业务,它可以按分时复用的方式来调用资源。
-
资源调度层面:在传统模式下,如果一个 Flink 集群有100台机器,那这100台机器就由它独占;云原生模式虚拟化出了资源池的概念。资源池可以承载不同类型的大数据集群,可以装 Flink 集群,也可以装 Spark 集群,而且这些集群都是按需拉起的,可以迅速回收,在不需要时可以释放掉。
-
统一部署和运维安装:原来的运维方式是每个集群要运维每个自己集群的状态,出现集群之间的时延或者故障时,问题定位比较复杂。而云原生有统一的服务管理界面,以 Helm Chart 或 Operator 的形式,统一对服务进行发布、运维。这样,出现问题时,我们可以通过统一的界面进行查看和管理,监控告警日志也是和 K8s Pod(进程) 的采集、Node 采集相统一的,在监控告警上,我们既可以看到 K8s 的节点和容器,也可以看到服务的运行状态。
云原生大数据平台的功能架构可以总结为“三大平台和一大支撑体系”。三大平台分别是平台服务层、核心引擎层和资源调度层。
- 平台服务层由开源组件插件化集成,支持灵活配置选用;
- 核心引擎层包括 Flink、Spark、云原生消息引擎、实时服务分析引擎、云原生日志搜索和统一存储 HDFS 等核心组件,支持存算分离和自动调优;
- 资源调度层支持统一计算资源调度和统一引擎云原生生命周期管理。
一大支撑体系是运维管理平台,是集开源组件、服务生命周期、集群、容灾、可观测性于一体的一站式管理平台。
平台服务层
平台服务层由开源组件插件化集成,灵活配置选用,这是整个平台架构的一个关键设计。
为了尊重现有用户使用习惯,将用户习惯使用的开源组件以插件化的形式进行了集成。现有主流的大数据工作场景主要包括信息门户、数据工程和数据科学三种,每个场景下都有许多用户常用的开源组件:
- 信息门户: 一般是 BI 报表类,如 Superset、Apache Ranger 等;
- 数据工程: 一般是大数据开发工程师、数仓工程师,做数据开发、数据 ETL、数据处理、清洗所用到的组件,如使用 Zeppelin Notebook 做数据开发,对接数据治理平台、调度平台;
- 数据科学: 一般适用于 AI 场景,如 Jupyter、Ray等;
上述三个场景是大数据工作中非常常见的场景,云原生大数据平台通过插件化的方式集成这些开源组件,即开即用,具备极大的便捷性和灵活性。
核心引擎层
核心引擎层具备了存算分离的特点。
在计算方面,集成主流大数据计算引擎包括 Flink、Spark,同时集成了云原生消息中间件、实时服务分析引擎和云原生日志搜索服务;
在存储方面,采取统一存储,兼容 HDFS 语义,支持 TOS 透明加速、缓存加速和数据湖管理。
自动调优
大数据向云原生发展需要推动计算引擎与云原生深度融合,向着自动调优方向演进。从我们的经验来看,这个过程可分为四个阶段:
-
第一阶段
- 部署和管理 K8s 集群
- 应用自己管理容器和镜像
-
第二阶段
- 资源池化:对底层 K8s 资源无感知
- 资源混部:在离线作业共享集群资源
- 只关注作业资源的额度和并行度
- 平滑演进:YARN 作业和 K8s 作业混部
-
第三阶段
- 虚拟队列 : 支持跨集群和机房作业自动调度
- 利用闲置资源: 利用超发和驱逐机制利用空闲资源
- 引擎半自动调优: 利用智能团队推荐任务配置参数,人工确认下发
-
第四阶段(也是当前的终极目标)
-
全局自动容灾: 实现跨机房自动调度和容灾
-
资源自动优化:没有负载的时候资源使用可以减低到0;毫秒级的冷启动延时
-
引擎自动调优: 混合不使用 AI 技术优化使用资源,包括计算网络和内存
-
存算分离
云原生化具体工作主要包括了三个部分:
统一管理和调度:
- 统一数据权限,降低安全风险:资源池包括数据,要有统一的权限和安全管理,降低安全风险;
- 统一资源调度和复用:资源池也需要统一的资源调度和复用,比如当进行了统一存储后,在不同业务进行复用时,我们可以进行统一的调度。
存储能力共用:
- 统一数据 Copy,减少数据卸载:数据任务经常出错,同步也会耗费资源,当任务同步出错时,定位很难,也非常耗费人力,所以要尽量减少数据卸载;
- 统一数据容灾,保证高可靠要求:支持多种存算分离的部署形态,既可以完全分为计算、存储两个集群,也可以将计算和存储混部在一个 K8s 集群上,但此时计算存储是单独管理的。
存算分离负载:
-
降低扩缩容和数据 Rebalance 时间:云原生数据湖、数据仓、消息队列、搜索引擎如果支持存算分离的部署模式,将存储放在统一的大数据文件存储或对象存储上,这样可以降低扩缩容和数据 Rebalance 时间;
-
增强对请求响应能力:将存储放在统一的大数据文件存储或对象存储上,也可以增强对请求的响应能力。
资源调度层
资源调度层主要起到统一计算资源调度,统一引擎云原生生命周期管理的作用,包含以下四个模块:
-
多云部署和调度:提供跨云的额度管理(统一的 Quota),可以实现高可用;
-
统一资源池:支持计算统一负载,支持在离线混部;
-
云原生 YARN :兼容 YARN 资源负载,平滑迁移现有的 Hadoop 的负载;
-
云原生 Operator:用 Helm Chart 管理整个引擎的云原生生命周期。
传统的资源调度系统向云原生演进,有两种并行的方式,可供二选一:
- Serverless YARN:从上图可以看到,Resource Manager、Node Manager、Application Master 是 YARN 的三大组件。本方案是在 Resource Manager 中进行修改,增加了新的组件。经过这样改造之后,对于客户来说,新系统仍保持了通过 YARN Client 提交作业的使用方式,只是在 Resource Manager 这一层做了封装调度,让用户把作业直接提交到 API Server,而这个 API Server 其实是 K8s 的 API Server。也就是说,通过对 YARN 的 Resource Manager 进行改造,可以让原来使用 YARN 来提交资源请求的业务,平滑地把业务提交到 K8s 上 。
- 云原生 Operator:这种方案是针对现有大数据组件的云原生化部署,把 Flink、 Spark 等计算引擎以 Cloud Native (云原生)的方式部署到 K8s 上。这种方案的好处有两个,第一是可以通过 Operator 对计算引擎进行全生命周期的管理,帮助用户进行更优的批量作业重启策略;第二是云原生和 K8s 融合得更好,它可以更精细地采集 Pod 上的日志,跟踪整个大数据的引擎和作业的运行状态。
统一资源池(左图);支持跨集群、跨机房、跨地域的全局资源湖(右图)
在调度层面,实现云原生化需要做的两件事情:
统一资源池
对于虚拟的资源池的概念,我们认为它需要一些基本的要求,包括:
- 队列属性:设置资源池 Min-Max 属性
- 更强的调度策略:任务优先级调度、GANG 调度和 DRF 调度(GANG 调度策略保证一个作业的所有容器一起被调度,DRF 算法保证公平地将资源分配给资源池内的各个作业)
- 更好的隔离控制:限制每个 Pod 的 CPU 时间片和内存使用量
- 更灵活的资源使用方式:空闲资源利用和队列抢占
全局资源湖
- ResLake 具有资源的全局视图、全局资源池和 Quota 管控
- 不限机房、不限集群,以最优化资源利用率为最终的调度目标
例如,当前在集群 A 有一个资源池,在集群 B 有一个资源池,为了容灾的需求,我们可能把这两个资源池作为一个主备的资源池,抽象出来一个虚拟队列的概念。这样在任务提交时,用户就可以不关注资源池,只提交到虚拟队列上即可,至于分配到 A 集群/机房还是分配到 B 集群/机房,会自动根据下面集群/机房的运行状态来判断。
运维管理平台
集开源组件、服务生命周期、集群、容灾、可观测性于一体的一站式管理平台。
大数据平台应当具备可观测性、开源组件管理、服务生命周期管理、集群管理、 容灾 管理的功能和服务,图中标蓝部分是云原生计算进行了特别增强的部分,下面来重点阐述一下:
-
全链路监测:可以全链路地监测每个服务的运行状态,包括调用链、调用关系等,从而可以在故障时定位到具体出问题的调用环节;
-
开源组件管理:通过 Helm Chart 来对组件进行部署,通过 Operator 对运行组件进行整个生命周期的管理,包括开始、终止、清理等一系列操作。因此,开源组件管理是从 K8s 平台上对引擎或特定的开源组件,甚至是任务进行管理的特殊模式,这个模式的优势是更快捷和更细粒度。
-
服务生命周期管理:通过统一可视化的管理界面,提供服务组件的渲染、发布和状态管理服务。
-
集群管理:除集群扩缩容、集群信息统计外,为了更好地监控整个的作业运行状态和服务运行状态,往往需要更细粒度地采集容器日志,所以我们对这部分进行了增强。另外,为了定位容器之间的运行状态,我们提供通过 Web Shell 登录到 Pod 中,以命令行的形式输入 Linux 指令,在浏览器上直接操作作业运行环境的服务,类似于在本地终端操作远程服务器,这对作业开发以及问题定位来说是一个非常实用的工具。
混合部署提升资源利用率
在混部的用户场景下,云原生大数据平台支持很多的业务场景,包括在线、流式、离线、查询分析和批处理等。
由于不同业务场景对于底层资源响应的核心指标不同,对底层资源的优化需求也会存在区别。如果要满足这些不同场景的业务指标要求,在混部的时候就要有重点地进行对应的优化。以下是混部的两个典型场景:
-
Flink 和 Spark 的混部。 即 Flink 不使用资源,或负载低的时候,资源可以出让给 Spark,Spark 执行完批式计算后,空闲的资源也可以出让给流式计算(Flink)用。
-
APP 实时调用和大数据场景的混部。在上图提到的5个场景中,右侧4个都是大数据场景。大数据场景可以和 APP 实时调用场景进行资源复用——当 APP 在线资源使用量较少时,可以出让给大数据场景使用,反之亦然。
以字节跳动为例,我们在通过这样多种计算资源混合部署调度之后,获得了不俗的收益。
-
首先是高效的资源切换,可以做到数万核离线资源分钟级出让。如在2022年春节时,抖音在线资源需求量非常高,我们将离线资源以分钟级出让了数十万核给在线资源使用。而当遇到某些突发社会热点导致的极端弹性场景时,高效的资源切换甚至可以成为业务的“保命利器” 。
-
其次是利用率的提升,通过混部,可以降低整体公用的开销,在字节跳动内部带来 2% 的利用率提升;
-
最后是在离线资源的统一管理,在离线资源全量共池,可以实现 Quota 管控、调度、运行、机器运维统一。
多云部署实现多云成本最优复用
在多云的用户场景下,我们可以提供多云部署和调度,实现多云成本最优复用和跨云队列容灾:
- 提供全局虚拟队列:在用户使用多云的场景下,首先需要提供一个全局虚拟队列的概念。如上图,一个虚拟队列就是一个资源池,下面对应不同的两个物理资源池。用户在提交的时候,不需要关注实际对应的集群,而是提交到一个虚拟队列上,下层会针对作业进行相应的调度,自动分发到合适的集群/机房/队列上,能够有效提升容灾能力。
- 应用按多因子综合选择流量分配:多云部署的另一个好处是可以通过多种因素的综合考虑来选择流量分配。比如在一个多云场景下,AZ1 理解为厂商1,AZ2 是厂商2,现在发现使用同样多的 CU,在厂商2上比在厂商1上贵50%,那就可以通过多云调度把流量尽量分发到厂商1上。这是从成本角度考虑的一种情况,当然还可能存在虽然成本降低,但经常宕机,响应时间较长,任务状态出错率高的情况,那就需要把重要的应用放到各方面指标较好的机房里,总的来说就是通过多种因子的综合考量进行流量分配。在多云部署场景下,帮助用户实现多云成本的最优复用。
报名云原生大数据技术交流,欢迎填写问卷:https://wenjuan.feishu.cn/m/cfm?t=slWBqP5K6OGi-6g6h