spark使用性能优化记录——二

之前做了记录了spark的一些配置调优,接下来记录一下本人在开发中用到的一些调优手段。

算子调优

MapPartitons提升Map类操作性能

spark中每个task处理一个RDDpartition,一条一条数据--> task function

MapPartitons后所有的数据(一个分区的所有数据)--> task function

优点: 不用一条一条的去处理数据 ,而是直接都处理

缺点:内存不够大的时候一下子处理会出现OOM

实现:预估RDD数量 partition数量分配给executor足够的内存资源使用

 

filter之后减少分区数量

1减少partition filter 之后的partition数据不均匀 ,数据倾斜。

2减少开始的partition数量

3减少filter之后的partition数量——>filter().coalesce(100);

4使用repartition解决Spark SQL低并行度的性能问题

 并行度设置提高性能:conf.set("spark.default.parallelism","500") 指定为core数量的2-3

但是有spark sql的地方是不能设置并行度是,sql会根据hive表对应的hdfs件block自动设置并行度,可能这个并行度严重低于你设置的,这样stage0会远远慢与stage1 阶段

解决方案:将sql查询出来的RDD使用repartition将并行度提高stage0的并行

reduceByKey本地聚合

reducebykey相对比普通的groupbykey 会进行map(每个partition)combiner聚合每一个key对应一个values

减少map端的数据数量磁盘占用量磁盘IO stage1阶段拉取也减少了reduce端的内存占用,聚合数量也减少了。

使用场景:word count、一些复杂的对每个key进行一些字符串的拼接(实现有点难)

减少了shuffle阶段的资源消耗

 

foreachPartition优化写数据库性能

实际生产环境都使用这个   

好处:只需要调用一次function函数,只要创建或获取一个数据库连接就可以,只要向数据库发送一次SQL语句和多组参数即可

坏处:也可能一次数据量特别大的时候,会发生OOM

 

数据倾斜

原理:ruduce阶段 task任务分布不均 shuffle过程产生 OOM 内存溢出

位置:在代码里找(groupbykeycountBykeyreduceBykeyjoin或者查看log发现 定位第几个stage是哪个stage task,定位代码。

解决方案:

聚合源数据:

90%的数据来源是hiveHSQL做离线 ETL 数据采集、清洗、导入)的数据仓库,所以聚合shufflehive离线晚上凌晨直接聚合然后spark就不做这个操作了对每个key聚合 value聚合后期用spark sql 直接查询就行,减少数据量。

过滤导致倾斜的key

放粗粒度聚合,不要聚合那么细。摒弃掉某些倾斜量特别大的key 直接查询获取数据的时候hive表中where过滤掉,直接弃掉某些数据

提高reduce并行度(shuffle阶段)

例如将原本一个task中的任务分配给5task配置的参数增加reducetask调入shuffle操作的时候传入参数数字及 reduce的并行度

上两个方案直接避免数据倾斜,这个是减轻了shuffle reduce task的数据压力,倾斜问题,使用后依旧很慢,只是没有OOM

使用随机key实现双重聚合

打散keymapTopair 加随机数),让其跑去不同的task--局部聚合--反向映射--还原key去新的task上计算

maptopair 打散,reducebykey局部聚合,maptopair还原reducebykey全局聚合

适用:reduceBykey 、groupBykey 场景适用

reduce join 转化为 map join

RDD join RDD

RDD->map-join-broadcast(广播变量)->RDD避免shuffle,避免了数据倾斜

.collect() list --> sc.broadcast(list) --> maptopair 遍历tuple放到map,拼接返回需要的值

适用场景:RDDjoin,一个RDD比较小,一个较大

 

Spark SQL 数据倾斜

解决方案和spark core的一样

 1.聚合数据 同core

  2.过滤导致倾斜的key sqlwhere

  3.提高shuffle并行度,groupByKey(1000) .set("spark.sql.shuffle.partitions","2000") 默认200

 4.双重group by

 5.reduce join 转换为 map join .set("spark.sql/autoBroadcastJoinThreshold","")默认是10485760

6.采样倾斜key单独joinspark core 的方式 sample filter 等算子

7.随机key与扩容表:spark sql + spark core

 

这是我在实际开发中遇到问题使用的一些调优方法,当然spark的调优肯定不止这些,希望能在以后的学习中更进一步,学习更多的知识。

posted @ 2019-01-06 15:33  力扛九鼎  阅读(844)  评论(0编辑  收藏  举报