Spark性能优化一之shuffle性能优化

shuffle操作是spark中唯一最最消耗性能的地方,会产生大量的磁盘IO(因为map task会将数据先写到bucket缓存中,然后溢写到磁盘文件中去,同时如果reduce task的聚合内存不大时也会溢写到磁盘),网络IO(因为会导致大量的数据在不同的节点之间进行传输),内存消耗(map task的bucket缓存,reduce task的拉取缓存,reduce task的聚合内存)
reduce task每次只能拉取指定缓存大小的数据量,拉取完进行聚合处理,聚合的时候在内存聚合(用于reduce端聚合的内存比例,默认0.2,超过比例就会溢出到磁盘上)聚合完然后再次拉取

在Spark中,什么情况下,会发生shuffle?
1、repartition类的操作:比如repartition、repartitionAndSortWithinPartitions、coalesce等
2、byKey类的操作:比如reduceByKey、groupByKey、sortByKey、countByKey等
3、join类的操作:比如join、cogroup等
在这里插入图片描述

我们的任务其实分两种,一种是shuffleMapTask和resultTask,只有最后一个触发action算子的任务是resultTask,其他的都是shuffleMapTask
普通Shuffle操作的原理剖析,spark1.3版本前
在这里插入图片描述
优化后的Shuffle操作的原理剖析,spark1.3版本后
在这里插入图片描述
第一个特点,
在Spark早期版本中,那个bucket缓存是非常非常重要的,因为需要将一个ShuffleMapTask所有的数据都写入bucket缓存之后,才会刷新到磁盘。但是这就有一个问题,如果map side数据过多,那么很容易造成内存溢出。所以spark在新版本中,优化了,默认那个bucket缓存是32kb,然后呢,当数据达到了刷新到磁盘的阈值之后,就会将数据一点一点地刷新到磁盘。
这种操作的优点,是不容易发生内存溢出。缺点在于,如果bucket缓存过小的话,那么可能发生过多的磁盘写io操作。所以,这里的bucket缓存大小,是可以根据实际的业务情况进行优化的。
第二个特点,
与MapReduce完全不一样的是,MapReduce它必须将所有的数据都写入本地磁盘文件以后,才能启动reduce操作,来拉取数据。为什么?因为mapreduce要实现默认的根据key的排序!所以要排序,肯定得写完所有数据,才能排序,然后reduce来拉取。
但是Spark不需要,spark默认情况下,是不会对数据进行排序的。因此ShuffleMapTask每写入一点数据,ResultTask就可以拉取一点数据,然后在本地执行我们定义的聚合函数和算子,进行计算。
spark这种机制的好处在于,速度比mapreduce快多了。但是也有一个问题,mapreduce提供的reduce,是可以处理每个key对应的value上的,很方便。但是spark中,由于这种实时拉取的机制,因此提供不了,直接处理key对应的values的算子,只能通过groupByKey,先shuffle,有一个MapPartitionsRDD,然后用map算子,来处理每个key对应的values。就没有mapreduce的计算模型那么方便。
优化:
new SparkConf().set(“spark.shuffle.consolidateFiles”, “true”)
1.spark.shuffle.consolidateFiles
是否开启shuffle block file的合并,默认为false,设置为true,写磁盘的数量大大减小,此外,result task拉取数据的时候,拉取的磁盘文件也少了,从而磁盘io也减少了,因为只要从每个节点上,拉取cpu core数量的磁盘文件即可。会合并map side输出文件,对于reduce task数量特别的情况下,可以极大减少磁盘IO开销,提升性能
2.spark.reducer.maxSizeInFlight
reduce task的拉取缓存,默认48m,由于每次只能拉取指定缓存大小的数据量,拉取完进行聚合处理,处理完了然后再次拉取,此参数增大后拉取的次数就少了,可增大为96m
3.spark.shuffle.file.buffer
map task的写磁盘缓存,默认32k,增大后溢写到磁盘的次数少了,比如调为64k

4.reduce task拉取磁盘文件的时候可能节点在垃圾回收导致连接不上节点从而导致拉取文件失败或者网络环境出现问题也会导致拉取文件失败
spark.shuffle.io.maxRetries
拉取失败的最大重试次数,默认3次,增大次数,比如60次
5.spark.shuffle.io.retryWait
拉取失败的重试间隔,默认5s,增大,比如60s
因为
在这里插入图片描述
在这里插入图片描述

6.spark.shuffle.memoryFraction
用于reduce端聚合的内存比例,默认0.2,超过比例就会溢出到磁盘上,增大到0.3 0.4
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值