一、动态资源分配(让集群按需增减 Executor)
-
spark.dynamicAllocation.enabled=true开启动态资源分配。Spark 会根据任务负载自动请求新 Executor 或释放空闲 Executor,避免资源浪费。
-
spark.shuffle.service.enabled=true开启外部 Shuffle 服务。这是动态资源分配的前提,保证 Executor 被回收时,其上产生的 Shuffle 数据仍能被其他节点读取。
-
spark.dynamicAllocation.maxExecutors=150动态分配时,最多申请 150 个 Executor(即使负载再高也不超过此数)。结合下面显式设置的
--num-executors 120,意味着初始启动 120 个,繁忙时可弹性扩至 150。 -
spark.dynamicAllocation.cachedExecutorIdleTimeout=60持有缓存数据的 Executor 空闲超过 60 秒后,也会被回收。默认是无限大(永不回收),设为 60 可更快释放资源。
二、Shuffle 并行度与网络传输(直接影响数据分布和性能)
-
spark.sql.shuffle.partitions=14000设置 Shuffle 操作(如
JOIN、GROUP BY)产生的默认分区数为 14000。这个值直接决定了 Reducer 的数量。 -
spark.shuffle.file.buffer=64KShuffle 写文件时,每个分区使用的内存缓冲区大小为 64 KB。适当增大可减少磁盘 I/O 次数(默认 32K)。
-
spark.reducer.maxSizeInFlight=96MReducer 从 Mapper 端拉取数据时,单次请求的最大数据量为 96 MB(默认 48M)。加大可提升吞吐,但会消耗更多内存。
-
spark.shuffle.io.retryWait=20Shuffle 网络请求失败时的重试等待间隔(秒)。默认可能更短,设为 20 秒表示在网络抖动时给更长的恢复时间。
-
spark.shuffle.memoryFraction=0.8(旧版参数) 指定 JVM 堆内存中用于 Shuffle 聚合和排序的比例为 80%。在 Spark 1.6 之前用于控制 Shuffle 内存池大小,新版已废弃,使用
spark.memory.fraction统一管理。如果版本较老,此参数仍会生效。 -
spark.shuffle.consolidateFiles=true(旧版参数) 开启 Shuffle 文件合并。将同一批次任务产生的多个中间 Shuffle 小文件合并成更少的文件,以减少磁盘随机读写压力。在 Spark 1.6 以后,此机制已被更优的排序式 Shuffle 取代,若仍在使用,可能是为了兼容历史版本。
三、内存与 GC(Executor 进程级资源控制)
-
spark.executor.memoryOverhead=6GExecutor 的堆外内存为 6 GB。这部分内存用于 JVM 自身开销、网络缓冲、字符串常量池等。结合
--executor-memory 40G,每个 Executor 容器向 YARN 申请的物理总内存为40 + 6 = 46 GB。 -
spark.executor.extraJavaOptions=-XX:+UseG1GC -XX:ParallelGCThreads=10给 Executor JVM 传递额外参数,这里指定使用 G1 垃圾回收器(适合大堆、低延迟场景),并设置并行 GC 线程数为 10(通常与核心数
--executor-cores 10匹配)。
四、IO 压缩与 Parquet 兼容性
-
spark.io.compression.codec=org.apache.spark.io.ZStdCompressionCodec使用 ZStandard(Zstd)作为 Shuffle 数据和中间结果的压缩算法。相比默认的 LZ4,Zstd 压缩率更高,能显著减少 Shuffle 传输量,代价是轻微增加 CPU。
-
spark.sql.parquet.enableVectorizedReader=false关闭 Parquet 向量化读。可能因为数据中有复杂嵌套字段或部分列类型不兼容向量化,强制走逐行读,保证正确性。
-
spark.sql.storeAssignmentPolicy=LEGACY表数据写入时的类型转换策略设为
LEGACY,即遵循 Spark 2.x 的宽松规则(允许一些默认禁止的类型强转),用于兼容老数据。 -
spark.sql.parquet.int96RebaseModeInRead=LEGACY读取 Parquet 文件时,对于 INT96 格式的时间戳,使用旧版时区偏移方式。这通常是为了与 Hive 老版本写入的 Parquet 时间戳字段保持一致,避免读取时出现时区偏移错误。
-
spark.sql.sources.partitionOverwriteMode=dynamic动态分区覆写模式。当执行
INSERT OVERWRITE TABLE时,只覆盖语句中实际涉及的那些分区,不会清空整表。这能防止误删其他日期的数据。
五、PySpark 环境与依赖
-
spark.yarn.appMasterEnv.PYSPARK_PYTHON=/usr/bin/python3.8设置 YARN ApplicationMaster 容器内 Python 解释器路径。
-
spark.pyspark.driver.python=/usr/bin/python3.8Driver 端使用的 Python 路径。
-
spark.pyspark.python=python3env/usr/bin/python3.8Executor 端使用的 Python 路径(可能指向一个自定义虚拟环境
python3env)。 -
--py-files hdfs:///user/hive/jinja2.zip,hdfs:///user/hive/markupsafe.zip分发到所有节点的 Python 依赖包(这里是 Jinja2 模板引擎及其依赖 MarkupSafe),供 PySpark 脚本使用。
六、基础资源规格(静态分配部分)
-
--executor-cores 10每个 Executor 使用 10 个 CPU 核心。
-
--executor-memory 40G每个 Executor 堆内内存 40 GB。
-
--driver-cores 8Driver 使用 8 个核心。
-
--driver-memory 20GDriver 内存 20 GB。
-
--num-executors 120启动时请求 120 个 Executor。因为开了动态分配,这是初始数量,后续可根据负载在 120~150 之间浮动。
-
--master yarn使用 YARN 作为集群管理器。
-
--deploy-mode clusterDriver 运行在 YARN 集群的某个节点上,而非提交任务的客户端。
-
--queue warehouse任务提交到 YARN 队列
warehouse。 -
--name jms_dwd__...为这个 Spark 应用设置显示名称,便于在 YARN UI 中识别。