Spark知识点复习

Spark面试题整理
一、Spark运行模式

(1)Local:运行在一台机器上。测试用。

(2)Standalone:是 Spark 自身的一个调度系统。 对集群性能要求非常高时用。国内很少使用。

(3)Yarn:采用Hadoop的资源调度器。 国内大量使用。

​ Yarn-client模式:Driver运行在Client上(不在AppMaster里)

​ Yarn-cluster模式:Driver在AM上

二、Spark常用端口号

(1)4040 spark-shell任务端口

(2)7077内部通讯端口,类比Hadoop的8020/9000

(3)8080查看任务执行情况端口,类比Hadoop的8088

(4)18080历史服务器,类比Hadoop的19888

由于spark只负责计算,所以并没有Hadoop中存储数据的端口9870/50070

三、RDD五大属性

分区列表:RDD数据结构中存在分区列表,用于执行任务时并行计算,实现分布式计算。
分区计算函数:spark在计算时,使用分区函数对每一个分区进行计算。
RDD之间的依赖关系(RDD是计算模型的封装,当需求中需要将多个计算模型进行组合时,就需要将多个RDD建立依赖关系)。
分区器(可选):当数据为kv类型数据时,可以通过设定分区器自定义数据的分区。
首选位置(可选):计算数据时,可以根据计算节点的状态选择不同的节点位置进行计算。

四、RDD弹性体现在哪里

存储弹性、计算弹性、任务弹性、数据位置弹性

(1)自动进行内存和磁盘切换

(2)基于lineage的高效容错

(3)Task如果失败会特定次数重试

(4)Stage如果失败会自动进行特定次数的重试,而且只会计算失败的分片

TASK:每个分区上执行的计算单元,当一个RDD操作出发,会创建一个任务执行相应计算。
stage:一组具有相同计算逻辑的任务的集合,一个阶段由一系列RDD转换操作所组成,这些操作之间存在宽依赖或窄依赖关系。

(5)checkpoint[每次对RDD操作都会产生新的RDD,如果链条比较长,计算比较笨重,就把数据放在硬盘中]和persist[内存或磁盘中对数据进行复用](检查点、持久化)

(6)数据调度弹性:DAG Task和资源管理无关

(7)数据分片的高度弹性repartion(将RDD重新分区(repartition)以适应数据处理需求,并在此过程中保持高度的弹性,即能够应对节点故障或性能问题而自动进行调整和恢复。)

五、Spark的转换算子

1)单Value

(1)map:将RDD中的每个元素通过一个函数映射为另一个元素,返回一个新的RDD。

(2)mapPartitions :类似于map,但是针对RDD的每个分区进行映射。

(3)mapPartitionsWithIndex :类似于mapPartitions,但是在映射函数中额外提供了分区的索引,可以根据分区索引号进行分区级别的操作。

(4)flatMap :与map类似,但每个输入元素可以被映射为0或多个输出元素,最终将所有输出展开为一个扁平的RDD。

(5)groupBy: 将RDD中的元素按照给定的键进行分组,并返回一个元素为(键,Iterable)元组的RDD,其中每个元组表示一个键和该键对应的所有元素的迭代器。

(6)filter:根据给定的条件函数过滤RDD中的元素,只保留满足条件的元素,返回一个新的RDD。

(7)distinct :去除RDD中重复的元素,返回一个包含唯一元素的新RDD。

(8)coalesce:将RDD的分区数减少到指定的数量,可以在数据减少后对RDD进行重新分区,减少分区数可以提高计算效率。

(9)repartition :将RDD重新分区为指定数量的分区,通常用于增加分区以提高并行度或重新分区以改变数据分布。

(10)sortBy:对RDD中的元素按照指定的排序规则进行排序,并返回一个按照指定顺序排列的新的RDD。

2)双value

(1)intersection :用于计算两个RDD之间的交集,返回一个新的RDD

(2)union :用于合并两个RDD。

(3)subtract: 从第一个RDD中移除与第二个RDD中相同键的键值对,返回一个新的键值对。

(4)zip:用于将两个RDD中的元素,一一对应地进行配对,生成一个新的RDD。会按照元素在各自RDD中的顺序进行匹配,最终返回一个包含元组的新RDD,其中每个元组包含来自两个RDD相同位置的元素。如果两个RDD的分区数不同,则zip操作会将分区数较少的RDD的分区数作为结果RDD的分区数。

3)Key-Value

(1)partitionBy :用于对RDD进行分区,根据指定的分区函数对数据进行重新分区。

(2)reduceByKey :对具有相同键地数据进行合并操作(求和、计数),返回一个新的键值对RDD。

(3)groupByKey :将有相同键的数据进行分区,并返回一个新的键值对RDD。

(4)sortByKey :根据键对数据进行排序,并返回一个新的按键排序后的RDD。

