Spark面试题(二)

2021年11月22日 阅读数:3
这篇文章主要向大家介绍Spark面试题(二),主要内容包括基础应用、实用技巧、原理机制等方面,希望对大家有所帮助。

关注公众号:大数据技术派,回复“资料”,领取1000G资料。
本文发于个人我的博客:Spark面试题(二)node

一、Spark有哪两种算子?

Transformation(转化)算子和Action(执行)算子。 面试

二、Spark有哪些聚合类的算子,咱们应该尽可能避免什么类型的算子?

在咱们的开发过程当中,能避免则尽量避免使用reduceByKey、join、distinct、repartition等会进行shuffle的算子,尽可能使用map类的非shuffle算子。
这样的话,没有shuffle操做或者仅有较少shuffle操做的Spark做业,能够大大减小性能开销。 sql

三、如何从Kafka中获取数据?

1)基于Receiver的方式
这种方式使用Receiver来获取数据。Receiver是使用Kafka的高层次Consumer API来实现的。receiver从Kafka中获取的数据都是存储在Spark Executor的内存
中的,而后Spark Streaming启动的job会去处理那些数据。
2)基于Direct的方式
这种新的不基于Receiver的直接方式,是在Spark 1.3中引入的,从而可以确保更加健壮的机制。替代掉使用Receiver来接收数据后,这种方式会周期性地
查询Kafka,来得到每一个topic+partition的最新的offset,从而定义每一个batch的offset的范围。当处理数据的job启动时,就会使用Kafka的简单consumer api来
获取Kafka指定offset范围的数据。 数据库

四、RDD建立有哪几种方式?

1)使用程序中的集合建立rdd
2)使用本地文件系统建立rdd
3)使用hdfs建立rdd
4)基于数据库db建立rdd
5)基于Nosql建立rdd,如hbase
6)基于s3建立rdd
7)基于数据流,如socket建立rdd api

五、Spark并行度怎么设置比较合适?

spark并行度,每一个core承载2~4个partition,如,32个core,那么64~128之间的并行度,也就是设置64~128个partion,并行读和数据规模无关,
只和内存使用量和cpu使用时间有关。 数组

六、Spark如何处理不能被序列化的对象?

将不能序列化的内容封装成object。 缓存

七、collect功能是什么,其底层是怎么实现的?

driver经过collect把集群中各个节点的内容收集过来汇总成结果,collect返回结果是Array类型的,collect把各个节点上的数据抓过来,
抓过来数据是Array型,collect对Array抓过来的结果进行合并,合并后Array中只有一个元素,是tuple类型(KV类型的)的。 markdown

八、为何Spark Application在没有得到足够的资源,job就开始执行了,可能会致使什么什么问题发生?

会致使执行该job时候集群资源不足,致使执行job结束也没有分配足够的资源,分配了部分Executor,该job就开始执行task,应该是task的调度线程
和Executor资源申请是异步的;若是想等待申请完全部的资源再执行job的:
须要将
spark.scheduler.maxRegisteredResourcesWaitingTime设置的很大;
spark.scheduler.minRegisteredResourcesRatio 设置为1,可是应该结合实际考虑
不然很容易出现长时间分配不到资源,job一直不能运行的状况。 网络

九、map与flatMap的区别?

map:对RDD每一个元素转换,文件中的每一行数据返回一个数组对象。
flatMap:对RDD每一个元素转换,而后再扁平化。
将全部的对象合并为一个对象,文件中的全部行数据仅返回一个数组对象,会抛弃值为null的值。 数据结构

十、Spark on Mesos中,什么是的粗粒度分配,什么是细粒度分配,各自的优势和缺点是什么?

1)粗粒度:启动时就分配好资源, 程序启动,后续具体使用就使用分配好的资源,不须要再分配资源;优势:做业特别多时,资源复用率高,适合粗粒度;
缺点:容易资源浪费,假如一个job有1000个task,完成了999个,还有一个没完成,那么使用粗粒度,999个资源就会闲置在那里,资源浪费。
2)细粒度分配:用资源的时候分配,用完了就当即回收资源,启动会麻烦一点,启动一次分配一次,会比较麻烦。

十一、driver的功能是什么?

1)一个Spark做业运行时包括一个Driver进程,也是做业的主进程,具备main函数,而且有SparkContext的实例,是程序的入口点;
2)功能:负责向集群申请资源,向master注册信息,负责了做业的调度,负责做业的解析、生成Stage并调度Task到Executor上。包括DAGScheduler,
TaskScheduler。

十二、Spark技术栈有哪些组件,每一个组件都有什么功能,适合什么应用场景?

