Spark面试题(3)

1.Spark中如何划分Stage?

答:谈到Spark中如何划分Stage,就不得不讲讲Spark中的宽依赖和窄依赖了

                       

宽依赖(图右):父RDD的每个partition会被子RDD的多个partition使用(多对一,涉及到shuffle的那些算子)

窄依赖(图左):父RDD的每个partition只会被子RDD的一个partition使用(一对一)

这里面join算子是个特殊的,他属于宽依赖还是窄依赖取决于是否产生了重新分区(也就是shuffle),有就是宽,没有就是窄。

Stage的划分:首先一个job(也就是一个action),在计算的时候会被划分成为多个stage,一个stage由多个task(等于partition的数量)组成,task又分为shuffleMaptask和result task俩类,shuffleMaptask输出的是shuffle所需要的数据,result task输出的是处理过后的结果集,而Stage的划分也是依据这个shuffle(宽依赖)来分的,如图,DAG的最后一个阶段会为每个结果的partition生成一个ResultTask,即每个Stage里面的Task的数量是由该Stage中最后一个RDD的Partition的数量所决定的!

结论:遇到一个宽依赖就划分一个Stage。

2.spark中cache和persist的区别

作用:俩个都是将RDD缓存起来,这样在之后的使用中都不用于重新计算,可以大大的节省程序的运行时间。

源码解析:

/** Persist this RDD with the default storage level (`MEMORY_ONLY`). */
def cache(): this.type = persist()

由上面可知,cache调用了persist,并且缓存策略是MEMORY_ONLY

/** Persist this RDD with the default storage level (`MEMORY_ONLY`). */
def persist(): this.type = persist(StorageLevel.MEMORY_ONLY)

//persist调用了StorageLevel这是一个缓存策略的方法,在这里可以选取自己合适的缓存策略。


def persist(newLevel: StorageLevel): this.type = {
  // TODO: Handle changes of StorageLevel
  if (storageLevel != StorageLevel.NONE && newLevel != storageLevel) {
    throw new UnsupportedOperationException(
      "Cannot change storage level of an RDD after it was already assigned a level")
  }

object StorageLevel {
  val NONE = new StorageLevel(false, false, false, false)
  val DISK_ONLY = new StorageLevel(true, false, false, false)
  val DISK_ONLY_2 = new StorageLevel(true, false, false, false, 2)
  val MEMORY_ONLY = new StorageLevel(false, true, false, true)
  val MEMORY_ONLY_2 = new StorageLevel(false, true, false, true, 2)
  val MEMORY_ONLY_SER = new StorageLevel(false, true, false, false)
  val MEMORY_ONLY_SER_2 = new StorageLevel(false, true, false, false, 2)
  val MEMORY_AND_DISK = new StorageLevel(true, true, false, true)
  val MEMORY_AND_DISK_2 = new StorageLevel(true, true, false, true, 2)
  val MEMORY_AND_DISK_SER = new StorageLevel(true, true, false, false)
  val MEMORY_AND_DISK_SER_2 = new StorageLevel(true, true, false, false, 2)
  val OFF_HEAP = new StorageLevel(false, false, true, false)
}

由上图可知,persist可以使用多种缓存策略,缓存策略的大致选取:

(1) Cache() MEMEORY_ONLY

(2) MEMORY_ONLY_SER

(3) _2  //表示副本数量

(4) 能使用内存就不使用磁盘

3.面试题暂且放一边了,学生最怕的是代码能力不过关,撸代码去了

猜你喜欢

转载自blog.csdn.net/qq_42064119/article/details/84589860