Spark on k8s 在阿里云 EMR 的优化实践

简介: 本文整理自阿里云技术专家范佚伦在7月17日阿里云数据湖技术专场交流会的分享。

导读:随着大数据技术的发展,Spark 成为当今大数据领域最受关注的计算引擎之一。在传统的生产环境中,Spark on YARN 成为主流的任务执行方式,而随着容器化概念以及存算分离思想的普及,尤其是 Spark3.1 版本下该模式的正式可用(GA),Spark on K8s 已成燎原之势。

今天的介绍会围绕下面两点展开:

  • Spark on K8s 的基础概念和特性
  • Spark on K8s 在阿里云 EMR 的优化和最佳实践


点击查看直播回放

Spark on K8s 的基础概念和特性

首先和大家分享下 Spark on K8s 的一些背景。

1. Spark 的集群部署模式


image.png


Spark 现如今支持 4 种部署模式:

  • Standalone:使用 Spark 的内置调度器,一般用于测试环境,因为没有充分利用到大数据的调度框架,无法充分利用集群资源。
  • Hadoop YARN:最常见的一种方式,源自 Hadoop,拥有良好的社区生态。
  • Apache Mesos:与 YARN 类似,也是一个资源管理框架,现在已经逐渐退出历史舞台。
  • Kubernetes:即 Spark on K8s,Spark3.1.1 对这种部署模式正式提供可用支持,越来越多的用户也在积极做这方面的尝试。

使用 Spark on K8s 的优势如下:

  • 提高资源利用率:无需按照使用场景部署多个集群,所有 Spark 作业共享集群资源,能提高总体集群利用率,而且在云上使用时可以弹性容器实例,真正做到按量付费。
  • 统一运维方式:可以利用 K8s 的社区生态和工具,统一维护集群,减少集群切换带来的运维成本。
  • 容器化:通过容器镜像管理,提高 Spark 任务的可移植性,避免不同版本 Spark 带来版本冲突问题,支持多版本的 A/B Test。

尤其需要关注的一点是,根据我们的测试,在相同的集群资源条件下,Spark on K8s 和 Spark on YARN 的性能差距几乎可以忽略不计。再加上充分利用 Spark on K8s 的弹性资源,可以更好地加速 Spark 作业。

总结来看,Spark on K8s 相较于 Spark on YARN 的模式来说,其实是利大于弊的。

2. Spark on K8s 的部署架构

当前环境下,想要把 Spark 作业提交到 K8s 上,有两种方式:

  • 使用原生的 spark-submit


image.png


在这种方式下,K8s 集群无需提前安装组件。像现在使用的 YARN 的提交方式一样,提交作业的 Client 端需要安装 Spark 的环境,并且配置 kubectl,就是连接 K8s 集群的一个工具,然后在提交命令中标注 K8s 集群地址以及使用的 Spark 镜像地址即可。


image.png


上图详细的展示了使用原生的 spark-submit 提交任务到 K8s 的任务运行流程。用户在 Client 端执行 spark-submit 命令后会在本地启动一个进程,该进程会连接 K8s 的 api server 请求创建一个 Driver Pod。Driver Pod 在启动进程中会启动 Spark Context,并负责申请 Executor Pod。任务执行完毕后,Driver Pod 会负责清理 Executor Pod。但 Driver Pod 结束后会保留,用于日志或状态的查看,需要手动清理。

优点:


这种提交方式符合用户的使用习惯,减少用户学习成本,与现有的大数据平台集成性更好。因为是 Client 模式提交,支持本地依赖,支持 Spark-shell 的交互式作业模式。


  • 使用 Spark-on-K8s-operator


image.png


Spark-on-K8s-operator 是 Google 开源的一个组件,需要提前在 K8s 集群中部署一个常驻 pod,以提供相关服务。与第一种方式不同的是,使用这种方式不再是以命令行的方式提交,而是使用 kubectl 提交一种 yaml 文件来提交作业。本质上来说,这种工具具体实现还是使用的 spark-submit 的方式,只是相当于命令行中的信息换了一种格式以文件的形式提交。但是 Spark-on-K8s-operator 在第一种方式的基础上,做了一些辅助工具,包括定时调度、监控、作业管理等。


