爱奇艺大数据异构计算实践
01#
背景
01#
背景
在机器选型阶段,我们综合评估了私有云、公有云的优缺点,以及考虑到爱奇艺大数据计算下一步的演进方向,决定使用公有云上的新机型:
私有云物理机须用满多年才能报废,而云上机器租赁时间灵活,可以贴合业务周期性的资源需求。
公有云引入新型硬件较快,可随时租、随时退,有助于我们加快机型迭代,不断提升单机性价比。
公有云提供丰富的计算机型,可选择适合大数据计算场景需求的机器配置,尤其是 CPU 核数和内存配比,我们从原先的 1 核 : 4~5 GB 提高到 1 核 : 8 GB,通过超分部署(即大数据计算层面 2 vcores = 操作系统层面 1 core)来拉高 CPU 利用率,进而提升单机性价比。
我们评估了多家公有云的数十款机型,包括 Intel Xeon、AMD Genoa、ARM 等不同 CPU 型号,本地盘、云盘等不同配置,虚拟机、裸金属等不同规格,最终选择了 AMD、ARM 两款裸金属机型。
由于 AMD 和 Intel 都采用 x86 架构,不需要特别的适配,而 ARM 的 CPU 架构和指令集与 x86 不同,需要适配改造,并支持异构计算调度,因此本文重点阐述我们引入 ARM 的过程与实践情况。
ARM 的上线经历了机器选型、大数据组件适配及业务代码兼容改造、大数据异构计算调度等几个环节,以下将分别展开介绍。
02#
公有云机器选型
02#
公有云机器选型
基础性能测试:使用计算密集型整数、浮点数运算,来评估 CPU 性能;通过 dd、fio 并行写入测试,来测试 IO 并发带宽; 典型 SQL 测试:选择 10 TB 规格 TPC-DS 的部分 SQL 耗时来评估性能,通过异构计算调度将测试任务定向调度到测试机器上。
给不同机型打上不同的标签,例如节点 A 的标签:vendor=xxx_cloud,cpuarch=aarch64 (ARM CPU 架构,有别于 x86_64) 等 采集线上单日 Spark SQL 的全部任务,按照计算节点维度聚合统计每核每秒的平均处理数据量 ( total input bytes / total (vcore * seconds) )
根据计算节点维度聚合的数据,以及节点上的标签进行再次实时聚合,绘制不同的维度的机型性能数据。如下:
图 1 不同机型的性能观测
同时基于单个计算节点维度的性能统计,我们可以快速发现同批次机型下的快慢节点,进行异常分析
将公有云测试机型超分部署后加入到线上生产集群(位于私有云)中,运行一周,观察负载情况 公有云测试机器与私有云生产集群中的其他节点之间的通信通过混合云专线网络,延时较低,对测试结果的影响可忽略不计(延时对性能测试结果的影响程度,最终会体现在机器性价比上,在我们的环境中,这部分占比微乎其微) 通过可观测性系统,计算得出测试机型对比基准机型的性能指数,即从性能方面考虑,一台测试机型可以兑换几台基准机型
03#
ARM 的兼容适配
03#
ARM 的兼容适配
3.1 大数据组件适配
Hadoop 3.2.2:在 ARM 节点上编译 RPM,确保 HDFS native 库的兼容性,并且将 leveldbjni 等依赖升级到支持 ARM 的内部版本 Flink Connector:存在大量适配需求,共计改造适配 20+ connectors Spark 3.5.0、Iceberg、Paimon 等组件适配良好,不需要太多改造
3.2 业务代码兼容性检测和改造
04#
异构计算调度
04#
异构计算调度
由于业务 Jar 任务的改造需要较长的周期,在上线初期,我们需要将已完成改造的任务(包括 SQL 任务)允许调度到 ARM 节点上,而未完成改造的任务只能运行在 x86 节点上。
图 3 统一调度将导致未适配任务失败
我们引入 YARN 节点属性 (YARN Node Attribute)调度功能,对不同节点加上不同的属性标签,并利用计算任务调度放置约束的设定 (YARN Placement Constraint),来实现指哪打哪的定向调度功能。
图 4 基于节点属性的异构计算调度
4.1 基于 YARN 节点属性调度
计算节点属性设置
为了给异构调度提供基础,我们对不同机型的计算机器设置了如下的属性标签:
计算资源生命周期:lifecycle=[reserved/on-demand],区分是固定节点,还是临时节点(如离在线混部弹性资源) CPU架构:cpuarch=[x86_64/aarch64],其中 aarch64 即为 ARM CPU型号:cpumodel=[Intel-xxx/AMD-xxx/...],主要用于性能观测 CPU性能:cpuperf=[high/medium/low],根据单核计算性能划分为高、中、低三档 磁盘类型:disktype=[ssd/hdd]
计算框架适配
YARN Node Attribute 特性需要结合计算任务设定 task 放置约束 (YARN Placement Constraint) 来实现,但是各个计算引擎均未支持此功能,因此我们对 Flink、Spark、MapReduce 等计算引擎进行了改造适配(尚未贡献给开源社区)。
计算引擎 | 改造 | Placement Constraint 参数配置 |
|---|---|---|
Spark | 通过扩展 YarnAllocator 来实现 YarnSchedulingRequestAllocator 支持对 placement constraint 的配置,并且允许用户可以通过配置化开启和关闭 | --conf "spark.yarn.schedulingRequestEnabled=true" --conf spark.yarn.executor.placement-constraint.spec="AND(lifecycle=reserved:staticresource=true)" |
Flink | 扩展实现 YarnResourceManagerDriver,并且为了兼容老版本的 Yarn Client, 实现了SchedulingRequestReflector | -Dyarn.taskmanager.placement-constraint.spec="AND(lifecycle=reserved:staticresource=true)" |
MapReduce | 鉴于 MapReduce 使用的 Yarn Client API 较为底层,我们在不破坏原有逻辑的本身,在 RMContainerRequestor 类中将资源申请的 resource request 替换为 scheduling request | -D mapreduce.placement- constraint.spec="lifecycle=reserved,staticresource=true" |
由于 YARN Node Attribute 的特性较新,社区的使用者较少,我们做了大量的生产试错和代码改造,也向 YARN、Spark、Paimon 等开源社区贡献了十几个通用性的改进和修复。
4.2 任务无感迁移策略
未适配 ARM 的 Jar 任务,统一在 YARN ResourceManager 侧通过黑名单避免调度到 ARM 计算节点上执行。对于这些任务,自动配置添加 constraint 为 nm.yarn.io/cpuarch=x86_64 对于已适配的任务,则默认放通,可使用全部的计算节点
同时,我们实现任务灰度的白名单机制,通过动态变更配置文件,对任务按照 Hadoop 用户来进行无感的灰度。
4.3 自定义均衡调度策略
在 ARM 计算节点上线后,我们发现因为 YARN CapacityScheduler 任务调度默认采用 Round-Robin 分配策略,依次轮询每个节点进行调度,导致 CPU 核数较少的大量低性能节点首先被用满,而 ARM 和 AMD 大容量机型 CPU 核数多、分配率低,未被充分利用。
如下图所示,Round-Robin 模式类似大水漫灌,处于 level 1、level 2 范围内的节点会依次先被打满。
图 5 Round-Robin 资源分配
因此,我们基于Yarn multi node placement 实现了自定义的均衡调度策略(默认的 ResourceUsageMultiNodeLookupPolicy 策略无法满足我们的调度需求):
在后台对单机 vcore 使用率按照从小到大进行排序,提升大容量节点的优先分配权
在低性能节点 vcore 使用率达到较高水位,在资源充足情况下,则降低调度权重,保证性能
在优化后,在资源利用高峰时,高性能节点将会优先被利用,而低性能节点则会处于较低的资源分配水位线上。
图 6 自定义均衡调度策略
05#
异构计算落地情况
05#
异构计算落地情况
06#
未来计划
06#
未来计划
固定计算(X%):保留 X% 在私有云机房内,逐步将部分旧机器替换成 AMD 等新机器; 实时弹性计算(Y%):Y% 计算资源通过 YARN + K8S 离在线混部体系以 K8S 容器方式提供,与在线业务共用私有云或公有云上的宿主机,根据大数据资源需求及在线业务空闲资源情况实时弹性调度,削峰填谷; 长周期弹性计算(Z%):Z% 私有云机器待过保后替换成公有云 AMD 或 ARM 机器,实现更长周期的按需弹性,比如应对寒暑假高峰,在业务需求减少后,可以当月就腾退掉,及时降本; X + Y + Z = 100%,将根据业务需求、公私有云成本、技术等因素动态调整。
也许你还想看
爱奇艺大数据离在线混部
Alluxio 在爱奇艺大数据的实践
大前端 | 大后端 | 播放