本次总结图如下
Executor内存管理两种机制
1:静态的内存管理分配图
(执行 --executor-memory 3G时候),会把executor内容分三大部分
2:统一的内存管理分配图
特点:Storage内存和shuffle内存可以互相借用,借用比例不能超过各自的50%
(执行 --executor-memory 3G时候),会把executor内容分三大部分
Spark资源调优两种情况
1、搭建集群的时候资源调优
配置更多资源,spark_worker_memory spark_worker_cores spark_worker_instance(每一个节点启动worker进程数)
2、在提交Application的时候资源调优
--executor-cores
--executor-memory
--driver-cores
--driver-memory
--total-executor-cores
Spark并行度调优
1、提高application的并行度(增加RDD的分区数)
a、读取hsfs数据 textfile(path,numPartion)
b、使用shuffle算子时候 reduceByKey(fun1,numPartion),如果在reduceByKey后面没有指定并行度,那么后面的stage的并行度j就是numberPartion
c、repartions,coalesce算子都可以增加RDD的分区
D、可以自定义分区器来增加RDD的并行度
备注:spark.default.parallelism没有默认值,如果在conf配置此参数 conf.set("spark.default.parallelism",100)
那么在shuffle过程中不指定并行度,默认并行度就是此设置的100, 例如 var rdd2=rdd.reduceByKey(fun1) ,rdd2的并行度就是100
Spark代码调优
1、避免创建重复的rdd
2、对多次使用rdd进行持久化(cache presist)
3、尽量避免使用shuffle算子 (广播变量来模拟join)
4、使用map-side预聚合的shuffle的操作
5、广播大变量
6、使用kryo优化序列化性能
7、优化数据结构(避免使用对象,字符串,集合类型)
8、使用高性能的库fastutil
9、使用高性能算子
mapPartition <- map
spark数据本地化 5中级别
1:Process_local 进程本地化,指的是task计算的数据在本进程中
2:node_local 节点本地化,指的是task计算的数据在本节点的磁盘上
3:no_pref 没有本地化这一说 ,比如数据在mysql
4: rack_local taks计算的数据在本机架的其他节点
5:any 随机了
配图说明如下
如何提交数据本地化级别?
答:设置本地化级别为Process_local,
调优办法,提高重试等待时间成本增长 3s -> 6s,
配置参数如下
spark.locality.wait 默认值3秒
spark.locality.wait.process =spark.locality.wait
spark.locality.wait.node =spark.locality.wait
spark.locality.wait.rack =spark.locality.wait
本地化代码解释
前言:hdfs文件集群最好包含计算集群,这样计算分发task可以直接在当前节点本地读取数据,进行计算,避免网络传输
1、从hdfs读取数据,一个三个rdd,将任务分成了三个2个job,job0中有两个rdd,job1中1个rdd
2、stage0从hdfs读取数据,所以数据最高级别只能为node_local
3、stage1是对stage0中的rdd进行过滤,数据最高级别process_local
数据倾斜(如果代码没有发生shuffle,一定不会发生数据倾斜)
1:对于hdfs,数据存储不均匀
2:对于计算框架MR,Hive,Spark来说,每一个task处理的数据量不一致
解决办法:
1、过滤少数导致倾斜的key
2、提高shuffle操作的并行度
3、双重聚合 (加随机前缀)
4、尽量避免使用shuffle类算子,可使用广播变量代替join算子