image.png


从流程上来说,用户提交了一个 yaml 文件,在 K8s 集群上常驻的 Spark-on-K8s-operator 就监听到了这个事件,通过解析文件转化成执行 spark-submit 命令启动一个 Spark 任务。

除了提交方式的不同,我们刚刚也提到这个工具提供了一些辅助的功能。Spark-on-K8s-operator 通过 K8s 的 Mutating Admission Webhook 机制,拦截了 K8s 的 Api 请求,在启动 Driver 和 Executor Pod 资源时,可以对其进行一些自定义配置处理。另一方面,工具可以监听 Driver 和 Executor Pod 的事件,从而跟踪和管理任务的执行进度。

优点:


工具的存在支持作业的管理,包括记录、重试、定时执行等。提供作业监控指标,也可以对接 Prometheus 方便统一监控。支持自动清理作业资源,也可以自动配置 Spark UI 的 service/ingress。

3. Spark on K8s 的社区进展


image.png  


Spark2.3 之前,有人尝试过通过在 K8s 上部署 YARN 的方式来支持 Spark on K8s,但是本质上 Spark 还是跑在 YARN 的资源管控下,所以并不能称之为完整意义上的 Spark on K8s。

Spark2.3,社区首次发布支持了原生的 Spark on K8s,全是第一次官方支持这样的部署方式。

Spark2.4 做了少量的特性优化,真正完善了这个功能是在 Spark3 版本,尤其是 Spark3.1 正式可用(GA)。当前 Spark on K8s 方向热度很高,所以如果感兴趣的同学建议直接升级到 Spark3.1 来尝试这个部署方式。

4. Spark on K8s 的重点特性

  • 优化 Spark Pod 配置属性


image.png


K8s 的 Pod 定义通常采用 Yaml 的描述处理,早期的 Driver 和 Executor Pod 定义只能通过 Spark Conf 进行配置,灵活性很差,毕竟不是所有的配置都能通过 Spark Conf 处理。Spark3.0 开始,支持使用模板文件。用户可以建立模板文件,定义 Pod 的属性,然后通过 spark 的配置传入,相较于单条配置更加便利,灵活性增强了很多。

  • 动态资源分配(Dynamic Allocation)


image.png


Spark2 版本时,动态资源分配只能使用 External Shuffle Service(ESS)的方式,这种方式下,executor 在执行时产生的 shuffle 数据全部交由 ESS 服务接管,executor 执行完毕随时回收。但是这种方式一般由 YARN 的 Node Manager 启动管理,很难在 K8s 上部署。

Spark3 版本中支持了 Shuffle Tracking 的特性,就是可以在没有 ESS 的情况下,利用自身对 executor 的管理,做到动态资源配置的效果。但是这种方式的缺点就是,在 shuffle read 阶段 executor 不能动态回收,仍需要保留以供 reducer 读取 shuffle 数据,然后需要等到 driver 端 gc 之后才会标记这个 executor 可以释放,资源释放效率低。

  • 节点优雅下线(node decommissioning)


image.png


在 K8s 的环境中,节点的缩容,抢占式实例回收这些场景还是比较常见的,尤其是在一些场景下,将部分 Spark 的任务优先级调低以满足其他高优先级的任务的使用。这种场景下,executor 直接退出可能会存在 stage 重算等情况,延长了 Spark 的执行时间。Spark3.1 提供了“优雅下线”特性,支持 Executor Pod 在“被迫”下线前,可以通知 Driver 不再分配新的 Task,并将缓存的数据或者 shuffle 的文件迁移到其他的 Executor Pod 中,从而保证对应 Spark 任务的效率,避免重算。

当前这个功能还属于实验性质,也就是默认不开启。

  • PersistentVolumeClaim 复用


image.png


