数据的本地性
数据本地性的意思就是尽量的避免数据在网络上的传输。Hadoop的MR之所以慢,频繁的读写HDFS是原因之一,为了解决这个问题,Spark将数据都放在了内存中(当然这是理想的情况,当内存不够用时数据仍然需要写到文件系统中)。
但是如果数据需要在网络上传输,也会导致大量的延时和开销,毕竟disk IO和network IO都是集群的昂贵资源。
数据本地性是尽量将计算移到数据所在的节点上进行。毕竟移动计算要比移动数据所占的网络资源要少得多。而且,由于Spark的延时调度机制,使得Spark可以在更大的程度上去做优化。比如,拥有数据的节点当前正被其他的task占用,那么这种情况是否需要将数据移动到其他的空闲节点呢?答案是不一定。因为如果预测当前节点结束当前任务的时间要比移动数据的时间还要少,那么调度会等待,直到当前节点可用。
文件系统本地性:计算任务最好在离数据最近的节点上,计算和数据最好在一台机器上
内存本地性:数据已经加载到内存中,那么,计算任务最好能够直接访问内存,即计算任务发生在内存所在的机器上
Spark程序调试注意的问题:
package spark.examples.shuffle
import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.SparkContext._
object SparkWordCountHashShuffle {
def main(args: Array[String]) {
System.setProperty("hadoop.home.dir", "E:\\devsoftware\\hadoop-2.5.2\\hadoop-2.5.2");
val conf = new SparkConf()
conf.setAppName("SparkWordCount")
// conf.setMaster("local[3]")
conf.setMaster("local") //不加[3]则给ResultTask添加断点时,会挂住断点3次,方便调试;加上,则只挂住一次
conf.set("spark.shuffle.manager", "hash");
val sc = new SparkContext(conf)
val rdd = sc.textFile("file:///D:/word.in.3",4);
val rdd1 = rdd.flatMap(_.split(" "))
val rdd2 = rdd1.map((_, 1))
val rdd3 = rdd2.reduceByKey(_ + _, 3);
rdd3.saveAsTextFile("file:///D:/wordout" + System.currentTimeMillis());
println(rdd3.toDebugString)
sc.stop
}
}
使用conf.setMaster("local[3]"),则ResultTask的runTask方法只会挂住一次,而使用conf.setMaster("local")则断点会挂住3次