Kubernetes 已成为运行大规模 Apache Spark 工作负载的首选平台。但随着工作负载的扩展,如何确保您的 Spark 作业高效运行而不遇到瓶颈?管理数千个并发 Spark 作业可能会带来严峻的性能挑战——从 Spark Operator 中的 CPU 饱和Kubernetes API 变慢以及作业调度效率低下

为了应对这些挑战,我们很高兴推出 Kubeflow Spark Operator 基准测试结果和工具包——一个用于分析性能、找出瓶颈并优化您在 Kubernetes 上部署 Spark 的综合框架。

🔍 包括什么?

这项基准测试工作提供了三个关键成果,可帮助您完全掌控您在 Kubernetes 上的 Spark 部署

基准测试结果 – 对大规模 Spark 工作负载的性能洞察和调优建议的详细评估。
🛠 基准测试工具包 – 一套完全可复现的测试套件,可帮助用户评估其自身的 Spark Operator 性能并验证改进效果。
📊 开源 Grafana 面板 – 一个经过实战检验的可视化工具,专门用于跟踪大规模 Spark Operator 部署,提供作业处理效率、API 延迟和系统健康的实时监控。

❌ 挑战:为什么基准测试很重要

在 Kubernetes 上大规模运行数千个 Spark 作业会暴露一些性能障碍,如果得不到解决,这些障碍会严重影响效率

  • 🚦 Spark Operator 变为 CPU 瓶颈:处理数千个 Spark 作业时,控制器 pod 会耗尽 CPU 资源,限制了作业提交速率。
  • 🐢 高 API Server 延迟:随着工作负载扩展,Kubernetes API 响应变慢——作业状态更新减慢,影响可观测性和调度效率。
  • 🕒 Webhook 开销导致作业启动变慢:使用 webhooks 会为每个作业增加大约 60 秒的额外延迟,降低了高并发环境中的吞吐量。
  • 💥 命名空间过载导致失败:在单个命名空间中运行超过 6000 个 SparkApplication 会由于过多的环境变量和服务对象过载而导致 pod 失败

💡 那么,如何解决这些问题并优化您的 Spark Operator 部署?
这就是我们的基准测试结果和工具包发挥作用的地方。

🛠 Spark Operator 的调优最佳实践

根据我们的基准测试发现,我们提供了清晰、可操作的建议,以提高 Spark Operator 在大规模环境下的性能。

如果您正在运行数千个并发 Spark 作业,以下是您需要做的

部署多个 Spark Operator 实例

💡 为什么?单个 Spark Operator 实例难以应对高作业提交速率。
解决方案:当单个 Spark Operator 实例难以应对高作业提交速率,导致 CPU 饱和和作业启动变慢时,部署多个实例会有所帮助。通过为每个实例分配不同的命名空间来分发工作负载。例如,一个实例可以管理 20 个命名空间,而另一个实例处理另一组 20 个命名空间。这可以防止瓶颈并确保高效的 Spark 作业执行。

禁用 Webhooks 以加快作业启动

💡 为什么?Webhooks 由于验证和变异开销,会为每个作业引入 ~60 秒 的延迟,降低了大型工作负载的吞吐量。✅ 解决方案:与其使用 webhooks 进行卷挂载、节点选择器或污点设置,不如直接在 Spark 作业定义中定义 Spark Pod Templates——无需额外文件。通过在 Helm chart 中设置 webhook.enable=false 来禁用 webhooks。

增加 Controller Workers 数量

💡 为什么?默认情况下,操作符运行有 10 个 controller workers,但我们的基准测试表明,将此数量增加到 20 或 30 个 workers 可以提高作业吞吐量。
解决方案:如果您的 Operator pod 运行在 36 核或更高 CPU 上,请将 controller.workers=20,以实现更快的并行作业执行。对于更大的工作负载(例如 72 核以上),请增加到 40 个或更多 workers,以获得更好的并行作业执行。

启用批处理调度器 (Volcano / YuniKorn)

💡 为什么?Kubernetes 的默认调度器未针对批处理工作负载进行优化,导致作业放置效率低下
解决方案:启用 VolcanoYuniKorn (batchScheduler.enable=true) 来优化作业调度。这些调度器提供协同调度、队列管理和多租户资源共享。基准测试表明,Apache YuniKorn 调度作业比默认的 Kubernetes 调度器更快。

优化 API Server 扩展

💡 为什么?API server 在重载下延迟会飙升至 600 毫秒以上,影响 Spark 作业的响应能力。
解决方案:扩展 API server 副本,分配更多 CPU 和内存,并优化事件处理。确保您的 Kubernetes API server 和 etcd 自动扩展以高效处理突发工作负载。监控 kube-apiserver 指标并相应地扩展 etcd。如果运行数千个 Spark pods,请考虑手动增加控制平面节点大小

将 Spark 作业分布到多个命名空间

💡 为什么?在单个命名空间中运行过多作业会导致环境变量溢出,从而导致 pod 失败。
解决方案:当太多 pods 位于单个命名空间中时,列表或修改资源等操作会生成大型 API server 响应,增加延迟。例如,检索所有 pods 的响应可能会非常大,消耗大量服务器资源。此外,etcd 作为 Kubernetes 的键值存储,在处理来自同一命名空间中大量 pods 的频繁更新时可能成为瓶颈。繁重的读写操作会给 etcd 带来压力,导致延迟增加和潜在的超时。为了提高性能和稳定性,建议将工作负载分布到多个命名空间

使用开源 Grafana 面板进行监控和调优

💡 为什么?可观测性是识别性能瓶颈的关键。
解决方案:使用我们的 Spark Operator 规模测试面板 来实时跟踪作业提交速率、API 延迟和 CPU 利用率。

📖 了解更多并开始使用

Kubeflow Spark Operator 基准测试结果和工具包 提供了一份深入的在 Kubernetes 上大规模运行 Spark 的性能操作手册。无论您是在排除现有部署的故障,还是在规划未来的增长,这个工具包都能为您提供成功所需的数据驱动的洞察最佳实践

🚀 准备好优化您的 Spark 工作负载了吗?深入了解下面的完整结果和工具包
📖 Kubeflow Spark Operator 基准测试