能够画一个这样的技术栈图先,而后分别解释下每一个组件的功能和场景
1)Spark core:是其它组件的基础,spark的内核,主要包含:有向循环图、RDD、Lingage、Cache、broadcast等,并封装了底层通信框架,
是Spark的基础。
2)SparkStreaming是一个对实时数据流进行高通量、容错处理的流式处理系统,能够对多种数据源(如Kafka、Flume、Twitter、Zero和TCP 套接字)
进行相似Map、Reduce和Join等复杂操做,将流式计算分解成一系列短小的批处理做业。
3)Spark sql:Shark是SparkSQL的前身,Spark SQL的一个重要特色是其可以统一处理关系表和RDD,使得开发人员能够轻松地使用SQL命令进行外部查询,
同时进行更复杂的数据分析。
4)BlinkDB :是一个用于在海量数据上运行交互式 SQL 查询的大规模并行查询引擎,它容许用户经过权衡数据精度来提高查询响应时间,其数据的精度
被控制在容许的偏差范围内。
5)MLBase是Spark生态圈的一部分专一于机器学习,让机器学习的门槛更低,让一些可能并不了解机器学习的用户也能方便地使用MLbase。
MLBase分为四部分:MLlib、MLI、ML Optimizer和MLRuntime。
6)GraphX是Spark中用于图和图并行计算。

1三、Spark中Worker的主要工做是什么?

主要功能:管理当前节点内存,CPU的使用情况,接收master分配过来的资源指令,经过ExecutorRunner启动程序分配任务,worker就相似于包工头,
管理分配新进程,作计算的服务,至关于process服务。
须要注意的是:
1)worker会不会汇报当前信息给master,worker心跳给master主要只有workid,它不会发送资源信息以心跳的方式给mater,master分配的时候就知道work,
只有出现故障的时候才会发送资源。
2)worker不会运行代码,具体运行的是Executor是能够运行具体appliaction写的业务逻辑代码,操做代码的节点,它不会运行程序的代码的。

1四、Mapreduce和Spark的都是并行计算,那么他们有什么相同和区别?

二者都是用mr模型来进行并行计算:
1)hadoop的一个做业称为job,job里面分为map task和reduce task,每一个task都是在本身的进程中运行的,当task结束时,进程也会结束。
2)spark用户提交的任务成为application,一个application对应一个SparkContext,app中存在多个job,每触发一次action操做就会产生一个job。
这些job能够并行或串行执行,每一个job中有多个stage,stage是shuffle过程当中DAGSchaduler经过RDD之间的依赖关系划分job而来的,每一个stage里面有多个task,
组成taskset有TaskSchaduler分发到各个executor中执行,executor的生命周期是和app同样的,即便没有job运行也是存在的,因此task能够快速启动读取内存
进行计算。
3)hadoop的job只有map和reduce操做,表达能力比较欠缺并且在mr过程当中会重复的读写hdfs,形成大量的io操做,多个job须要本身管理关系。
4)spark的迭代计算都是在内存中进行的,API中提供了大量的RDD操做如join,groupby等,并且经过DAG图能够实现良好的容错。

1五、RDD机制?

rdd分布式弹性数据集,简单的理解成一种数据结构,是spark框架上的通用货币。 全部算子都是基于rdd来执行的,不一样的场景会有不一样的rdd实现类,
可是均可以进行互相转换。rdd执行过程当中会造成dag图,而后造成lineage保证容错性等。 从物理的角度来看rdd存储的是block和node之间的映射。

1六、什么是RDD宽依赖和窄依赖?

RDD和它依赖的parent RDD(s)的关系有两种不一样的类型,即窄依赖(narrow dependency)和宽依赖(wide dependency)
1)窄依赖指的是每个parent RDD的Partition最多被子RDD的一个Partition使用
2)宽依赖指的是多个子RDD的Partition会依赖同一个parent RDD的Partition

1七、cache和pesist的区别?

cache和persist都是用于将一个RDD进行缓存的,这样在以后使用的过程当中就不须要从新计算了,能够大大节省程序运行时间
1) cache只有一个默认的缓存级别MEMORY_ONLY ,cache调用了persist,而persist能够根据状况设置其它的缓存级别;
2)executor执行的时候,默认60%作cache,40%作task操做,persist是最根本的函数,最底层的函数。

1八、 cache后面能不能接其余算子,它是否是action操做?

cache能够接其余算子,可是接了算子以后,起不到缓存应有的效果,由于会从新触发cache。
cache不是action操做。

1九、reduceByKey是否是action?

不是,不少人都会觉得是action,reduce rdd是action

20、 RDD经过Linage(记录数据更新)的方式为什么很高效?

1)lazy记录了数据的来源,RDD是不可变的,且是lazy级别的,且RDD之间构成了链条,lazy是弹性的基石。因为RDD不可变,因此每次操做就产生新的rdd,
不存在全局修改的问题,控制难度降低,全部有计算链条将复杂计算链条存储下来,计算的时候从后往前回溯 900步是上一个stage的结束,要么就checkpoint。
2)记录原数据,是每次修改都记录,代价很大若是修改一个集合,代价就很小,官方说rdd是粗粒度的操做,是为了效率,为了简化,每次都是操做数据集合,
写或者修改操做,都是基于集合的rdd的写操做是粗粒度的,rdd的读操做既能够是粗粒度的也能够是细粒度,读能够读其中的一条条的记录。
3)简化复杂度,是高效率的一方面,写的粗粒度限制了使用场景如网络爬虫,现实世界中,大多数写是粗粒度的场景。