您的位置:首页 > 其它

第24课:彻底解密Shuffle是如何成为Spark性能杀手的及调优点思考

2017-05-20 16:34 344 查看
第24课:彻底解密Shuffle是如何成为Spark性能杀手的及调优点思考

人们对于Spark的第一印象是往往是Spark基于内存进行计算。但从实质上讲,Spark基于内存进行计算,也可以基于磁盘进行计算,或者基于第三方的存储空间进行计算。背后两层含义:1,Spark架构框架的实现模式是倾向于在内存中计算数据的,可以从Storage、算法、库的不同方式看出来。2,我们要计算数据的时候,数据就在内存中。Shuffle和Spark完全基于内存的计算愿景是相违背的,Shuffle就变成了Spark的性能杀手,从现在的计算机硬件和软件的发展水平来看,这个是不可抗拒的。
Shuffle 不可以避免是因为在分布式系统中把一个很大的的任务/作业分成一百份或者是一千份文件,这一百份或一千份文件在不同的机器上独自完成各自不同的部份,完成之后针对整个作业要结果,在后面进行汇聚,从前一阶段到后一阶段及网络传输的过程就叫 Shuffle。
在 Spark 中为了完成 Shuffle 的过程会把一个作业划分为不同的Stage,这个Stage 的划分是跟据依赖关系去决定的,Shuffle 是整个 Spark 中最消耗性能的地方。大家想一下,如果没有Shuffle,Spark几乎可以完成一个纯内存的操作,因为不需要网络传输,又有迭代的概念,那数据每次在内存中计算,如内存不够也可以每次算一点,完成纯内存的操作。
那Shuffle如何破坏了这一点?因为在不同机器不同节点上我们要进行数据传输,例如reduceByKey,它会把每个Key对应的Value聚合成一个 value,然后生成新的 RDD。下游Stage的Task拿到上一个Stage相同的key,然后进行Value的reduce操作,这里分为Map端的reduce,和Reducer端的reduce。数据在通过网络发送之前,要先存储在内存中,内存达到一定的程度,它会写到本地磁盘,(在以前 Spark 的版本没有Buffer 的限制,会不断地写入Buffer,内存满了就写入本地文件,Buffer 没有限制有个很大的弊端,容易出现OOM,但有个好处,例如以前的版本可以使用48G的内存,可以减少IO操作;现在的Spark版本对 Buffer大小设定了限制,例如限制Buffer为48K,48K刷新一次Buffer,以防止出现 OOM。每一个版本的变化都有原因,不能简单的说好还是不好。)Mapper 端写入内存 Buffer,这个关乎到 GC 的问题,然后 Mapper端的 Block 要写入本地磁盘文件,Spark 以前版本实现的时候曾经只要RDD存在,本地的临时文件并不会被删除掉,这个好处是计算到一半或者95%的时候可以复用Mapper端本地磁盘的数据;但这个不好的地方就是一直在运行,例如流处理程序运行了5天的时间,缓存越来越大,最终造成系统崩溃。
Spark一再鼓励数据就在内存中,我们就在内存中计算数据,但Spark是分布式的,不可避免的要进行网络传输,不可避免的进行内存与磁盘IO的操作,以及磁盘IO与网络IO的操作, 大量的磁盘与IO的操作和磁盘与网络IO的操作,这就构成了分布式的性能杀手。
如果要对最终计算结果进行排序,一般都会进行sortByKey,如果以最终结果来思考,可以认为是产生了一个很大很大的 partition,例如使用reduceByKey 的时候指定它的并行度,把reduceByKey 的并行度变成为1,数据切片就变成1,从理论上讲排序一般都会牵涉很多节点,如果把很多节点变成一个节点然后进行排序,有时候会取得更好的效果,因为数据就在一个节点上,就依靠一个进程进行排序。以前的一个项目就用到这一点:reduceByKey之后变成1个数据分片,然后进行mapPartitions,reduceByKey是Key-Value的方式,对于Key值业务清楚其内容,mapPartitions这里就是一个Partition,Partition内部可以按照Key进行比较,按照业务需要进行排序。还有另外一种算子repartitionAndSortWithinPartitions,在Partitions的过程中进行Sort排序。SortByKey默认是全局级别的,我们还是使用reduceByKey 的时候指定它的并行度,把reduceByKey 的并行度变成为1,这也是全局级别的。
Shuffle还有一个很危险的地方就是数据倾斜,例如一个ReduceTask抓一部分数据,另一个ReduceTask抓一部分数据,Key的分发时可能第一个节点处理了99%的数据,第二个节点、第三个节点处理了1%的数据。什么时候会导致数据倾斜? Shuffle 的时候会导致数据倾斜。读者可能会问,在计算的时候可能有些节点数据特别多,这个根本不用担心,有2个层面:1,Spark 的数据一般来源于Hdfs,Hdfs自动分配的数据尽可能的均匀分配。即使原始数据有数据倾斜,就算百亿级别的数据量计算也是很快的,Spark就很擅长在本地节点计算,很凸显Spark计算性能的地方。2,但是Shuffle产生的数据倾斜,就需向上帝祈祷了。能否彻底的掌握Shuffle及Shuffle中数据倾斜的所有内容是判断一个Spark高手的最直接的方式。
Shuffle数据倾斜的问题会牵扯很多其他问题,比如,网络带宽、各种硬件故障、内存消耗OOM、文件掉失。因为 Shuffle 的过程中会产生大量的磁盘 IO、网络 IO、以及压缩、解压缩、序列化和反序列化等等。
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