尚硅谷最新Spark3.0调优笔记

尚硅谷Spark 调优

1. 查看Spark 执行计划
2. 资源调优
3. Spark SQL 语法优化
4. 数据倾斜
5. Job 优化
6. Spark AQE
7. Spark 3.0 DPP
8. Spark 3.0 Hint增强
9. 故障排除

1. Explain 查看执行计划

***

分析–逻辑计划优化–物理计划–评估模型分析—代码生成


基于代价的优化CBO
sql.explain("")  
 空/simple/extended  /codegen 显示可执行java 代码 /formatted  物理计划大纲
 用 空 或 extended 多一点

看执行计划 从下往上 看。
缩进一样的话同时执行。
Project : 列裁剪 SQL 中投影操作。 Exchange 其实就是shuffle
聚合一般在执行计划里分为两步 一步是 预聚合 还有就是 分组聚合。
单个Reducer 内部hashpartitioning +Exchange HashPartitioning Exchange 即是shuffle 全表扫描是Local TableScan

2.资源调优

		资源设定上限 估算  机器内存 ,executor 数量
		
		精确内存估算:核心 估算一个Executor 内存多大合适。 
		内存模型 统一内存模型
			      动态内存
			      storage 缓存 广播变量     广播变量+cache/Executor 数量
			      execution。 shuffle   核心操作。 每个Executor 核数*(数据集大小/并行度)
			      other 用户定义的数据结构。    自定义数据结构* 每个Executor 核数

spark.memory.fraction = S+E / S+E+O
spark.memory.storageFraction = S/S+E

1. 持久化和序列化
	RDD 
	  RDD cache  缓存级别
	  Kryo  序列化
    DS	DF 相关序列化
    	cache 和序列化 自己实现的Encoder
    	对于Spark SQL 而言 用不用序列化差异不大 ,但RDD 注意使用。
    	
2. CPU 优化
	CPU低效原因:
	并行度:task 的数量
		spark.default.parallelism RDD 默认自动 由join reduceByKey 等转换决定
		spark.sql.shuffle.partitions SQL  默认200
	并发度:同时执行的task 数量
	低效:
		并行度较低 数据分片较大容易导致CPU线程挂起
		较高,数据过于分散让调度开销更多。
 并行度设置:task 数量 集群核心数(并发度)的两到三倍 2 -3 

3.Spark SQL 语法优化

    1)基于RBO的优化
	      inner join 的谓词下推。
		  列裁剪
	  	  常量替换
	2)Statistics 收集. CBO 优化
		 计算可能的物理计划的代价
		 生成表级别的信息 统计
		 ANALYZE TABLE src  COMPUTE STATISTIsCS 
	     使用CBO
	     	spark.sql.cb.enabled. CBO 总开关
	     	spark.sql.cbo.joinReorder.enabled   使用CBO 来自动调整连续的inner join 的顺序
	     	spark.sql.cbo.joinReorder.dp.threshold CBO 来自动调整 连续inner join 的表的个数阈值。
	     	CBO 以过滤后大小做判断 是否广播join 而正常则是以过滤之前的量来判断
	3)广播Join
	4)SMB Join
		两表分桶 桶数相等 
		两边Join 时 join列=排序列=分桶列
		可以不改原表 插入一张分桶的中间表中

4. 数据倾斜

       原因: 一般是 发生在Shuffle 类的算子 比如distinct groupByKey reduceByKey aggregateByKey join cogroup 等 涉及到数据 重分区。如果其中一个Key 数量特别大 就发生了数据倾斜。
       数据倾斜 大Key 定位。
    		  抽样定位大key sample
	   单表数据倾斜的处理:
	   		 提前预聚合。
	   	      shuffle read 数据不均匀 出现倾斜 
	   	      随机前缀 + 随机前缀去除
> val sql1 =
      """
        |select
        |  courseid,
        |  sum(course_sell) totalSell
        |from
        |  (
        |    select
        |      remove_random_prefix(random_courseid) courseid,
        |      course_sell
        |    from
        |      (
        |        select
        |          random_courseid,
        |          sum(sellmoney) course_sell
        |        from
        |          (
        |            select
        |              random_prefix(courseid, 6) random_courseid,
        |              sellmoney
        |            from
        |              sparktuning.course_shopping_cart
        |          ) t1
        |        group by random_courseid
        |      ) t2
        |  ) t3
        |group by
        |  courseid
      """.stripMargin
/*SQL*/

      Join数据倾斜优化:
	  广播Join
	      拆分大key     Join    倾斜前缀打散再Union
	      	添加一个额外的字段,用作关联原有的字段不变 效率更高、
	      	实现
		   打散打表 扩容小表
	       参数开启AQE
