spark 调优((一)

本文深入探讨Spark调优,包括通过Explain查看执行计划,资源调优如内存估算和CPU优化,以及Spark SQL的语法优化,如RBO与CBO的策略,广播Join和SMB Join的应用。
摘要由CSDN通过智能技术生成

1.Explain的查看执行计划

2.资源调优

2.1 资源规划

以单台服务器 128G 内存,32 线程为例。
先设单个Executor 核数,如果设置Executor的核数是4,那么最多跑7个executor。
总的 executor 数=单节点数量*节点数

2.1.1 具体提交参数

1)Driver
不负责具体任务的计算,除非调用colllect 函数。一般1G,2G
2) executor-cores
每个 executor 的最大核数。根据经验实践,设定在 3~6 之间比较合理(一般是4个)
3) num-executors
该参数值=每个节点的 executor 数 * work 节点数(总的服务器数)
每个 node 的 executor 数 = 单节点 yarn 总核数 / 每个 executor 的最大 cpu 核数
比如服务器的核数是32G,分给yarn的配置是yarn.nodemanager.resource.cpu-vcores 配
置为:28,参数 executor-cores 的值为:4,那么每个 node 的 executor 数 = 28/4 = 7,假设集
群节点为 10,那么 num-executors = 7 * 10 = 70
假设一个任务你设置100个,那么肯定会出现问题。
4)executor-memory
单个executor多大的内存。要么oom,要么就处理的速度很慢。
该参数值=yarn-nodemanager.resource.memory-mb / 每个节点的 executor 数量
如果 yarn 的参数配置为 100G,那么每个 Executor 大概就是 100G/7≈14G,同时要注意
yarn 配置中每个容器允许的最大内存是否匹配。

2.1.2 内存估算

在这里插入图片描述
1.系统的预留内存,默认300M
2.可用内存:统一内存和其它
其它:元数据和自己定义的数据结构。map (40%)
统一内存(60%)
Store 50%
cache,presist 缓存,广播变量。
executor 50%–执行内存
shuffle. join,group by key
对于一个Executor 而言:
估算 Other 内存 = 自定义数据结构每个 Executor 核数
估算 Storage 内存 = 广播变量 + cache/Executor 数量
估算 Executor 内存 = 每个 Executor 核数 * (数据集大小/并行度)
单个并行度的数据量,shuffle 200, 要shuffle的数据集是100G,每个task 500M,假设是4个核。
最少4
500M=2G

2.1.3调整内存配置项

spark.memory.fraction=(估算 storage 内存+估算 Execution 内存)/(估算 storage 内存
+估算 Execution 内存+估算 Other 内存)得到
spark.memory.storageFraction =(估算 storage 内存)/(估算 storage 内存+估算
Execution 内存)
代入公式计算:
Storage 堆内内存=(spark.executor.memory–300MB)spark.memory.fractionspark.memory.storageFraction
Execution 堆内内存=
(spark.executor.memory–300MB)spark.memory.fraction(1-spark.memory.storageFraction)

2.2 持久化和序列化

2.2.1 RDD

1、cache
在这里插入图片描述
打成 jar,提交 yarn 任务,并在 yarn 界面查看 spark ui
spark-submit --master yarn --deploy-mode client --driver-memory 1g --numexecutors 3 --executor-cores 2 --executor-memory 6g --class
com.atguigu.sparktuning.cache.RddCacheDemo spark-tuning-1.0-SNAPSHOT-jarwith-dependencies.jar
在这里插入图片描述
通过 spark ui 看到,rdd 使用默认 cache(内存) 缓存级别,占用内存 2.5GB,并且 storage 内存
还不够,只缓存了 29%。
2.kryo+序列化缓存
使用 kryo 序列化并且使用 rdd 序列化内存缓存级别。使用 kryo 序列化需要修改 spark 的序
列化模式,并且需要进程注册类操作。
打成 jar 包在 yarn 上运行。
spark-submit --master yarn --deploy-mode client --driver-memory 1g --numexecutors 3 --executor-cores 2 --executor-memory 6g --class
com.atguigu.sparktuning.cache.RddCacheKryoDemo spark-tuning-1.0-SNAPSHOTjar-with-dependencies.jar
查看 storage 所占内存,内存占用减少了 1083.6mb 并且缓存了 100%。使用序列化缓
存配合 kryo 序列化,可以优化存储内存占用。
在这里插入图片描述
3.DataFrame、DataSet
1、cache
提交任务,在 yarn 上查看 spark ui,查看 storage 内存占用。内存使用 612.3mb
spark-submit --master yarn --deploy-mode client --driver-memory 1g --numexecutors 3 --executor-cores 2 --executor-memory 6g --class
com.atguigu.sparktuning.cache.DatasetCacheDemo spark-tuning-1.0-SNAPSHOTjar-with-dependencies.jar
在这里插入图片描述
DataSet 的 cache 默认缓存级别与 RDD 不一样,是 MEMORY_AND_DISK。
源码:Dataset.cache() -> Dataset.persist() -> CacheManager.cacheQuery()
在这里插入图片描述
DataSet 类似 RDD,但是并不使用 JAVA 序列化也不使用 Kryo 序列化,而是使用一种特
有的编码器进行序列化对象。
从性能上来讲,DataSet,DataFrame 大于 RDD,建议开发中使用 DataSet、DataFrame

