Spark面试题总结

发布于:2024-07-02 ⋅ 阅读:(11) ⋅ 点赞:(0)

一、RDD的五大特性是什么

1、RDD是由一些分区构成的,读取文件时有多少个block块,RDD中就会有多少个分区
2、算子实际上是作用在RDD中的分区上的,一个分区是由一个task处理,有多少个分区,总共就有多少个task
3、RDD之间存在依赖关系,后一个RDD中的数据是依赖与前一个RDD的计算结果,数据会像水流一样在RDD之间流动
4、分区类的算子只能作用在键值对格式的RDD上,groupByKey、reduceByKey
5、spark为task计算提供了精确的计算位置,移动计算而不移动数据

二、Spark常用算子

转换算子:
map(func):对RDD中的每个元素应用一个函数,返回一个新的RDD。
filter(func):根据给定的条件筛选RDD中的元素,返回一个新的RDD。
flatMap(func):类似于Map,但每个输入元素可以映射到多个输出元素,返回一个扁平化的新RDD。
distinct():去除RDD中的重复元素,返回一个新的RDD。
union(otherRDD):将两个RDD合并成一个新的RDD。
intersection(otherRDD):返回两个RDD的交集。
subtract(otherRDD):返回两个RDD的差集。
groupByKey():将RDD中的元素按键分组,生成(键,值列表)对的RDD。
reduceByKey(func):对具有相同键的元素执行reduce操作。
sortByKey():根据键对RDD进行排序。

行动算子:
collect():将RDD中的所有元素收集到驱动程序节点,以数组的形式返回。
count():返回RDD中元素的数量。
first():返回RDD中的第一个元素。
take(n):返回RDD中的前n个元素。
saveAsTextFile:将结果输出到外部存储系统

三、reduceByKey和groupByKey的区别

groupByKey:根据键对RDD中的元素进行分组,但不执行聚合操作
reduceByKey:会根据键将元素进行分组并聚合,并且会在map端做预聚合

四、Spark部署方式

--loacl(本地模式)
主要用于本地开发程序与测试。

--Standalone(独立集群模式)
在此种方式下,Spark自带完整的资源调度管理服务,无需依赖任何其他的资源管理系统。
部署模式:分为client模式和cluster模式

--YARN模式(Spark on YARN)
把Spark作为一个客户端,将作业提交给YARN调度执行
有yarn-client和yarn-cluster两种模式
主要区别在于:
yarn-client模式:Driver在本地启动,在本地可以看到详细日志
yarn-cluster模式:YARN会在集群中选择一台机器来启动Driver进程,在本地看不到详细日志

五、介绍一下Spark中的RDD持久化

--RDD持久化的适用场景
Spark基于内存进行计算,如果某个中间计算结果会被重复使用,我们可以使用RDD持久化将中间结果存储在内存中或磁盘上,避免重复计算,从而提高程序的运行效率。

--RDD持久化的实现方式
1、cache()方法:将数据持久化到内存中。
2、persist()方法:允许用户指定存储级别,包括内存、磁盘、序列化等不同的选项。

--存储级别
MEMORY_ONLY:只将数据存储在内存中,适用于数据量较小且内存资源充足的情况。  --通常使用
MEMORY_ONLY_SER:将数据以序列化的形式存储在内存中,适用于数据量较大但内存资源有限的情况。
MEMORY_AND_DISK:优先将数据存储在内存中,如果内存不足则存储在磁盘上。  ----通常使用
MEMORY_AND_DISK_SER:与MEMORY_AND_DISK类似,但数据以序列化的形式存储。
DISK_ONLY:只将数据存储在磁盘上,适用于数据量非常大且无法完全放入内存的情况。
OFF_HEAP:将数据存储在堆外内存中,适用于对内存管理有特殊要求的场景。

六、Spark中的shuffle是什么?

1、spark的运行过程中如果出现了相同的键被拉取到对应的分区,这个过程称之为shuffle。
2、只有Key-Value型的RDD才会有Shuffle操作,例如reduceByKey、groupByKey。
3、具体来说宽依赖的划分会产生shuffle

七、RDD是什么?

RDD:弹性分布式数据集,是Spark提供的一个面向数据集的分布式内存计算模型,RDD支持内存计算,并可以在多个节点上并行操作数据

八、Spark RDD宽窄依赖是什么?

--窄依赖
父RDD的每个分区仅被一个子RDD的对应分区所使用的情况。

--宽依赖
父RDD的一个或多个分区被多个子RDD的分区所使用的情况。宽依赖的划分会产生shuffle,如groupByKey、reduceByKey等需要数据重新分区的操作。

九、spark资源调度+任务调度

--资源调度
1、Driver向集群申请资源启动Executor
2、Executor启动后,会向Driver反向注册,报告自己的资源信息(如内存和CPU使用情况)
3、Driver根据Executor的资源信息和任务需求,将任务分发给相应的Executor执行。
4、当所有任务执行完毕后,Executor进程停止,释放所占用的内存和CPU资源。


--任务调度(spark作业提交流程)
1、在提交节点上会启动Driver进程,Driver会启动SparkContext。
2、SparkContext在接收到用户程序后,会解析程序中的RDD操作构建DAG有向无环图
3、DAGScheduler根据宽窄依赖将DAG有向无环图划分一个一个Stage,每个Stage中包含了一个或多个Task,Task的数量取决于RDD的Partition个数。
4、TaskScheduler将Task以TaskSet的形式分发给Executor执行。
5、当所有Task执行完毕后,Task的执行结果会返回给Driver进程,Spark会释放所有占用的资源,并通知资源管理器作业已完成。


