spark高频面试题

一、 spark的运行流程?

具体运行流程如下:

  • 当一个spark任务提交的时候,根据提交参数创建驱动进程(driver),驱动器根据参数创建SparkContext对象,即Spark运行环境。SparkContext启动构建DAGScheduler(把DAGT图分解成stage)和TaskScheduler(提交和监控Task)两个调度模块
  • SparkContext 向资源管理器注册并向资源管理器申请运行 Executor
  • 资源管理器分配并启动执行器(executor)
  • executor发送心跳至资源管理器
  • SparkContext 构建 DAG 有向无环图
  • 将 DAG 分解成 Stage(TaskSet)
  • 把 Stage 发送给 TaskScheduler
  • Executor 向 SparkContext 申请 Task
  • TaskScheduler 将 Task 发送给执行器(executor) 运行
  • Task 在 Executor 上运行,运行完毕释放所有资源

二、Spark 有哪些组件?

  1. clusterManager(集群管理器):管理集群和节点,不参与计算。
  2. worker(工作节点):计算节点,进程本身不参与计算,和 master 汇报。
  3. Driver(驱动器):运行程序的 main 方法,创建 spark context 对象。
  4. spark context:控制整个 application 的生命周期,包括 DAGScheduler 和 TaskScheduler 等组件。
  5. client:用户提交程序的入口。
  6. DAGScheduler 负责 stage 级的调度,主要是将 DAG 切分成多个 stage,并将 stage 打包成 TaskSet 交给 TaskScheduler;
  7. TaskScheduler 负责 task 级的调度,将 DAGScheduler 发过来的 TaskSet 按照指定的调度策略发送给 Executor;
  8. job(作业):以 action 方法为界,一个 action 触发一个 job
  9. stage(阶段):它是 job 的子集,以rdd宽依赖为界,遇到宽依赖即划分stage
  10. task(任务):它是 stage 的子集,以分区数来衡量,分区数多少,task 就有多少
  11. TaskSet:一组关联的,相互之间没有shuffle依赖关系的任务组成的任务集。

三. Spark 中的 RDD 机制理解吗?

RDD 是 spark 提供的核心抽象,全称为弹性分布式数据集。

RDD 在逻辑上是一个 hdfs 文件,是一种元素集合,它是被分区的,每个分区分布在集群中的不同结点上,从而让 RDD 中的数据可以被并行操作(分布式数据集)

RDD 的数据默认存放在内存中,但是当内存资源不足时,spark 会自动将 RDD 数据写入磁盘。RDD 的弹性体现在于 RDD 自动进行内存和磁盘之间权衡和切换的机制。

RDD 最重要的特性就是容错性,可以自动从节点失败中恢复过来。即如果某个结点上的 RDD partition 因为节点故障,导致数据丢失,那么 RDD可以通过自己的数据来源重新计算该 partition。这一切对使用者都是透明的。

四、RDD的操作分类

  • 转换(transformations) :从已经存在的数据集中创建一个新的数据集,会创建一个新的RDD,例如map操作,会把数据集的每个元素传给函数处理,并生成一个新的RDD,常见如:Map,Filter,FlatMap,GroupByKey,ReduceByKey,Join,Sort,PartionBy
  • 动作(actions) :在数据集上进行计算之后返回一个值到驱动程序,例如reduce动作,使用函数聚合RDD所有元素,并将结果返回给驱动程序,常见有:Collect,Reduce,Save,Lookup

五、如何区分 RDD 的宽窄依赖?为什么要设计宽窄依赖?

窄依赖:父 RDD 的一个分区只会被子 RDD 的一个分区依赖;

宽依赖:父 RDD 的一个分区会被子 RDD 的多个分区依赖(涉及到 shuffle)

对于窄依赖: 窄依赖的多个分区可以并行计算; 窄依赖的一个分区的数据如果丢失只需要重新计算对应的分区的数据就可以了。

对于宽依赖: 划分 Stage(阶段)的依据:对于宽依赖,必须等到上一阶段计算完成才能计算下一阶段。

六、RDD 持久化原理?

spark 非常重要的一个功能特性就是可以将 RDD 持久化在内存中。

调用 cache()和 persist()方法即可。cache()和 persist()的区别在于,cache()是 persist()的一种简化方式,cache()的底层就是调用 persist()的无参版本 persist(MEMORY_ONLY),将数据持久化到内存中。

如果需要从内存中清除缓存,可以使用 unpersist()方法。RDD 持久化是可以手动选择不同的策略的。在调用 persist()时传入对应的 StorageLevel 即可。

七、Checkpoint 检查点机制?

checkpoint是安全可靠、不保留RDD血统的持久化方式,checkpoint 的数据通常是保存在高可用的文件系统中,比如 HDFS 中,所以数据丢失可能性比较低,Checkpoint 首先会调用 SparkContext 的 setCheckPointDIR()方法,设置一个容错的文件系统的目录,比如说 HDFS;然后对 RDD 调用 checkpoint()方法。之后在 RDD 所处的 job 运行结束之后,会启动一个单独的 job,来将 checkpoint 过的 RDD 数据写入之前设置的文件系统,进行高可用、容错的类持久化操作。

八、Checkpoint 和持久化机制的区别?