(5)mapValues :对RDD中每个键对应的值应用一个函数,而键保持不变,返回一个新的键值对RDD。

(6)join:用于将两个RDD中具有相同键的数据进行连接操作,返回一个包含键值对的新的RDD。

六、Spark 的行动算子
  1. reduce
    • 对RDD中的元素应用一个指定的函数进行归约操作,返回一个单一的结果。通常用于对RDD中的数据进行求和、求最大/最小值等聚合操作。
  2. collect
    • 将RDD中的所有元素收集到驱动器程序中,并返回一个包含所有元素的数组。注意,如果RDD中的元素量级很大,使用collect可能会导致驱动器程序内存溢出。
  3. count
    • 返回RDD中元素的个数。它不会遍历整个RDD,而是在所有分区上并行计算每个分区中的元素数量,然后将结果汇总。
  4. first
    • 返回RDD中的第一个元素,类似于collect操作,但只返回第一个元素而不是整个RDD。
  5. take
    • 返回RDD中的前n个元素,并将它们收集到一个数组中。与collect不同,take只收集指定数量的元素,因此更适合于大型RDD。
  6. save
    • 用于将RDD中的数据保存到外部存储系统中,如文件系统(HDFS、本地文件系统等)、数据库、或其他支持的存储系统。你可以指定保存的格式和存储位置。
  7. foreach
    • 对RDD中的每个元素应用一个指定的函数,但不返回任何结果。通常用于执行一些副作用操作,比如将数据写入外部系统或进行打印输出。注意,foreach是一个迭代操作,它会在各个执行器上并行地对每个元素应用指定的函数。
七、map和mapPartitions区别

(1)map:每次处理一条数据 (2)mapPartitions:每次处理一个分区数据

八、Repartition 和 Coalesce 区别

1)关系:

两者都是用来改变RDD的partition数量的,repartition底层调用的就是coalesce方法: coalesce(numPartitions, shuffle = true)。

2)区别:

repartition 一定会发生 Shuffle,coalesce 根据传入的参数来判断是否发生Shuffle。

一般情况下增大rdd的partition数量使用repartition,

减少partition数量时使用coalesce。

九、reduceByKey 与 groupByKey 的区别

reduceByKey:具有预聚合操作(优先采用)。 groupByKey:没有预聚合。

十、RDD的血缘和依赖关系:

1)RDD血缘关系:

RDD的lineage会记录RDD的元数据信息和转换行为,当该RDD的部分分区数据丢失时,可以根据信息来重新运算和恢复丢失的数据分区。

2)RDD依赖关系:
两个相邻RDD之间的关系,包括RDD的窄依赖和宽依赖
窄依赖:表示每一个父(上游)RDD的partition最多被子RDD的一个partition使用(独生子女)
宽依赖:表示同一个父RDD的partition被多个子RDD的partition依赖,会引起shuffle

十一、Spark 任务的划分

(1)Application:初始化一个SparkContext 即生成一个Application;

(2)Job:一个Action算子就会生成一个Job;

(3)Stage:Stage 等于宽依赖的个数加1;

Stage是Spark中作业(Job)执行的基本单元,它代表了一系列的并行计算阶段。一个Stage通常由一个或多个转换操作(例如map、filter、reduce等)组成,并且每个阶段都包含了相同类型的计算操作。

  • 加1的目的在于将宽依赖的操作作为一个新的Stage,这样可以确保Shuffle操作在不同的Stage中执行。如果不加1,那么最后一个宽依赖操作将与之前的宽依赖操作合并在同一个Stage中执行,这可能会导致一些性能问题,因为这些操作无法并行执行。因此,为了避免这种情况,Spark将宽依赖的个数加1,确保每个宽依赖操作都作为一个独立的Stage执行,从而提高了作业的并行度和性能。

(4)Task:一个Stage阶段中,最后一个RDD的分区个数就是Task的个数。

Task是在Spark集群中执行的最小工作单位,它代表了对数据的一次计算操作。

​ 最后一个RDD的分区个数就是Task的个数因为Stage中的每个Task都负责处理输入RDD的一个分区,而在一个阶段中,数据已经按照前面的转换操作进行了划分,最后一个RDD的分区个数决定了最终的任务数。每个Task都会独立地在集群中的Executor上执行,处理一个或多个RDD分区的数据。

十二、SparkSQL 中 RDD、DataFrame、DataSet 三者的转换及区别

后期spark版本中,ds可能会逐步取代rdd和df成为唯一的api接口
RDD:不支持sparksql操作
DF:与RDD和DS不同,DF的每一行的类型固定为row,每一列的值没法直接访问,只有通过解析才能获取各个字段得到值
DS:DF其实是一个DS的特例(行的形式)

DataFrame 和 DataSet 的区别:前者是row类型

RDD和DataSet 及DataSet 的区别:前者没有字段和表信息

