近期接手了不少大数据表任务调度补数据的工作,补数时发现资源消耗异常的大且运行速度却不怎么给力.
发现根本原因在于sparkSQL配置有诸多问题,解决后总结出来就当抛砖引玉了.
类型 | 内存数量 | cpu核心数量 | executor数量 | executor内存 | 单核心内存 |
---|---|---|---|---|---|
系统资源总量 | 7168G | 3500 | - | - | 2G |
目前一个任务 | 480G | 120 | 120 | 4G | 4G |
优化后 | 480G | 240 | 60 | 8G | 2G |
以下为SparkSQL调优相关设置
//1.下列Hive参数对Spark同样起作用。 set hive.exec.dynamic.partition=true; // 是否允许动态生成分区 set hive.exec.dynamic.partition.mode=nonstrict; // 是否容忍指定分区全部动态生成 set hive.exec.max.dynamic.partitions = 100; // 动态生成的最多分区数
//2.运行行为 set spark.sql.autoBroadcastJoinThreshold; // 大表 JOIN 小表,小表做广播的阈值 set spark.dynamicAllocation.enabled; // 开启动态资源分配 set spark.dynamicAllocation.maxExecutors; //开启动态资源分配后,最多可分配的Executor数 set spark.dynamicAllocation.minExecutors; //开启动态资源分配后,最少可分配的Executor数 set spark.sql.shuffle.partitions; // 需要shuffle是mapper端写出的partition个数 set spark.sql.adaptive.enabled; // 是否开启调整partition功能,如果开启,spark.sql.shuffle.partitions设置的partition可能会被合并到一个reducer里运行 set spark.sql.adaptive.shuffle.targetPostShuffleInputSize; //开启spark.sql.adaptive.enabled后,两个partition的和低于该阈值会合并到一个reducer set spark.sql.adaptive.minNumPostShufflePartitions; // 开启spark.sql.adaptive.enabled后,最小的分区数 set spark.Hadoop.mapreduce.input.fileinputformat.split.maxsize; //当几个stripe的大小大于该值时,会合并到一个task中处理
//3.executor能力 set spark.executor.memory; // executor用于缓存数据、代码执行的堆内存以及JVM运行时需要的内存 set spark.yarn.executor.memoryOverhead; //Spark运行还需要一些堆外内存,直接向系统申请,如数据传输时的netty等。 set spark.sql.windowExec.buffer.spill.threshold; //当用户的SQL中包含窗口函数时,并不会把一个窗口中的所有数据全部读进内存,而是维护一个缓存池,当池中的数据条数大于该参数表示的阈值时,spark将数据写到磁盘 set spark.executor.cores; //单个executor上可以同时运行的task数