最主要的区别在于持久化只是将数据保存在 BlockManager 中,但是 RDD 的 lineage(血缘关系,依赖关系)是不变的。但是 checkpoint 执行完之后,rdd 已经没有之前所谓的依赖 rdd 了,而只有一个强行为其设置的 checkpointRDD,checkpoint 之后 rdd 的 lineage 就改变了。

持久化的数据丢失的可能性更大,因为节点的故障会导致磁盘、内存的数据丢失。但是 checkpoint 的数据通常是保存在高可用的文件系统中,比如 HDFS 中,所以数据丢失可能性比较低

spark高频面试题_第1张图片

 九、reduceBykey与groupByKey属于转换操作还是行动操作?哪个性能好?

都属于转换操作

reduceByKey:reduceByKey会在结果发送至reducer之前会对每个mapper在本地进行merge,有点类似于在MapReduce中的combiner。这样做的好处在于,在map端进行一次reduce之后,数据量会大幅度减小,从而减小传输,保证reduce端能够更快的进行结果计算。

groupByKey:groupByKey会对每一个RDD中的value值进行聚合形成一个序列(Iterator),此操作发生在reduce端,所以势必会将所有的数据通过网络进行传输,造成不必要的浪费。同时如果数据量十分大,可能还会造成OutOfMemoryError。

所以在进行大量数据的reduce操作时候建议使用reduceByKey。不仅可以提高速度,还可以防止使用groupByKey造成的内存溢出问

十. Spark SQL 是如何将数据写到 Hive 表的?

  • 方式一:是利用 Spark RDD 的 API 将数据写入 hdfs 形成 hdfs 文件,之后再将 hdfs 文件和 hive 表做加载映射。
  • 方式二:利用 Spark SQL 将获取的数据 RDD 转换成 DataFrame,再将 DataFrame 写成缓存表,最后利用 Spark SQL 直接插入 hive 表中。而对于利用 Spark SQL 写 hive 表官方有两种常见的 API,第一种是利用 JavaBean 做映射,第二种是利用 StructType 创建 Schema 做映射。

十一、Spark RDD转换成DataFrame的两种方式

DataFrame=RDD+Schema 。 它其实和关系型数据库中的表非常类似,RDD可以认为是表中的数据,Schema是表结构信息。

spark官方提供了两种方法实现从RDD转换到DataFrame。

  • 第一种方法是利用反射机制来推断包含特定类型对象的Schema,这种方式适用于对已知的数据结构的RDD转换;
  •  第二种方法通过编程接口构造一个 Schema ,并将其应用在已知的RDD数据中。

Spark RDD转换成DataFrame的两种方式_李大寶的博客-CSDN博客

十二. DAG 是什么?

DAG(Directed Acyclic Graph 有向无环图)指的是数据转换执行的过程,有方向,无闭环(其实就是 RDD 执行的流程); 原始的 RDD 通过一系列的转换操作就形成了 DAG 有向无环图,任务执行时,可以按照 DAG 的描述,执行真正的计算(数据被操作的一个过程)。

十三. 说是Spark特点,相对于MR来说

  • 减少磁盘I/O:MR 会把map端中间结果输出和结果存储在磁盘中,reduce端又需要从磁盘读取中间结果,造成磁盘I/O瓶颈,而Spark允许将map端的中间输出和结果存储在内存中,reduce从中间结果拉取,避免了大量的磁盘I/O
  • 增加并行度 :由于把中间结果写入磁盘与从磁盘读取中间结果属于不同的环境,hadoop简单的通过串行执行链接起来,而Spark则把不同的环节抽象成Stage,允许多个Stage既可以串行又可以并行执行
  • MapReduce 默认是排序的,spark 默认不排序,除非使用 sortByKey 算子。

十四、哪些Spark算子会有shuffle过程

  • 去重:distinct
  • 排序:groupByKey ,reduceByKey
  • 重分区:repartition
  • 集合或者表连接操作:join

我们应该尽量避免上面算子的操作,应该尽量使用map类算子

十五、Spark sql执行一定比Hive快吗

Spark SQL 比 Hadoop Hive 快,是有一定条件的,而且不是 Spark SQL 的引擎比 Hive 的引擎快,相反,Hive 的 HQL 引擎还比 Spark SQL 的引擎更快。其实,关键还是在于 Spark 本身快。

消除了冗余的 HDFS 读写: Hadoop 每次 shuffle 操作后,必须写到磁盘,而 Spark 在 shuffle 后不一定落盘,可以 cache 到内存中,以便迭代时使用。如果操作复杂,很多的 shufle 操作,那么 Hadoop 的读写 IO 时间会大大增加,也是 Hive 更慢的主要原因了。 消除了冗余的 MapReduce 阶段: Hadoop 的 shuffle 操作一定连着完整的 MapReduce 操作,冗余繁琐。而 Spark 基于 RDD 提供了丰富的算子操作,且 reduce 操作产生 shuffle 数据,可以缓存在内存中。 JVM 的优化: Hadoop 每次 MapReduce 操作,启动一个 Task 便会启动一次 JVM,基于进程的操作。而 Spark 每次 MapReduce 操作是基于线程的,只在启动 Executor 是启动一次 JVM,内存的 Task 操作是在线程复用的。每次启动 JVM 的时间可能就需要几秒甚至十几秒,那么当 Task 多了,这个时间 Hadoop 不知道比 Spark 慢了多少。

你可能感兴趣的:(大数据,面试题,spark,大数据,分布式)