如何缩短Apache Spark on YARN应用的调度延迟与任务反序列化时间?
问题分析与优化方案
一、Scheduler Delay 过长的优化方向
Scheduler Delay 通常和资源调度效率、集群资源配置、任务调度策略直接相关,优先从以下配置和策略调整入手:
- YARN 与 Spark 资源分配匹配:
- 每个工作节点预留部分资源给系统进程:将
yarn.nodemanager.resource.memory-mb设为14336(16GB 内存预留 2GB),yarn.nodemanager.resource.cpu-vcores设为10(12 核预留 2 核)。 - Spark 端调整 executor 资源分配:每个工作节点分配 2 个 executor,每个 executor 配置
spark.executor.memory=6g、spark.executor.cores=4,总 executor 数达 10,总核心数 40,避免资源碎片导致的调度等待。
- 每个工作节点预留部分资源给系统进程:将
- 调度策略调整:
- 若为批处理场景,将
spark.scheduler.mode设为FAIR,避免单队列任务阻塞;若为专属任务,保留FIFO但确保队列资源配额充足。 - 检查 YARN 队列配置,确认应用所在队列的资源配额未被其他任务抢占,必要时调整队列权重。
- 若为批处理场景,将
二、Task Deserialization Time 过长的优化方向
该指标过高通常和序列化效率、任务数据量、数据格式有关,优化点如下:
- 替换序列化框架:
- 将默认 Java 序列化改为 Kryo,设置
spark.serializer=org.apache.spark.serializer.KryoSerializer,若有自定义类需提前注册(spark.kryo.registeredClasses),Kryo 序列化速度和压缩率远优于 Java。
- 将默认 Java 序列化改为 Kryo,设置
- 减少任务传递的大对象:
- 避免通过闭包传递大数据集或配置对象,改用
spark.broadcast广播共享小数据,降低序列化数据量。
- 避免通过闭包传递大数据集或配置对象,改用
- 调整任务粒度:
- 确保任务数为总核心数的 2-3 倍(比如总核心 40 时,任务数保持 80-120),可通过
repartition或coalesce调整输入数据分区数,避免单任务处理过多数据导致序列化开销激增。
- 确保任务数为总核心数的 2-3 倍(比如总核心 40 时,任务数保持 80-120),可通过
- 优化输入数据格式:
- 替换 CSV、JSON 等文本格式为 Parquet、ORC 二进制格式,这类格式自带序列化优化,读取和反序列化效率大幅提升。
三、问题根源判断
从你描述的「Executor Computing Time 极低」来看,配置不合理的概率更高:比如未启用高效序列化、资源分配不匹配导致调度等待、任务粒度设置不当。但也不能排除代码问题,比如传递大闭包、使用低效数据格式等。建议先排查配置项,再验证代码逻辑。
下一步排查建议
如需更精准分析,可提供以下信息:
- Spark 提交参数(
spark-submit命令或spark-defaults.conf配置) - YARN 核心配置(
yarn-site.xml关键参数) - 代码中数据读取、转换的核心逻辑(尤其是涉及闭包传递、分区处理的部分)
- Spark UI 中各 Stage 的任务数、调度延迟/反序列化时间的分布情况
内容的提问来源于stack exchange,提问作者T. Hanuman
相关产品推荐
相关产品推荐

