Spark调优
1 资源调优
1.1 分配更多的资源
- 分配资源
- 提交任务脚本
spark-submit \ -- master spark://node1:7077 \ --class com.WC \ --num-executors 3 \ 配置executor --driver-memory 1g \ 配置driver内存 --executor-memory 1g \ 配置每一个executor的内存大小 --executor-core 3 \ 配置每一个executor的cpu 个数
- 参数调节
Standalone模式
计算出每个公司spark集群上的所有资源,每台节点的内存大小和cput参数。
Yarn模式
先计算出yarn集群的所有大小
1.2 提高并行度
spark作业中,各个stage的task的数量,也就代表了spark作业在各个阶段stage的并行度!当分配完所能分配的最大资源了,然后对应资源去调节程序的并行度。
- 可以设置task的数量
- 设置成spark Application 总cpu core数量的2-3倍
- 设置参数spark.default.parallelism设置task数量
- 默认是没有值的,如果设置了值为10,它会在shuffle的过程才会起作用
- 给RDD重新设置partition的数量
- 使用rdd.repartion重新分区
- 提高SparkSql运行的task数量
- Spark.sql.shuffle.partitions 默认为200
2. 开发调优
2.1 RDD的重用和持久化
- rdd的cache或者persist方法进行持久化。cache默认是把数据持久化到内存中,其本质还是调用了persist方法。
- 持久化时可以使用序列化
2.2 广播变量的使用
SparkContext的broadcast方法把数据转换成广播变量。获取广播变量中的值可以通过broadcast方法把数据转换成广播变量。
2.3 尽量避免使用shuffle类蒜子
map-side 预聚合,在每个节点本地对相同的key进行一次聚合操作
2.4 使用高性能算子
使用高性能的算子
- 使用reduceByKey/aggregateByKey替代groupByKey;
- 使用mapPartitions替代普通map;mapPartitions一次函数调用会处理一个partition所有的数据。
- 使用foreachPartitions替代foreach;一次函数调用处理一个partition的所有数据。
- 使用filter之后进行coalesce操作;
- 使用repartitionAndSortWithinPartitions替代repartition与sort类操作
3. jvm调优
spark中堆内存被划分为两块:
- 给RDD作cache\persist持久化的 StorageMemory.
- 专门来另一块是给spark算子函数运行使用的,存放函数中自己创建的对象。
1.6版本之后采用统一内存管理机制 :storage和execution各占50%,若己方不足对方空余可占用对方空间
可尝试调节executor堆外内存
spark.yarn.executor.memoryOverhead = 2048m
调节连接等待时长
spark.core.connection.ack.wait.timeout = 300
4. shuffle数据倾斜调优
- 预聚合源数据,对hive源表提前进行聚合操作,在hive聚合之后,spark任务再去读取
- 检查倾斜的key是否是脏数据,可以提前过滤
- 提高shuffle操作reduce的并行度
- 使用随机key实现双重聚合
- 将reduce端 join转换成map端 join
- sample采样倾斜key,单独进行join后在union
- 使用随机数以及扩容表进行join