PersisentVolumnClaim(简称 pvc),是 K8s 的存储声明,每个 Pod 都可以显式地申请挂载。Spark3.1 支持动态创建 pvc,意味着不需要提前声明申请,可以随着执行动态的申请挂载资源。但是这个时候 pvc 的生命周期伴随着 Executor,如果出现上述的抢占式被迫关闭的情况,同样会出现保存在 pvc 上面的数据丢失重算的问题。所以在 Spark3.2 中,支持了 pvc 重新利用,它的生命周期伴随 Driver,避免了重新申请和计算,保障整体的效率。

Spark on K8s 在阿里云 EMR 的优化和最佳实践

接下来和大家分享下阿里云 EMR 对于 Spark on K8s 的优化和最佳实践。

1. Spark on ACK 简介


image.png


ACK:阿里云容器服务 Kubernetes 版,简称 ACK。

EMR:阿里云开源大数据平台 E-MapReduce,简称 EMR。

在阿里云公共云上,我们有一款 EMR on ACK 的产品,其中包含了 Spark 类型的集群,后面简称 Spark on ACK。Spark on ACK 这个产品是一套半托管的大数据平台,用户首先需要有一个自己的 ACK 集群,也就是 k8s 集群,然后我们会在这个集群内创建一个用于 Spark 作业的 namespace,并安装一些固定组件 pod 比如 spark-operator、historyserver 之类,后续的 Spark 作业 pod 也会在这个 namespace 下运行,这些 Spark 作业 pod 可以利用用户自己的 ACK 节点机器来跑,也可以利用我们的弹性实例 ECI 来跑,来实现按量付费。这个所谓弹性实例 ECI 是什么,接下来我们具体介绍一下。

2. 云上弹性优势

image.png


Spark 在云上最大的优势就是更好的弹性,在阿里云的 ACK 的环境中,提供了一个弹性容器实例 ECI 的产品,有了 ECI 意味着,我们申请 pod 时不再是占用自己的机器节点的资源了,而是完全利用云上资源来创建 pod,而且可以做到快速拉起,秒级付费。利用 ECI 来跑 spark 作业我认为是非常划算的,因为通常大家用 spark 作业跑批处理任务,凌晨高峰,白天可能只有少量查询,这种峰谷明显的特点搭配快速弹性和按量付费是很适合的,外加 ECI 可以使用 spot 抢占式实例,有 1 个小时的保护期,并结合 Spark 的 Node decommissioning 特性,可以节省很多成本。

3. RSS 优化 Shuffle 和动态资源

image.png


Spark Shuffle 对本地存储依赖较大,但是云上环境下,存储分离的机器很难保障自带本地磁盘,使用云盘大小也无法预估,性价比不高。另一方面,Spark 原生的无 ESS 的动态资源配置,executor 的释放资源效率较低,可能因为无法回收造成资源浪费。


Spark Shuffle 本身也有很多缺点。Mapper 的输出量增大,导致 spill 到本地磁盘,引发额外的 IO;Reducer 并发拉取 Mapper 端的数据,导致大量随机读的产生,降低效率;在 shuffle 过程中,产生 numMapper * numReducer 个网络连接,消耗过多 CPU 资源,带来性能和稳定性问题;Shuffle 数据单副本导致数据丢失时,需要重新计算,浪费资源。


阿里云提供了独立部署的 RSS,目前已经在 github 上开源,可以直接对接 ACK,用户无需关注 Shuffle 数据是否有本地磁盘支持。原先的 spark shuffle 数据保存在 executor 本地磁盘,使用 RSS 后,shuffle 的数据就交给 RSS 来管理了。其实采用 push based 的外部 shuffle service 业界已经是一种共识了,很多公司都在做这方面的优化。优点有很多,Executor 执行完毕即可回收,节约资源;RSS 还将传统的大量随机读优化成了追加写,顺序读,进一步弥补了 Spark Shuffle 的效率问题;RSS 服务支持 HA 部署,多副本模式,降低重复计算的可能性,进一步保障 Spark 任务的效率。

4. 增强 K8s 作业级别调度


image.png


