Spark 批处理调优这点事:资源怎么要、Shuffle 怎么省、序列化怎么选?我用这些年踩过的坑告诉你

简介: Spark 批处理调优这点事:资源怎么要、Shuffle 怎么省、序列化怎么选?我用这些年踩过的坑告诉你

Spark 批处理调优这点事:资源怎么要、Shuffle 怎么省、序列化怎么选?我用这些年踩过的坑告诉你

大家好,这里是大数据圈里“被 Yarn 吊着打过、和 Spark 吵过架”的 Echo_Wish。
今天咱们来聊聊 Spark 批处理作业的调优。别听到“调优”两个字就觉得高大上,它其实本质就是三句话:

资源别瞎要、Shuffle 别乱搞、序列化别拖后腿。

你能把这三件事整明白,70% 的性能问题都会给你让路。剩下 30% 基本靠缘分和运维同事心情。

这篇文章,我想和你聊点真东西:你能立刻用、立刻见效、能救你半夜线上跑不动作业的那种优化技巧。


一、资源调优:要得对比要得多更重要

Spark 作业的资源问题,大部分不是资源少,而是资源分配的方式完全不对。

1. Executor 数量和 CPU 核心到底怎么配?

这里给你一个我自己线上测试无数次得出的“黄金思路”:

  • Executor 内核数别超过 5~6 个
    因为再多 GC 压力大、上下文切换更大、反而越跑越慢。

  • Executor 数量比核心数量更重要
    小 Executor + 多 Executor 往往比 大 Executor + 少 Executor 更稳。

例如,你的集群有 50 核想全用上,不要这样配:

# 典型的错误配置:又大又笨
--executor-cores 10
--num-executors 5

应该这样:

# 典型的性能更优配置:小而精,数量多
--executor-cores 5
--num-executors 10

为什么?
因为大 Executor 会导致:

  • GC 时间飙升
  • Shuffle 文件争抢
  • Task 并发不均衡

而小 Executor 则让资源调度更灵活、稳定性更高。


2. Executor 内存不是越大越好

很多朋友喜欢直接开 20G、30G 内存的 Executor,我只能说:
你这是把自己的作业推进了 GC 炼狱

合理内存一般在 6~12G 之间,特别是 ETL 型作业。

万一你非要调大?那至少要打开:

--conf spark.memory.fraction=0.6
--conf spark.memory.storageFraction=0.3

否则别怪 Spark 动不动 OOM。


二、Shuffle 调优:能绕开就绕开,绕不开就优化

Shuffle 是 Spark 性能最大的杀手,没有之一。
凡是经过 Shuffle 的地方,都会:

  • 打断 pipeline
  • 写磁盘、读磁盘
  • 网络传输
  • 排序 & 聚合

你要做的不是“优化 Shuffle”,而是“减少 Shuffle”!

1. 尽量避免两个最致命的操作:groupByKeyjoin

groupByKey 是性能灾难,因为它会把 key 相同的所有 value 拉到同一个 Executor。

举个例子:

// 千万别这么写!这是 shuffle 地狱!
rdd.groupByKey()

正确写法应该使用 reduceByKey / aggregateByKey

// reduceByKey 会在 Map 端先进行预聚合,极大减少 shuffle 数据量
rdd.reduceByKey(_ + _)

2. join 一定要提前 broadcast 小表,减少 shuffle

传统 join 如下,一定会 shuffle:

df1.join(df2, "id")

但如果 df2 是小表(小于 300MB),你应该这样写:

import org.apache.spark.sql.functions.broadcast

df1.join(broadcast(df2), "id")

本质就是:凡是小表 join,大胆 broadcast。

3. Shuffle 分区(spark.sql.shuffle.partitions)是性能关键

Spark 默认是 200 分区,这个值对大多数作业来说过大或过小。

我的经验:

数据量 推荐分区数
< 10GB 50~100
10~200GB 200~500
> 200GB 500~2000

设置方式:

--conf spark.sql.shuffle.partitions=300

千万不要盲目调大分区,否则:

  • 分区太多 → 调度时间爆炸
  • 分区太少 → 单分区数据倾斜

三、序列化:Spark 性能的隐形加速器

Spark 默认使用 Java 序列化,效率低、体积大,非常影响 shuffle 和 cache 效率。

一句话:强烈建议使用 Kryo。

开启 Kryo:

--conf spark.serializer=org.apache.spark.serializer.KryoSerializer
--conf spark.kryo.registrationRequired=false

如果你有自定义 class,可以手动注册,加速更多:

val conf = new SparkConf()
conf.registerKryoClasses(Array(classOf[MyClass]))

为什么 Kryo 这么重要?

  • 序列化速度比 Java 快 5~10 倍
  • 体积小 30%~60%
  • 直接提升 shuffle 和 cache 性能

我自己线上 ETL 作业切到 Kryo 后,整体性能提升了 25% 左右,非常划算。


四、一个真实案例:从 1 小时优化到 14 分钟

