引言:
在大数据处理中,Shuffle 机制是计算组件的核心,负责将数据导向正确的处理节点,其设计直接影响任务执行效率和资源利用率。从 MapReduce 到 Spark,Shuffle 机制的进化不仅体现了大数据技术的进步,也凸显了优化 Shuffle 以应对大规模集群挑战的重要性。
背景
奇富科技的大数据平台每日处理超过数十万个离线任务(90%以上基于 Spark)和上万个 adhoc 查询,Shuffle 数据量达 PB 级,峰值时间点超过 300 TB,全平台每天超过几亿文件落盘。早期使用的 Spark3 内置 Push Shuffle 模型难以应对如此大规模的数据,随机IO 对计算节点负载极高,导致任务耗时波动从分钟到小时不等,特别对核心业务 SLA 保障也无法达成,同时磁盘损坏率比正常硬件损害率大大提高。
目标
提高任务稳定性和集群资源使用率,保障数据 SLA 承诺。
生产无感且有质量保障地迁移,无需用户干预即可升级 SQL 和非标 Spark 程序。
选型方案
对于小规模集群,通过提升磁盘硬件能力等措施缓解 Spark 原生 Shuffle 架构带来的 IO 影响即可见效。然而,在奇富科技的大数据平台上,由于存在大量算力型和存储型机器,采用高性能硬件(如 SSD)将大幅增加成本。因此,必须从现有 Spark Shuffle 架构上寻求突破,以实现降本提效的目标。
1. 从 RSS 组件上考虑
基于External Shuffle Service (ESS)的架构,包括优化后的 Push Shuffle,在处理 Map 任务输出和 Reduce 任务拉取 Shuffle 数据时,并未带来本质上的改进。此外,为了防止数据丢失而进行的数据备份增加了服务器的 IO 负担,且该模式下的 merge data 阶段失败率很高,任务依旧还是拉取的原始数据。因此,这种模式未能有效解决 Shuffle 过程中的随机 IO 问题。如下图所示为 ESS 的输入读取流程简图:
行业内已经推出了新一代成熟的解决方案:Remote Shuffle Service (RSS)。该方案通过将 Shuffle 过程中的随机 IO 编排成单文件 IO,显著优化了数据处理效率和系统性能。RSS 不仅解决了传统 ESS 架构下Map任务输出与 Reduce 任务拉取 Shuffle 数据时存在的问题,还通过以下方式提升了整体作业的稳定性和效率。
基于 Remote Shuffle Service (RSS) 的架构已经有很多厂商开源了。经过调研以及与 Celeborn 社区同学交流、通过 Benchmark 测试,最终选择了 Celeborn。其中 Celeborn 优雅的退出升级机制、无感回滚、热点处理、负载均衡、自我保护机制等等也是关注的重点。以下是基于不同 RSS 实现组件做的压测:
2. 从硬件选型上考虑
在有限的成本内,磁盘的 IO 性能越高越好,经过压测对比,最终选择了配备高性能闪存的 NVMe 固态磁盘机型,单台机器 4*4t 磁盘,实际 IO 性能远超 SSD,和 SATA 盘对比,针对高并发顺序和随机读取都有同等 SATA 盘机型的数十倍性能。
3. 从部署架构上考虑
经过参数优化后,Celeborn 在暴力测试中的表现显著优于 Spark ESS 和其他 RSS 组件。具体来说,在使用25个 Worker 节点(每个节点配置 4G On-Heap 和16G Off-Heap 内存)同时提交50个 2TB Shuffle 数据的任务时:
Shuffle Fetch Time:任务的 Shuffle Fetch 时间最短,最大不超过3分钟。
Shuffle Write Time:任务的 Shuffle Write 时间小于1分钟。
总体而言,采用 Celeborn 的 Spark Job 在处理大规模 Shuffle 数据时展现了最佳性能和效率。
4. 从版本上考虑
采用了社区 master
分支自行打包的 Celeborn 版本,而非官方0.5版本,因为后者尚有一些重要 PR 未合并。这样确保了系统包含最新的改进和优化,支持大规模数据处理需求。
Celeborn 应用
1. 简单介绍
Celeborn 主要由三个重要角色构成:Master、Worker 和 Driver 中的 LifecycleManager。
Master:组成高可用(HA)集群,管理所有Worker节点的状态。
Worker:负责任务的 Shuffle 文件的读写操作。
LifecycleManager(位于 Driver 中):维护 Shuffle 过程中的元数据。
2. 平台集成
⭐ 系统集成方案(用户无感切换)
我们通过定制 DolphinScheduler(奇富大数据调度)和自研实时诊断功能,实现了智能任务调度:
任务降级:在 Celeborn 集群都出问题时,原⽣模式会退化成第⼀代 Shuffle,⽽我们内部使⽤了第⼆代,即 ESS 的 Push 模式(稳定性⽐第⼀代好)。有必要退化成更优的选择⽅案,甚⾄通过跨机房调度保证此时任务的稳定性
动态开启 Celeborn:仅对含 Shuffle 的任务启动 RSS,非 SQL 任务通过特殊参数无感启动 RSS。
超大 Shuffle 任务:路由到配备大量 SATA 盘的专用大集群,处理超大规模 Shuffle。
流量自动切换:低峰期自动将部分批处理流量切换到 B 集群,优化资源利用。
⭐ 质量方案(切换质量保障):
通过调度平台自研的任务升级功能,自动圈选任务,并做陪跑后校验任务数据一致性,并做自动升级(调度可切为 RSS 运行模式)。
⭐ 组件部署架构
我们内部总共部署三套 Celeborn 环境:
SLA 集群(硬件资源1倍 Buffer,路由所有高优任务)
普通集群(硬件资源有限,路由大部分普通任务)
超大混部集群(Shuffle 量 TB 级别)
备注:超大混部集群跟 ESS 一样,混部在有磁盘的集群节点上,有成千上万的 SATA 磁盘。
说明:初期普通集群任务量全部放到超大混部集群,大量小任务的 IO 退化成随机 IO,SATA 盘容易造成热点,后续只路由大任务,热点大大降低。
3. 日常运营和监控
Celeborn 组件已经成为奇富科技内部大数据不可或缺的一部分,生产做了高稳定性保障,服务器架构分布采用容器架物理机混合,从
1)基础指标,包括流量、内存、磁盘 IO 和使用率
2)服务的 Fetch、Push 指标、服务堆内外内存、文件数、流量波动等等做了详细监控上线至今两个季度,可用率100%。
项目收益
1. 目标达成情况
目前奇富科技已将所有含 Shuffle 的任务从 ESS 切换至 RSS,目标:
性能维度:切换 RSS 后,81%任务得到加速(19%大部分属于正常波动60s内),平均加速30%,总体计算成本降低超过20%
稳定性维度:任务耗时波动<1min占比90.33%,<5m占比98.81%,内部核心数据提前小时级别以上产出
2. 其他小概率的稳定性问题
ESS 任务经常出现 Shuffle Fetch 夯死,失败,切换至 RSS 后也不再触发。
org.apache.spark.shuffle.FetchFailedException
at org.apache.spark.errors.SparkCoreErrors$.fetchFailedError(SparkCoreErrors.scala:312)
at org.apache.spark.storage.ShuffleBlockFetcherIterator.throwFetchFailedException(Sh(10.xxx.xxx.67 : 01e86c20bd7f409290ea30b52f58758f)
Fetch Time 提升数量级,由之前的分钟级提升至秒级。
生产应用优化过程
以下调优基本都以存储为 NVMe 固态硬盘的机型为例
核心调优参数:
celeborn.worker.storage.dirs
/hdpShuffle01:capacity=3800G:disktype=SSD:flushthread=2048
celeborn.worker.push.io.threads 64
磁盘组设置更⼤使热点更加离散
celeborn.master.slot.assign.loadAware.numDiskGroups 20
celeborn.master.slot.assign.loadAware.flushTimeWeight 0.5
celeborn.master.slot.assign.loadAware.fetchTimeWeight 0.5
连接数设置
spark.celeborn.data.io.numConnectionsPerPeer=1
linux tcp连接数调整
1. Push 线程调优原则
评估 Push 线程配置,可查看 Worker 的 Netty 内存和物理机 IO 写⼊指标。Netty 内存⾼且 IO 写⼊低时,需增加 Push 线程。优化⾄最佳时,Spark 任务平均 Shuffle write time 应<3s,Celeborn worker 的 PushDataTime_Mean≈5ms,PushDataTime_Max≤1s。
2. Flush 线程调节原则
Fetch Thread 参数调节对 Spark 任务性能至关重要,尤其在使用特殊磁盘时。由于 Push 阶段(Map Task 完成计算后推送数据)时间较长,不易成为瓶颈;而 Fetch 阶段(Reduce Task 从上游获取 Shuffle 数据)快速,若拥堵则影响显著。我们采用以下方法调节 Fetch Thread 参数:先通过 Spark Shuffle Metric 计算集群峰值时的 Shuffle 数据量,再基于控制变量原理,阶梯式递增数据量进行压测,以确定最适合当前集群的参数值。
3. Worker 节点 CPU 占比优化
在应用过程中,发现大量小文件任务压测时,`FetchChunkTime_Mean`不合理。通过分析 Worker 节点的火焰图,发现 CPU 大量被不必要的指标统计占用。为此,优化指标的计算,减少无用的统计,从而显著提升 Worker 性能和指标计算速度。
4. 网卡优化
在优化线程数后,继续进行大规模 Shuffle 数据压测时发现,FetchChunkTime_Mean 仍不理想,且 IO 读消耗较低。进一步分析显示,网卡成为新的瓶颈。由于 Fetch 阶段 Reduce 任务成批次拉取大量数据且时间短,小网卡限制了性能(集群节点数较少)。因此后续 NVMe 固态硬盘机型 Worker 节点配置了25G双向网卡,最高可支持50G的上行下行流量。
最终:
Celeborn Worker 单位时间内处理的最大 Shuffle 数据量提升了近一倍。
物理机的 IO 读消耗达到了合理水平。
这一升级显著改善了 Celeborn 在高并发 Shuffle 场景下的性能表现。
5. Worker 连接数优化
由于采用单独的 NVMe 固态硬盘机型承载更多 Shuffle 请求,奇富科技的总体机器数远少于传统 NM 机器(约3%),这使得网络连接更易成为性能瓶颈。当 Worker 连接数达到1.5万时,热点问题显现,导致某些 Spark 任务的单个 Reduce Task Shuffle Fetch时间显著长于其他任务。
小结
总体而言,Celeborn 作为新一代 Shuffle 服务为 Spark 任务带来了显著提升,在超大集群环境下某些任务的性能优化达到了30%。它主要解决了 Shuffle 随机 IO 对集群环境的污染问题,这对混布的大数据集群尤其有利,不仅提升了任务本身的性能,还缓解了服务器上其他 IO 密集型服务的压力。
我们将继续深耕 Celeborn,计划将其打造为独立的 Shuffle Service 平台,支持更多具有 Shuffle 场景的组件接入,进一步提升整体大数据处理能力。
总结:
性能提升:任务平均优化达30%。
解决问题:任务耗时不再产生大的波动,减少 Shuffle 随机 IO 对集群的污染 (DataNode)。
未来计划:将 Celeborn 发展为独立 Shuffle Service 平台,支持更多组件接入。
▼ Celeborn 社区交流钉钉群:41594456 ▼
欢迎关注「Apache Celeborn」
点击「阅读原文」跳转 Celeborn 官网~