spark面试问题 1、spark中的RDD是什么,有哪些特性RDD(Resilient Distributed Dataset)叫做分布式数据集,是Spark中最基本的数据抽象,它代表一个不可变、可分区、里面的元素可并行计算的集合。Dataset:就是一个集合,用于存放数据的 Distributed:分布式,可以并行在集群计算 Resilient:表示弹性的弹性表示1、RDD中的数据可以存储在内存或者是磁盘 2、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) 3、谈谈spark中的宽窄依赖RDD和它依赖的父RDD(s)的关系有两种不同的类型,即窄依赖(narrow dependency)和宽依赖(wide dependency)。 宽依赖:指的是多个子RDD的Partition会依赖同一个父RDD的Partition 窄依赖:指的是每一个父RDD的Partition最多被子RDD的一个Partition使用。 4、spark中如何划分stage1.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 如何防止内存溢出 7、spark中cache和persist的区别cache:缓存数据,默认是缓存在内存中,其本质还是调用persist persist:缓存数据,有丰富的数据缓存策略。数据可以保存在内存也可以保存在磁盘中,使用的时候指定对应的缓存级别就可以了。 8、简要描述Spark分布式集群搭建的步骤地球人都知道 这里可以概述下如何搭建高可用的spark集群(HA) 9、spark中的数据倾斜的现象、原因、后果(1)、数据倾斜的现象多数task执行速度较快,少数task执行时间非常长,或者等待很长时间后提示你内存不足,执行失败。 (2)、数据倾斜的原因数据问题1、key本身分布不均衡(包括大量的key为空) 2、key的设置不合理 spark使用问题 (3)、数据倾斜的后果1、spark中的stage的执行时间受限于最后那个执行完成的task,因此运行缓慢的任务会拖垮整个程序的运行速度(分布式程序运行的速度是由最慢的那个task决定的)。 2、过多的数据在同一个task中运行,将会把executor撑爆。 10、如何解决spark中的数据倾斜问题 11、flume整合sparkStreaming问题(1)、如何实现sparkStreaming读取flume中的数据可以这样说:前期经过技术调研,查看官网相关资料,发现sparkStreaming整合flume有2种模式,一种是拉模式,一种是推模式,然后在简单的聊聊这2种模式的特点,以及如何部署实现,需要做哪些事情,最后对比两种模式的特点,选择那种模式更好。推模式:Flume将数据Push推给Spark Streaming 拉模式:Spark Streaming从flume 中Poll拉取数据 (2)、在实际开发的时候是如何保证数据不丢失的
可以这样说:flume那边采用的channel是将数据落地到磁盘中,保证数据源端安全性(可以在补充一下,flume在这里的channel可以设置为memory内存中,提高数据接收处理的效率,但是由于数据在内存中,安全机制保证不了,故选择channel为磁盘存储。整个流程运行有一点的延迟性) sparkStreaming通过拉模式整合的时候,使用了FlumeUtils这样一个类,该类是需要依赖一个额外的jar包(spark-streaming-flume_2.10) 要想保证数据不丢失,数据的准确性,可以在构建StreamingConext的时候,利用StreamingContext.getOrCreate(checkpoint, creatingFunc: () => StreamingContext)来创建一个StreamingContext,使用StreamingContext.getOrCreate来创建StreamingContext对象,传入的第一个参数是checkpoint的存放目录,第二参数是生成StreamingContext对象的用户自定义函数。如果checkpoint的存放目录存在,则从这个目录中生成StreamingContext对象;如果不存在,才会调用第二个函数来生成新的StreamingContext对象。在creatingFunc函数中,除了生成一个新的StreamingContext操作,还需要完成各种操作,然后调用ssc.checkpoint(checkpointDirectory)来初始化checkpoint功能,最后再返回StreamingContext对象。 这样,在StreamingContext.getOrCreate之后,就可以直接调用start()函数来启动(或者是从中断点继续运行)流式应用了。如果有其他在启动或继续运行都要做的工作,可以在start()调用前执行。 流失计算中使用checkpoint的作用:保存元数据,包括流式应用的配置、流式没崩溃之前定义的各种操作、未完成所有操作的batch。元数据被存储到容忍失败的存储系统上,如HDFS。这种ckeckpoint主要针对driver失败后的修复。 保存流式数据,也是存储到容忍失败的存储系统上,如HDFS。这种ckeckpoint主要针对window operation、有状态的操作。无论是driver失败了,还是worker失败了,这种checkpoint都够快速恢复,而不需要将很长的历史数据都重新计算一遍(以便得到当前的状态)。 设置流式数据checkpoint的周期对于一个需要做checkpoint的DStream结构,可以通过调用DStream.checkpoint(checkpointInterval)来设置ckeckpoint的周期,经验上一般将这个checkpoint周期设置成batch周期的5至10倍。 使用write ahead logs功能这是一个可选功能,建议加上。这个功能将使得输入数据写入之前配置的checkpoint目录。这样有状态的数据可以从上一个checkpoint开始计算。开启的方法是把spark.streaming.receiver.writeAheadLogs.enable这个property设置为true。另外,由于输入RDD的默认StorageLevel是MEMORY_AND_DISK_2,即数据会在两台worker上做replication。实际上,Spark Streaming模式下,任何从网络输入数据的Receiver(如kafka、flume、socket)都会在两台机器上做数据备份。如果开启了write ahead logs的功能,建议把StorageLevel改成MEMORY_AND_DISK_SER。修改的方法是,在创建RDD时由参数传入。 使用以上的checkpoint机制,确实可以保证数据0丢失。但是一个前提条件是,数据发送端必须要有缓存功能,这样才能保证在spark应用重启期间,数据发送端不会因为spark streaming服务不可用而把数据丢弃。而flume具备这种特性,同样kafka也具备。 (3)Spark Streaming的数据可靠性
有了checkpoint机制、write ahead log机制、Receiver缓存机器、可靠的Receiver(即数据接收并备份成功后会发送ack),可以保证无论是worker失效还是driver失效,都是数据0丢失。原因是:如果没有Receiver服务的worker失效了,RDD数据可以依赖血统来重新计算;如果Receiver所在worker失败了,由于Reciever是可靠的,并有write ahead log机制,则收到的数据可以保证不丢;如果driver失败了,可以从checkpoint中恢复数据重新构建。 12、kafka整合sparkStreaming问题