--重试机制:
TaskScheduler监控每个Task的执行情况,如果Task执行失败,会尝试重新提交(默认重试3次)。
如果某个Stage的所有Task都失败,DAGScheduler会重新提交该Stage(默认重试4次)。

十、spark唯一一次(ECO)怎么保证

1、开启checkpoint支持
2、数据源可以采用kafka(Kafka支持幂等性和事务,为Spark Streaming提供了实现Exactly Once语义的基础)

十二、Spark的内存模型?

Spark的内存模型是基于分布式内存计算的,主要包括两个组件:Driver和Executor。

--Driver
Driver节点负责将应用程序转化为任务并将其分配给Executor执行。Driver节点包含了应用程序的整个代码以及数据集的元数据,也会保存一部分数据在内存中。

--Executor
Executor是Spark执行任务计算的节点。每个Executor运行在一个独立的JVM进程中,它们通过网络与Driver进行通信。Executor会将数据存在在内存中RDD或DataFrame中。

十三、Spark分哪几个部分(模块)

--Spark Core
Spark的核心组件,提供了弹性分布式数据集rdd以及程序入口SparkContext,主要用于处理非结构化数据和半结构化数据

--Spark SQL
Spark用于处理结构化数据的模块,引入DataFrame的概念和程序入口SparkSession

--Spark Streaming
spark对数据进行实时处理的模块(实际上是微批处理,做不到真正的实时,准确来说是近实时)

--Spark MLlib(提供常见机器学习功能的库)
--Spark GraphX(用于图计算的模块)

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

1、groupByKey:将具有相同键的键值对分组到一起,必须进行shuffle以重新分配数据到不同的分区。
2、reduceByKey:对具有相同键的键值对进行聚合操作,需要将具有相同键的数据重新分配到不同的分区。
3、sortByKey:按照键对数据进行排序,需要将数据重新分区以进行排序。
4、join:将两个具有相同键的数据集进行连接操作,需要将具有相同键的数据重新分配到不同的分区。
5、distinct:去除数据集中的重复元素,需要对元素进行重新分区以进行重复元素的合并。

十五、Spark Executor内存分配?

Spark Executor内存分配主要涉及到两个参数:driver-memory和executor-memory。
--driver-memory
驱动程序运行时可用的内存量,它决定了Spark应用程序驱动程序在集群中的可用内存大小

--executor-memory
每个Executor可用的内存量,它决定了每个Executor可以用来执行任务的内存大小

十六、广播变量和累加器

--广播变量
广播变量通过Spark的SparkContext.broadcast()方法创建,如果数据集比较大或需要频繁访问某个数据集时,可以将该数据集广播到executor中,提高Spark作业的性能。

--累加器
通过累加器,executor可以将中间结果或统计信息直接发送到driver端,可以提高Spark作业的性能。

十七、介绍一下Spark DAGScheduler、TaskScheduler、SchedulerBackend?

--DAGScheduler(有向无环图调度器)
它通过分析Spark作业的RDD依赖关系生成一个有向无环图,并将作业划分为多个Stage。然后,DAGScheduler根据Stage的依赖关系和数据本地性进行任务调度。它佳能任务添加到任务队列中,并在有空闲Executor时将任务发送给它们。

--TaskScheduler(任务调度器)
它根据调度策略(如FIFO、FAIR等)从任务队列中选择任务,并将其分发给可用的Executor。TaskScheduler会监控任务的执行状态,如果任务失败,它会尝试重新执行或标记任务为失败。它还会定期检查Executor的健康状态,并根据需要添加或删除Executor。

--SchedulerBackend(调度器后端)
它负责与特定的集群管理器交互,并负责资源的管理和任务的分配。SchedulerBackend会向集群管理器申请资源,并在资源可用时将其分配给Spark应用程序。它还会监控和管理Executor的状态,并在需要时重新申请资源。

十八、spark中如果发生数据倾斜该怎么处理?

1、当Spark作业的数据来源是Hive表,在Hive表中对数据进行预处理,例如按照key进行分组,将同一key对应的所有value用一种特殊的格式拼接到一个字符串里,这样在Spark中处理时就可以避免shuffle操作,从根源上减少了数据倾斜的可能性。
2、当倾斜的key很少且不重要时,可以过滤导致倾斜的key
3、增加shuffle分区的数量(调整spark.sql.shuffle.partitions参数),使数据更加均匀地分布到各个节点
4、对于聚合操作产生的数据倾斜,可以使用局部聚合+全局聚合的方式(首先给每个key打上随机数前缀并进行局部聚合,然后去除前缀进行全局聚合)
5、给每个key添加随机前缀,使数据分布更加均匀

十九、你知道哪些spark的优化方案?

--优化RDD操作
1、对多次使用的RDD进行缓存或持久化,减少重复计算
2、数据倾斜处理:使用随机前缀或哈希分区等方法来均衡数据分布,避免某些节点负载过重
3、将reduce join转为map join:当join操作的一个RDD或表比较小时,可以将其广播到所有节点,在map阶段进行join操作,避免shuffle过程。

--参数调优
1、设置合理的并行度:根据集群资源情况,调整RDD的分区数,以充分利用集群的计算能力
2、优化资源量设置:通过spark-submit提交参数或配置文件,合理设置Driver和Executor的内存、核心数等资源。