2.3 cpu 优化

2.3.1CPU 低效原因

1)并行度
spark.default.parallelism(task 数量)
在这里插入图片描述
设置 RDD 的默认并行度,没有设置时,由 join、reduceByKey 和 parallelize 等转换决定。
2)spark.sql.shuffle.partitions
适用 SparkSQL 时,Shuffle Reduce 阶段默认的并行度,默认 200。此参数只能控制
Spark sql、DataFrame、DataSet 分区个数。不能控制 RDD 分区个数
在这里插入图片描述
并发度:同时执行的 task 数

2.3.2 合理利用 CPU 资源

spark-submit --master yarn --deploy-mode client --driver-memory 1g --num-executors 3 --executor-cores 4 --executor-memory 6g --class
com.atguigu.sparktuning.partition.PartitionDemo spark-tuning-1.0-
SNAPSHOT-jar-with-dependencies.jar
去向 yarn 申请的 executor vcore 资源个数为 12 个(num-executors*executor-cores),如
果不修改 spark sql 分区个数,那么就会像上图所展示存在 cpu 空转的情况。(最后一个cpu跑,其他的在的空转)
在这里插入图片描述

为了合理利用资源,一般会将并行度(task 数)设置成并发度(vcore 数)的 2 倍到 3 倍。也就是设置成36个task。
修改参数 spark.sql.shuffle.partitions(默认 200), 根据我们当前任务的提交参数有 12个 vcore,将此参数设置为 24 或 36 为最优效果:
在这里插入图片描述

3.spark sql的语法优化

SparkSQL 在整个执行计划处理的过程中,使用了 Catalyst 优化器。

3.1 RBO 的优化

3.1.1 谓词下推

谓词(过滤条件,on 后面的和where 后面的)
将 过 滤 条 件 的 谓 词 逻 辑 都 尽 可 能 提 前 执 行 , 减 少 下 游 处 理 的 数 据 量 。
左外关联下推规则:左表 left join 右表
在这里插入图片描述
注意:外关联时,过滤条件写在 on 与 where,结果是不一样的!

3.1.2 列剪裁(Column Pruning)

列剪裁就是扫描数据源的时候,只读取那些与查询相关的字段。

3.1.3 常量替换

我们在 select 语句中,掺杂了一些常量表达式,Catalyst 也会自动地用表达式的结果进行替换。

3.2 基于 CBO 的优化

CBO 优化主要在物理计划层面,原理是计算所有可能的物理计划的代价,并挑选出代价最小的物理执行计划。
每个执行节点的代价,分为两个部分:
1)该节点输出数据集的大小与分布
2)该执行节点操作算子的代价
1)初始数据集,也即原始表,其数据集的大小与分布可直接通过统计得到;
2)中间节点输出数据集的大小与分布可由其输入数据集的信息与操作本身的特点推算。

3.2.1Statistics 收集

1)从Hive 源数据库中查看 tbls
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
生成表级别统计信息(扫表)

ANALYZE TABLE 表名 COMPUTE STATISTICS

生成 sizeInBytes 和 rowCount。 大小和行数
在这里插入图片描述
显示统计信息
DESC FORMATTED 表名
在这里插入图片描述
也可以通过如下命令显示列统计信息:
DESC FORMATTED 表名 列名

3.2.2 使用 CBO

通过 “spark.sql.cbo.enabled” 来开启,默认是 false。配置开启 CBO 后,CBO 优化器可以基于表和列的统计信息,进行一系列的估算,最终选择出最优的查询计划。在这里插入图片描述
在这里插入图片描述

3.3 广播 Join (大小表join)

Spark join 策略中,如果当一张小表足够小并且可以先缓存到内存中,那么可以使用Broadcast Hash Join,其原理就是先将小表聚合到 driver 端,再广播到各个大表分区中,那么再次进行 join 的时候,就相当于大表的各自分区的数据与小表进行本地 join,从而规避了shuffle
1)通过参数指定自动广播
广播 join 默认值为 10MB,由 spark.sql.autoBroadcastJoinThreshold 参数控制
在这里插入图片描述
2)强行广播
1.关闭广播
在这里插入图片描述
2.强制指定的是广播join和mapjoin
在这里插入图片描述

3.4 SMB Join(大 join 大)

SMB JOIN 是 sort merge bucket 操作,需要进行分桶,首先会进行排序,然后根据 key值合并,把相同 key 的数据放到同一个 bucket 中(按照 key 进行 hash)。分桶的目的其实就是把大表化成小表。相同 key 的数据都在同一个桶中之后,再进行 join 操作,那么在联合的时候就会大幅度的减小无关项的扫描。使用条件:
(1)两表进行分桶,桶的个数必须相等
(2)两边进行 join 时,join 列=排序列=分桶列
如果两个表先不是分桶表,那么先转换成一个分桶表
在这里插入图片描述
满足smb join(将两个非分桶的表转换成分桶表再进行Join)
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大数据学习爱好者

你的鼓励是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值