十三、Hive on Spark和Spark on Hive区别

Hive on spark 元数据为mysql 采用RDD作为执行引擎,语法为HQL,生态完善。

Spark on Hive(spark sql) 元数据为mysql 采用ds\df作为执行引擎 语法为Spark Sql,生态有欠缺

十四、YarnCluster模式提交流程

1)脚本执行启动spark-submit解析参数、创建客户端client

2)客户端向resourceManager注册任务,申请启动AM

3)resourceManager找一个Nodemanager申请一个容器(container)用来启动AM

4)AM在container中启动driver

5)AM向RM申请计算资源,RM把资源列表发送给AM

7)AM通知NM启动excutor

8)excutor向Driver反向注册,申请计算任务

9)提交task到excutor中执行

10)执行完成后,AM注销自己并释放资源

十五、Stage任务划分

1、从main进入,会初始化生成一个Application应用。
2、执行代码到第一个Action行动算子,会形成一个Job。
3、Job会启动DAGScheduler,对job切分stage,stage产生task

DAGScheduler 根据宽依赖做Stage划分; 根据分区数做Task划分

十六、spark shuffle流程

(1)SortShuffle:减少了小文件。 中间落盘应该是本地磁盘 生成的文件数=Task数量*2

在溢写磁盘前,先根据key进行排序,排序过后的数据,会分批写入到磁盘文件中。默 认批次为10000条,数据会以每批一万条写入到磁盘文件。写入磁盘文件通过缓冲区溢写的 方式,每次溢写都会产生一个磁盘文件,也就是说一个Task过程会产生多个临时文件。最 后在每个Task中,将所有的临时文件合并,这就是merge过程,此过程将所有临时文件读取出来,一次写入到最终文件。

(2)bypassShuffle:减少了小文件,不排序,效率高。在不需要排序的场景使用。

十七、Spark统一内存模型

系统内存 = 可用内存 + 预留内存(默认300M,保障留出足够的空间)

可用内存 = 统一内存(默认60%) + 其它(默认40%,用户定义的数据结构或spark内部元数据)

统一内存 = storage内存(用于缓存数据) + execution内存(用于缓存在执行shuffle过程中产生的中间数据)(默认各占50%,具有动态占用机制,若己方内存不足对方充足可以占用对方,storage占用的可以被收回,execution占用的不可能被淘汰)

十八、Spark为什么比MR快

1)内存、硬盘

MR在Map阶段会在溢写阶段将中间结果频繁的写入磁盘,在Reduce阶段再从磁盘拉取数据。频繁的磁盘IO消耗大量时间。

Spark不需要将计算的中间结果写入磁盘,得益于Spark的RDD,在各个RDD的分区中,各自处理自己的中间结果即可,迭代计算时,优势更为明显。

2)Spark DAG任务划分减少了不必要的shuffle

(1)对MR来说,每一个Job的结果都会落地到磁盘。后续依赖于此job结果的job,再从磁盘中读取数据再进行计算。

(2)对Spark来说,每一个Job的结果都可以保存到内存中,配合Spark的缓存机制,减少了不必要的shuffle。

3)资源申请粒度:进程和线程

开启和调用进程的代价一般情况下大于线程

(1)MR任务以进程的方式运行在Yarn集群中,N个MapTask就要申请N个进程。

(2)Spark的任务是以线程的方式运行在进程中,N个MapTask就要申请N个线程。

十九、Spark Shuffle和Hadoop Shuffle的区别

(1)Hadoop不用等所有的MapTask都结束后开启ReduceTask,Spark必须等到父Stage都完成,才能去Fetch数据。

(2)Hadoop的Shuffle是必须排序的,那么不管是Map的输出,还是Reduce的输出,都是分区内有序的。而Spark不要求这一点。

二十、Spark任务使用shell脚本进行提交,海豚调度器可以通过页面提交spark任务。
二十一、请列举会引起shuffle的spark算子,能简述功能。

(2)reduceByKey :对具有相同键地数据进行合并操作(求和、计数),返回一个新的键值对RDD,有预聚合。

(3)groupByKey :将有相同键的数据进行分区,并返回一个新的键值对RDD。

reduceByKey

groupByKey


repartition 一定会发生 Shuffle,coalesce 根据传入的参数来判断是否发生Shuffle。

一般情况下增大rdd的partition数量使用repartition,

减少partition数量时使用coalesce。

二十二、Spark 操作数据库时,如何减少Spark运行中的数据库连接数?

使用foreachPartition 代替 foreach,在 foreachPartition 内获取数据库的连接。

当使用foreach操作时,Spark会为每个数据分区创建一个任务,并在每个任务内部逐个处理分区中的元素。每个元素都会创建一个数据库连接,这样可能会导致数据库连接数过多,对数据库和Spark集群都会造成压力。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值