K8s 默认的调度器调度粒度是 Pod,但是传统的 Spark 任务调度默认粒度是 application。一个 Application 的启动,会伴随启动多个 Pod 执行支持。所以,突然提交大量 Spark 任务时,可能出现大量 Driver Pod 启动,单都在等待 Executor Pod 启动,从而导致整个集群死锁。另一方面,K8s 的多租户场景支持不佳,也不支持租户之间的弹性调度,以及动态配额等。相比于 YARN 的调度策略,K8s 的调度策略单一,为默认优先级+FIFO 的方式,无法做到公平调度。


阿里云 ACK 在这个方面做了增强:

  • 调度时优先判断资源是否满足,解决上述可能出现的死锁问题。
  • 基于 NameSpace 实现多租户树状队列,队列可以设置资源上下限,支持队列间抢占资源。
  • 实现了以 App 粒度调度 Spark 作业的优先级队列,支持队列间的公平。调度,并基于 Spark-on-K8s-operator 的扩展,提交作业会自动进入队列。

5. 云上数据湖存储与加速


image.png


  • 在 K8s 环境下,相比于传统的 Hadoop 集群,使用数据湖存储 OSS 更贴合存算分离的架构。Spark on ACK 内置 Jindo SDK,无缝对接 OSS。
  • Fluid 可支撑 Spark on K8s 部署模式下的缓存加速,在 TPC-DS 场景下,可以提升运行速度 30%左右。

6. 使用 DLF 构建云上数据湖


image.png


在 K8s 上想要使用 Hadoop 生态圈的组件,还需要额外部署。但是 Spark on ACK 无缝对接阿里云 DLF(Data Lake Formation),DLF 提供了统一的元数据服务,支持权限控制和审计,另外提供数据入湖的功能,支持 Spark SQL 的交互式分析,以及数据湖管理功能,支持进行存储分析和成本优化。

7. 易用性提升


image.png


Spark on ACK 提供了一个 CLI 工具,可以直接以 spark-submit 语法来提交 spark 作业,同时也会记录到 spark-operator 里面来管理。之前我们提到了 2 种提交作业方式的优劣,spark-operator 具备比较好的作业管理能力,但是提交作业不兼容老的命令语法,也无法跑交互式 shell,从老集群迁移的用户改动比较麻烦,因此利用我们这种工具,可以同时享受 2 种提交方式的优点,对用户的易用性来说是个比较大的提升。


image.png


在日志收集这一点,Spark on ACK 提供日志收集方案,并通过 HistoryServer 让用户可以像 Spark on YARN 一样在界面上查看。


更多信息:

产品官网

[1] 数据湖构建 Data Lake Formation:https://www.aliyun.com/product/bigdata/dlf

[2] 开源大数据平台 EMR: https://www.aliyun.com/product/emapreduce

[3] 大数据知识图谱: https://developer.aliyun.com/learning/topic/bigdata


数据湖系列

[1] 数据湖揭秘—Delta Lake: https://developer.aliyun.com/article/909818

[2] 数据湖构建—如何构建湖上统一的数据权限:  https://developer.aliyun.com/article/918403

[3] 关于 Data Lake 的概念、架构与应用场景介绍:https://developer.aliyun.com/article/944650

[4] 数据湖架构及概念简介:

https://developer.aliyun.com/article/1004847

[5] 数据湖统一元数据和权限

https://developer.aliyun.com/article/1008235



更多 数据湖 相关技术问题,可扫码加入钉钉交流群

第一时间获取最新技术文章和社区动态,请关注公众号~

image.png

