Spark 性能优化涉及资源配置、代码设计、数据倾斜处理等多个维度,以下是综合官方文档与实际经验后的核心优化策略与方法:
一、资源配置优化
Executor 配置
-
数量与内存:
-
--num-executors 应结合集群总资源与任务特性合理设置(中小规模推荐 10~100)。
-
--executor-memory 建议每个 Executor 分配 6~10GB 内存,避免超过 YARN 队列限制。
-
CPU 核数:--executor-cores 建议设置为 2~4 核,以提升任务并行度。
-
并行度配置:
-
spark.default.parallelism 推荐设为总 Executor CPU 核数的 2~3 倍,以避免任务过少或部分核心闲置。
-
对于 Spark SQL,设置 spark.sql.shuffle.partitions 合理控制 Shuffle 分区数(默认 200,可调整为 400~1000)。
内存管理优化
-
调整内存分配比例:
-
spark.memory.fraction(默认 0.6):用于执行和缓存。
-
spark.memory.storageFraction(默认 0.5):用于缓存比例。
-
提高堆外内存:适当增加 spark.executor.memoryOverhead,防止因堆外开销不足导致 OOM。
二、RDD 与算子优化
RDD 复用与持久化
-
避免重复计算:对多次使用的 RDD 使用 persist() 或 cache()。
-
优先使用 MEMORY_ONLY_SER(配合 Kryo 序列化)减少内存使用。
-
尽早过滤无效数据:如在 map 前添加 filter。
高效算子替代与改写
-
用 mapPartitions 替代 map,批处理提升效率(注意控制分区数据量避免 OOM)。
-
用 foreachPartition 替代 foreach,如数据库写入场景可复用连接池。
-
使用 reduceByKey 替代 groupByKey,前者支持 map 端预聚合,可显著减少 Shuffle 数据量。
-
避免嵌套 RDD 操作,建议优先使用 DataFrame / Dataset API 以便 Catalyst 优化器介入。
三、数据倾斜处理
热点 Key 处理策略
-
倾斜识别:通过 Spark UI 查看 Shuffle Read Skew、Task Duration。
-
加盐处理:将大 Key 拆分为多个子 Key,Join 后再聚合。
-
两阶段聚合:先局部聚合(map 端),再全局聚合(reduce 端),适用于倾斜聚合类操作。
Join 策略优化
-
广播小表:使用 broadcast(df) 明确提示广播 Join,避免 Shuffle。
-
大表 Join:采用加盐扩容、大表拆分等策略平衡数据分布。
-
启用 AQE(Spark 3.x):
-
spark.sql.adaptive.enabled=true
-
spark.sql.adaptive.skewJoin.enabled=true 可自动识别倾斜并拆分 Join。
四、Shuffle 与序列化优化
Shuffle 调优
-
调整缓冲参数:
-
spark.shuffle.file.buffer:调整 Map 端缓冲区大小(默认 32KB)。
-
spark.reducer.maxSizeInFlight:控制 reduce 端拉取数据块的最大大小(默认 48MB,可适当提高)。
-
启用 AQE(Adaptive Query Execution):支持动态分区合并、小文件聚合、Join 策略调整。
序列化加速
-
启用 Kryo 序列化:
-
设置 spark.serializer=org.apache.spark.serializer.KryoSerializer
-
并注册自定义类(避免反射带来的开销)。
-
PySpark 加速建议:
-
优先使用 pandas_udf + Arrow 加速列式数据传输。
-
避免使用 udf 导致的 Java-Python 数据交互瓶颈。
-
对于大量自定义逻辑,结合 vectorized UDF 与内置函数更优。
五、其他关键优化
小文件治理
-
输入优化:设置 spark.sql.files.maxPartitionBytes 控制分区大小,合理合并读取文件。
-
输出优化:使用 coalesce(n) 或 repartition(n) 合理控制输出文件个数,避免产生大量小文件。
Catalyst 优化器利用
-
避免阻断优化:尽量使用内置 SQL 函数替代 UDF。
-
若需复杂逻辑,建议改用 pandas_udf 结合列式处理,不影响 Catalyst 优化器。
-
启用基于代价的优化器(CBO):
-
spark.sql.cbo.enabled=true,需配合 ANALYZE TABLE 收集表统计信息。
监控与诊断工具
-
利用 Spark UI 分析关键指标:
-
Stage Timeline 识别长尾 Task
-
Shuffle Read Size 评估数据倾斜
-
GC 时间与内存使用监控 Executor 状态
-
开启事件日志:结合 Spark History Server 或 Dr. Elephant、SparkLens 进行离线性能分析。
💎 总结与实践建议
Spark 性能优化无银弹,需结合实际场景持续迭代:
-
基础配置优先级最高:资源分配、并行度、序列化方式需合理配置。
-
数据特性驱动策略:如数据倾斜、小文件问题,需定制化优化方案。
-
推荐使用高级特性:如 AQE、CBO、结构化 API(DataFrame / SQL)优于 RDD 操作。
-
持续调试与验证:配合 Spark UI 与事件日志工具,逐步验证调优效果。