某业务的明细拉链作业每日增量约 80GB,最初 60 分钟跑不完。
我调优后压到了 14 分钟。优化手段如下:

1. 资源重配

从:

--executor-cores=8
--executor-memory=20G
--num-executors=10

改成:

--executor-cores=5
--executor-memory=10G
--num-executors=18

GC 秒降。

2. Broadcast 小表

原来:

df1.join(df2, Seq("uid", "date"))

改为:

df1.join(broadcast(df2), Seq("uid", "date"))

Shuffle 直接少一半。

3. Spark Shuffle 分区调小

从默认 200 → 调整为 300
结合 80GB 数据量效果刚刚好。

4. 序列化改为 Kryo

直接减少 shuffle 文件大小,带来 10~15% 性能收益。


五、最后说一句:调优没有银弹,但有套路

Spark 调优看起来复杂,其实就三个方向:

  1. 让资源配置更合理
  2. 减少 Shuffle,或者让 Shuffle 更轻量
  3. 让数据体积更小,序列化更高效

你只要掌握这三点,任何批处理作业你都能找到优化点。

而调优最核心的本质就是一句话:

你要理解 Spark 的执行方式,而不是调一堆参数希望它变快。

代码写得再优雅、框架再先进,只要你无脑 groupByKey、无脑大 Executor、无脑默认序列化,性能肯定救不回来。

目录
相关文章
|
21天前
|
Prometheus 分布式计算 监控
大数据指标和 SLA,那些你以为懂了其实没懂的事
大数据指标和 SLA,那些你以为懂了其实没懂的事
220 7
|
27天前
|
存储 自然语言处理 测试技术
一行代码,让 Elasticsearch 集群瞬间雪崩——5000W 数据压测下的性能避坑全攻略
本文深入剖析 Elasticsearch 中模糊查询的三大陷阱及性能优化方案。通过5000 万级数据量下做了高压测试,用真实数据复刻事故现场,助力开发者规避“查询雪崩”,为您的业务保驾护航。
1020 52
|
10天前
|
机器学习/深度学习 缓存 物联网
打造社交APP人物动漫化:通义万相wan2.x训练优化指南
本项目基于通义万相AIGC模型,为社交APP打造“真人变身跳舞动漫仙女”特效视频生成功能。通过LoRA微调与全量训练结合,并引入Sage Attention、TeaCache、xDIT并行等优化技术,实现高质量、高效率的动漫风格视频生成,兼顾视觉效果与落地成本,最终优选性价比最高的wan2.1 lora模型用于生产部署。(239字)
201 27
|
1月前
|
机器人 数据挖掘 API
一个销售数据分析机器人的诞生:看 Dify 如何在 DMS 助力下实现自动化闭环
Dify 作为一款低代码 AI 应用开发平台,凭借其直观的可视化工作流编排能力,极大降低了大模型应用的开发门槛。
418 22
一个销售数据分析机器人的诞生:看 Dify 如何在 DMS 助力下实现自动化闭环
|
1月前
|
人工智能 前端开发 算法
大厂CIO独家分享:AI如何重塑开发者未来十年
在 AI 时代,若你还在紧盯代码量、执着于全栈工程师的招聘,或者仅凭技术贡献率来评判价值,执着于业务提效的比例而忽略产研价值,你很可能已经被所谓的“常识”困住了脚步。
1359 89
大厂CIO独家分享:AI如何重塑开发者未来十年
|
19天前
|
算法 安全 量子技术
量子来了,RSA要凉?聊聊后量子加密的未来与现实(含代码!)
量子来了,RSA要凉?聊聊后量子加密的未来与现实(含代码!)
114 11
|
6天前
|
数据可视化 前端开发 数据挖掘
期货数据API对接与可视化分析全攻略:从数据获取到K线图生成
本文系统讲解期货数据API对接与K线图可视化全流程,涵盖WebSocket实时行情获取、RESTful历史数据调用、Pandas数据清洗处理及mplfinance、ECharts等多方案图表生成,助你构建完整的期货分析系统。
|
1月前
|
运维 监控 数据可视化
故障发现提速 80%,运维成本降 40%:魔方文娱的可观测升级之路
魔方文娱携手阿里云构建全栈可观测体系,实现故障发现效率提升 80%、运维成本下降 40%,并融合 AI 驱动异常检测,迈向智能运维新阶段。
314 36
|
2月前
|
存储 消息中间件 Kafka
Confluent 首席架构师万字剖析 Apache Fluss(一):核心概念
Apache Fluss是由阿里巴巴与Ververica合作开发的Flink表存储引擎,旨在提供低延迟、高效率的实时数据存储与变更日志支持。其采用TabletServer与CoordinatorServer架构,结合RocksDB和列式存储,实现主键表与日志表的统一管理,并通过客户端抽象整合湖仓历史数据,弥补Paimon在实时场景下的性能短板。
519 22
Confluent 首席架构师万字剖析 Apache Fluss(一):核心概念