相关实践学习
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。     相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
相关文章
|
11月前
|
分布式计算 运维 搜索推荐
立马耀:通过阿里云 Serverless Spark 和 Milvus 构建高效向量检索系统,驱动个性化推荐业务
蝉妈妈旗下蝉选通过迁移到阿里云 Serverless Spark 及 Milvus,解决传统架构性能瓶颈与运维复杂性问题。新方案实现离线任务耗时减少40%、失败率降80%,Milvus 向量检索成本降低75%,支持更大规模数据处理,查询响应提速。
555 57
|
6月前
|
存储 Kubernetes 网络安全
关于阿里云 Kubernetes 容器服务(ACK)添加镜像仓库的快速说明
本文介绍了在中国大陆地区因网络限制无法正常拉取 Docker 镜像的解决方案。作者所在的阿里云 Kubernetes 集群使用的是较旧版本的 containerd(1.2x),且无法直接通过 SSH 修改节点配置,因此采用了一种无需更改 Kubernetes 配置文件的方法。通过为 `docker.io` 添加 containerd 的镜像源,并使用脚本自动修改 containerd 配置文件中的路径错误(将错误的 `cert.d` 改为 `certs.d`),最终实现了通过多个镜像站点拉取镜像。作者还提供了一个可重复运行的脚本,用于动态配置镜像源。虽然该方案能缓解镜像拉取问题,
655 2
|
9月前
|
人工智能 分布式计算 DataWorks
一体系数据平台的进化:基于阿里云 EMR Serverless Spark 的持续演进
本文介绍了一体系汽配供应链平台如何借助阿里云EMR Serverless Spark实现从传统Hadoop平台向云原生架构的迁移。通过融合高质量零部件供应与创新互联网科技,一体系利用EMR Serverless Spark和DataWorks构建高效数据分析体系,解决大规模数据处理瓶颈。方案涵盖实时数据集成、Lakehouse搭建、数仓分层设计及BI/ML应用支持,显著提升数据处理性能与业务响应速度,降低运维成本,为数字化转型奠定基础。最终实现研发效率提升、运维压力减轻,并推动AI技术深度整合,迈向智能化云原生数据平台。
293 4
|
9月前
|
分布式计算 运维 监控
Fusion 引擎赋能:流利说如何用阿里云 Serverless Spark 实现数仓计算加速
本文介绍了流利说与阿里云合作,利用EMR Serverless Spark优化数据处理的全过程。流利说是科技驱动的教育公司,通过AI技术提升用户英语水平。原有架构存在资源管理、成本和性能等痛点,采用EMR Serverless Spark后,实现弹性资源管理、按需计费及性能优化。方案涵盖数据采集、存储、计算到查询的完整能力,支持多种接入方式与高效调度。迁移后任务耗时减少40%,失败率降低80%,成本下降30%。未来将深化合作,探索更多行业解决方案。
612 1
|
11月前
|
存储 负载均衡 测试技术
ACK Gateway with Inference Extension:优化多机分布式大模型推理服务实践
本文介绍了如何利用阿里云容器服务ACK推出的ACK Gateway with Inference Extension组件,在Kubernetes环境中为多机分布式部署的LLM推理服务提供智能路由和负载均衡能力。文章以部署和优化QwQ-32B模型为例,详细展示了从环境准备到性能测试的完整实践过程。
|
12月前
|
人工智能 分布式计算 调度
打破资源边界、告别资源浪费:ACK One 多集群Spark和AI作业调度
ACK One多集群Spark作业调度,可以帮助您在不影响集群中正在运行的在线业务的前提下,打破资源边界,根据各集群实际剩余资源来进行调度,最大化您多集群中闲置资源的利用率。
|
Cloud Native Serverless 数据中心
阿里云ACK One:注册集群支持ACS算力——云原生时代的计算新引擎
阿里云ACK One:注册集群支持ACS算力——云原生时代的计算新引擎
395 10
|
边缘计算 调度 对象存储
部署DeepSeek但IDC GPU不足,阿里云ACK Edge虚拟节点来帮忙
介绍如何使用ACK Edge与虚拟节点满足DeepSeek部署的弹性需求。
|
Kubernetes 监控 Serverless
基于阿里云Serverless Kubernetes(ASK)的无服务器架构设计与实践
无服务器架构(Serverless Architecture)在云原生技术中备受关注,开发者只需专注于业务逻辑,无需管理服务器。阿里云Serverless Kubernetes(ASK)是基于Kubernetes的托管服务,提供极致弹性和按需付费能力。本文深入探讨如何使用ASK设计和实现无服务器架构,涵盖事件驱动、自动扩展、无状态设计、监控与日志及成本优化等方面,并通过图片处理服务案例展示具体实践,帮助构建高效可靠的无服务器应用。

推荐镜像

更多