Spark面试问题
spark面试问题
1、spark中的RDD是什么,有哪些特性
-
RDD(Resilient Distributed Dataset)叫做分布式数据集,是Spark中最基本的数据抽象,它代表一个不可变、可分区、里面的元素可并行计算的集合。
-
Dataset:就是一个集合,用于存放数据的
-
Distributed:分布式,可以并行在集群计算
-
Resilient:表示弹性的
-
弹性表示
-
1、RDD中的数据可以存储在内存或者是磁盘
-
-
*RDD五大特性:
-
A list of partitions 一个分区列表,RDD中的数据都存在一个分区列表里面
-
A function for computing each split 作用在每一个分区中的函数
-
A list of dependencies on other RDDs 一个RDD依赖于其他多个RDD,这个点很重要,RDD的容错机制就是依据这个特性而来的
-
Optionally, a Partitioner for key-value RDDs (e.g. to say that the RDD is hash-partitioned) 可选的,针对于kv类型的RDD才具有这个特性,作用是决定了数据的来源以及数据处理后的去向
-
Optionally, a list of preferred locations to compute each split on (e.g. block locations for an HDFS file) 可选项,数据本地性,数据位置最优
-
2、概述一下spark中的常用算子区别(map、mapPartitions、foreach、foreachPartition)
-
map:用于遍历RDD,将函数f应用于每一个元素,返回新的RDD(transformation算子)。
-
foreach:用于遍历RDD,将函数f应用于每一个元素,无返回值(action算子)。
-
mapPartitions:用于遍历操作RDD中的每一个分区,返回生成一个新的RDD(transformation算子)。
-
foreachPartition: 用于遍历操作RDD中的每一个分区。无返回值(action算子)。
-
总结:一般使用mapPartitions或者foreachPartition算子比map和foreach更加高效,推荐使用。
3、谈谈spark中的宽窄依赖
-
RDD和它依赖的父RDD(s)的关系有两种不同的类型,即窄依赖(narrow dependency)和宽依赖(wide dependency)。
-
宽依赖:指的是多个子RDD的Partition会依赖同一个父RDD的Partition
-
窄依赖:指的是每一个父RDD的Partition最多被子RDD的一个Partition使用。
4、spark中如何划分stage
-
1.Spark Application中可以因为不同的Action触发众多的job,一个Application中可以有很多的job,每个job是由一个或者多个Stage构成的,后面的Stage依赖于前面的Stage,也就是说只有前面依赖的Stage计算完毕后,后面的Stage才会运行。
-
2.Stage划分的依据就是宽依赖,何时产生宽依赖,例如reduceByKey,groupByKey的算子,会导致宽依赖的产生。
-
3.由Action(例如collect)导致了SparkContext.runJob的执行,最终导致了DAGScheduler中的submitJob的执行,其核心是通过发送一个case class JobSubmitted对象给eventProcessLoop。 eventProcessLoop是DAGSchedulerEventProcessLoop的具体实例,而DAGSchedulerEventProcessLoop是eventLoop的子类,具体实现EventLoop的onReceive方法,onReceive方法转过来回调doOnReceive
-
4.在doOnReceive中通过模式匹配的方法把执行路由到
-
5.在handleJobSubmitted中首先创建finalStage,创建finalStage时候会建立父Stage的依赖链条
-
总结:以来是从代码的逻辑层面上来展开说的,可以简单点说:写介绍什么是RDD中的宽窄依赖,然后在根据DAG有向无环图进行划分,从当前job的最后一个算子往前推,遇到宽依赖,那么当前在这个批次中的所有算子操作都划分成一个stage,然后继续按照这种方式在继续往前推,如在遇到宽依赖,又划分成一个stage,一直到最前面的一个算子。最后整个job会被划分成多个stage,而stage之间又存在依赖关系,后面的stage依赖于前面的stage。
5、spark-submit的时候如何引入外部jar包
-
在通过spark-submit提交任务时,可以通过添加配置参数来指定
-
--driver-class-path 外部jar包
-
--jars 外部jar包
-
6、spark 如何防止内存溢出
-
driver端的内存溢出
-
可以增大driver的内存参数:spark.driver.memory (default 1g)
-
这个参数用来设置Driver的内存。在Spark程序中,SparkContext,DAGScheduler都是运行在Driver端的。对应rdd的Stage切分也是在Driver端运行,如果用户自己写的程序有过多的步骤,切分出过多的Stage,这部分信息消耗的是Driver的内存,这个时候就需要调大Driver的内存。
-
-
map过程产生大量对象导致内存溢出
-
这种溢出的原因是在单个map中产生了大量的对象导致的,例如:rdd.map(x=>for(i <-
-