Spark的性能调优实际上是由很多部分组成,不是调节几个参数就可以立竿见影的,我们需要根据不同的业务情况以及数据情况,对Spark作业进行综合性的分析,然后进行多方面的调节和优化才能获得最佳性能。
一、开发调优
概述
Spark性能优化的第一步,就是要在开发Spark作业的过程中注意和应用一些性能优化的基本原则。开发调优,就是要让大家了解以下一些Spark基本开发原则,包括:RDD lineage设计、算子的合理使用、特殊操作的优化等。在开发过程中,时时刻刻都应该注意以上原则,并将这些原则根据具体的业务以及实际的应用场景,灵活地运用到自己的Spark作业中。
原则一:避免创建重复的RDD
我们在开发一个Spark作业时,首先是基于某个数据源(比如Hive表或HDFS文件)创建一个初始的RDD;接着对这个RDD进行某个算子操作,然后得到下一个RDD;以此类推,循环往复,直到计算出我们想要的结果。在这个过程中,多个RDD会通过不同的算子操作串起来,这个RDD串就是RDD lineage,也即是RDD的血缘关系链。
我们在开发中应该注意:对于同一份数据,只应该创建一个RDD,不能创建多个RDD来代表同一份数据。一个简单的例子:
// 需要对名为“hello.txt”的HDFS文件进行一次map操作,再进行一次reduce操作。也就是说,需要 对一份数据执行两次算子操作。
//错误的做法:对于同一份数据执行多次算子操作时,创建多个RDD//这里执行了两次textFile方法,针对同一个HDFS文件,创建了两个RDD出来,然后分别对每个RDD都执行了一个算子操作。
//这种情况下,Spark需要从HDFS上两次加载hello.txt文件的内容,并创建两个单独的RDD;第二次加载HDFS文件以及创建RDD的性能开销,很明显是白白浪费掉的。
val rdd1=sc.textFile("hdfs://192.168.0.1:9000/hello.txt")
rdd1.map(...)
val rdd2=sc.textFile("hdfs://192.168.0.1:9000/hello.txt")
rdd2.reduce(...)