5 Job 优化:
   Map 端
		Map端预聚合
		读取小文件的优化
               spark.sql.files.maxPartitionsBytes =128M
               spark.files.openCostInBytes=4194304       4M  文件开销。(合并小文件阈值:这说法错误)
              源码: def maxSplitBytes
              	*

Math.min(defaultMaxSplitBytes,Math.max(openCostInBytes,bytesPerCore))

bytesPerCore= totalBytes/defaultParallelism 默认分区数 默认并行度 计算total bytes 时每个文件都要加上open 开销

		增大map溢写时输出流buffer  减少小文件
		mybeSpill   internal 方法 对外不可见 public 属性为false   myMemoryThreshold 初始阈值。
		ExternalSort: spill 方法。默认写入磁盘 10000 一批次 。
		原始阈值5M 和批次的10000 条无法调整。 spark.shuffle.file.buffer = 32 -> 64 shuffle write 性能提升。
		
Reduce 端优化:  过多资源CPU 空转浪费 过少影响任务性能
		合理Reduce 数量
		输出产生小文件优化
			1.join 后结果插入新表
				解决方式:
					插入表前进行缩小分区操作来解决小文件过多的问题 如coalesce repartition 
					调整shuffle 并行度 
			2.动态分区插入数据
				倾斜分区单独处理。
		增大Reduce 缓冲区减少拉取的次数。
		reducer 端缓冲区。spark.reducer.maxSizeInFlight  48M 默认。
		调节Reduce端 拉取数据等待间隔 spark.shuffle.io.retryWait   提高稳定性。
		调节Reduce 端拉取数据重试次数
			spark.shuffle.io.maxRetries 
			
		合理使用Bypass
		普通 /ByPass/序列化 shuffle   registerShuffle。注册shuffle。
			没有预聚合(map端聚合). shuffle read task数量小于200 (sort shuffle manager)
			非bypass 要做排序。

5.整体优化

	调节数据本地化等待时长
	spark.locality.wait   6s ,10s  默认3s。
	spark.locality.wait.process 60s
	spark.locality.wait.node 30s
	spark.locality.wait.rack 20s   默认单位是 ms
		节点本地化 即可
		等待时间大于网络传输时间 ? 没必要 非要实现进程本地化
	使用堆外内存
	 spark.memory.enable.offheap.enable 设置为true。
	 spark.executor.memory.Overhead 默认开启  默认为 spark.executor.memory*0.1 而且会与 min 384m 做对比取最大值。 所以spark on yarn 任务堆内内存 申请一个而时机去yarn 申请的内存大于1G。
	 2.4  exec memory + mem overhead + pyspark memory 
	 3.0 exec memory + exec offHeap memory + mem overhead +pyspark memory
	 **注意版本区别**
	 StorageLevel.OFF_HEAP    堆外内存 存储级别
	调节连接等待时长
	spark.network.timeout 

6 Spark AQE

	演示AQE效果关闭广播Join 
 **`.set("spark.sql.autoBroadcastJoinThreshold", "-1") //为了演示效果,禁用广播join
  .set("spark.sql.adaptive.enabled", "true")
  .set("spark.sql.adaptive.coalescePartitions.enabled", "true") // 合并分区的开关
  .set("spark.sql.adaptive.coalescePartitions.initialPartitionNum","1000") // 初始的并行度
  .set("spark.sql.adaptive.coalescePartitions.minPartitionNum","10") // 合并后的最小分区数
  .set("spark.sql.adaptive.advisoryPartitionSizeInBytes", "20mb") // 合并后的分区,期望有多大`**
 动态和合并分区
 动态申请资源。
 动态切换Join策略
 动态优化Join倾斜
	自动打散。
    会有越界情况产生  倾斜大小小于优化阈值。

7 Spark DPP

	动态分区裁剪。  

8 Spark Hint 增强 产生指定一种join类型。

broadcasthash join
sort merge join
shuffle_hash join
shuffle_replicate_nl join 优先级最低

9 故障排除

1.控制reduce 端缓冲大小以避免OOM 
  太大 会OOM  
2.JVM  GC 导致的shuffle 文件拉取失败
3.解决各种序列化问题导致的报错
4.解决算子返回NULL 导致的问题。 替换成业务上的 无意义值。
5. 解决YARN-CLIENT模式下导致网卡流量激增问题
6.YARN-CLUSTER模式下的JVM栈内存溢出无法执行的问题
	永久代的问题  82M--128M  子查询过多会栈溢出。
7.Spark SQL 导致的JVM栈内存溢出
8.持久化与checkpoint的使用
9.内存泄露排查
		IBM HadpAnalyzer
		JMAP 
10.频繁GC问题
	建议G1 GC       
  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值