spark面试说词

spark简介

Spark是专为大规模数据处理而设计的快速通用的计算引擎,在迭代的场景下,spark比MR快10倍以上,spark运行速度快的原因不仅仅是因为spark基于内存计算,同时spark会有DAG有向无环图切割任务,确定任务的执行先后顺序。

spark有四种运行模式

local:多用于本地测试

Standalone:spark自带的一个资源调度框架

yarn:

Mesos

这里提到了spark的资源调度框架:那么就不得不说一下spark在standalone模式和yarn模式下的任务提交方式

standalone-client:首先客户端提交任务,这时候在客户端会启动Driver这个进程—>这时候Driver会向Master申请启动Application的启动资源(我们所有的Worker节点,会向Master节点进行心跳,这样Master就知道Worker的资源信息)—>资源申请成功后,Driver会发送task到Worker端执行—>最后Worker端将task执行的结果返回到Driver端(注意:这种提交任务的模式,在生产环境下不能使用client,因为当我们有多个Application提交的使用,Driver每次都会在client端启动,就会导致多次的网卡流量暴增)

standalone-cluster:首先客端提交任务,这时候客户端会向Master申请启动Driver进程,这时候Master在集群内找一台节点启动Driver进程,Driver启动之后会向Master申请Applaction执行的资源,之后Driver会发送task给Worker节点执行,worker会返回task执行情况和结果给Driver端,这里解决了client模式下网卡流量暴增的问题(注意:这里应用程序所有的jar包和文件,必须保证所有的Worker节点都要有,因为spark不回自动上传包,这时候我们通用的解决方式一般是将依赖包和文件打包,存储到hdfs上)

yarn-client:首先客户端提交Application之后,客户端会启动一个Driver进程,之后客户端进程会发送请求到ResourceManager上请求启动applicationMaster,Rs收到请求后会在集群中随机找一台节点启动AM,AM启动之后会向RS申请一批Container用于启动Exeuctor,这时候RS返回一批NameNode给AM,然后AM会向NM发送命令启动EXecutor,Executor启动之后会反响注册给Driver,Driver这时候发送task给Executor,最后执行的情况和结果会返回给Driver,(这里同样也会发生网卡流量暴增的问题,只适合于测试)

yarn-cluster:客户端提交Application之后,会发送请求带RS上,请求启动AM,RS收到后随机在一台NM上启动AM(相当于Driver),AM启动之后,AM发送请求到RS上请求一批container用于启动Executor,RS会返回一批NM给AM,这时候AM发送命令给NM启动Executor,Executor会反向注册到AM节点的Driver上,这时候Driver会发送task给Executor,执行情况和结果会返回给Driver

说完提交任务的方式之后我们需要谈一下spark的RDD,通过源码内的注释,可以得知RDD的五大特性:

1.RDD是由一系列的partition组成2.函数是作用在RDD上的3.分区器是作用在K,V格式的RDD上4.RDD有依赖关系

5.RDD提供了一系列最佳的计算位置,这里体现了RDD的弹性容错和分布式,因为RDD是由一系列大的partition组成的,而我们的paritition数量和大小都是没有限制的这里踢下线RDD的弹性,同时我们的RDD又是由上一个RDD通过计算得来,这里体现了RDD的容错,我们的partition是分布在不同的节点上,又体现了RDD的分部署的特性,最后我们RDD提供了最佳的计算位置,这里体现了大数据中的,计算向数据移动的思想

提到了我们函数是作用在RDD之上的,之后再说一下spark中我们常用的算子,

算子分为转换算子和行动算子

转换算子:

filter,map,flatmap,sample,reduceBykey,sortBykey,join,leftOutJoin,rightOutjoin,fullOutJoin,union,intersection,subtract,mapPartition,cogroup作用在K,V格式上,repartition,coalesce,groupBykey,distinct

行动算子:count,take,foreach,collect,countBykey,countByvalue,reduce,foreachpartition

在我们使用过程中有的算子会产生Shuffle,比如groupBykey,distinct,join等,平时应尽量避免使用Shuffle类的算子,我们可以使用广播变量来实现相同的功能

在spark中Shuffle分为两种,在1.2之前HashShuffle,在1.2之后引入了SortShuffle,

HashShuffle分为普通机制和合并机制

1.普通机制是每一个task产生结果溢写的时候自己维护一个Buffer,每个Buffer大小为32k,task将每个不同的结果写到不同的Buffer中最后产生大量的小文件,reducetask拉去这些小文件,产生的小文件个数为M*R,(这时候产生这么多小文件在数据通过网络传输时,出现故障的可能性大大增加,一旦出现故障会导致Suffle file not find导致task错误,这时候TaskScheduler不负责重试,由DAG负责重试整个stage,而且在写这些小文件和读取这些小文件的时候会产生大量的读写对象导致JVM频繁GC,如果GC无法解决就会造成OOM)

2.合并机制是一个Executor内多个task共用一个Buffer内存,最后产生的小文件个数是C(core)*R

SortShuffle分为普通机制和ByPass机制

1.普通机制:每一个task产生的结果会先写到一个数据结构中,这个数据结构大小默认为5M,在Shuffle的过程中会有一个定时器不定期的去估算这个内存结构的大小,当这个内存结构超过5M的时候,就会申请一个大小是现在大小的两倍减去5M的大小的内存给数据结构,如果申请不成功,这时候就会发生溢写到磁盘上,在溢写之前,会首先进行排序最后溢写到磁盘上按批写入默认1万条数据写一次,maptask执行完后,会将这些小文件合并成一个大文件并且生成一个索引文件。产生的文件数 2*M

2.ByPass机制:首先ByPass机制与普通机制不同的就只是少了一个排序的过程,而ByPass机制触发的条件是我们的Shuffle reduce task 数量默认小于200,产生的文件个数 2*M

说完Shuffle的过程之后就要说一下Shuffle文件的寻址

当maptask执行完成后,会将task的执行结果以及磁盘的小文件的地址封装到mapstatus对象中,通过MapOutputTrackerWork对象汇报给Driver中的MapOutputTrackerMaster对象,这时候reduceTask拉去文件的时候会先在本地的MapoutputTrackerWork对象中获取,当本地没有时,就会向Driver请求小文件的地址,这时候Driver端返回小文件的地址,我们的reducetask会默认启用5个线程去拉取数据,5个线程拉取数据的大小不能超过48M

我们spark会根据RDD的依赖关系形成一个DAG的有向无环图,而DAGScheduler划分stage根据宽窄依赖,宽依赖一定会产生Shuffle过程,既是一对多的关系,而窄依赖不会产生Shuffle多对一或者一对一的关系,这时候,DAGScheduler划分stage时,当遇到宽依赖的时候就会划分一个stage,一个stage内包含一组task,而且一个stage内是pipeline的计算模式,在spark的资源调度和任务调度时,当集群启动后,worker节点会向Master节点汇报自己的资源情况,当提交一个Apllication之后,在Driver端的TaskScheduler会向Master请求,Master会向worker节点发送启动Executor进程,worker节点启动完成Executor后,Executor会向TaskScheduler注册自己的信息,这时候TaskScheduler有一批Executor列表,这时候DAGSchelduer会根据RDD的宽窄依赖切分job让偶以taskSet的形式发送给TaskScheduler,TaskScheduler接收到TaskSet之后会遍历TaskSet,拿到每一个task到Executor上去执行,Executor反馈执行情况和结果。Task执行失败的时候,TaskScheduler负责重试,默认重试3次,3次之后依然失败的情况下,这个task所在的satge执行失败,由DAGScheduler负责重试,重新发送TaskSet到TaskScheduler上,默认重试4次,诺4次之后依然失败则这个job执行失败。TaskScheduler除了能够重试失败的task之外,还能重试执行缓慢的task,当一个task执行缓慢的时候,TaskScheduler会找到一个新的Executor执行这个task,这两个task那个先执行完就以那个task的结果为准,这就是spark的推测执行机制,这里如果我们在这个任务中有入库或者文件落地的操作,那么有可能会造成数据重复,所以当我们有这种操作的时候会关闭spark的推测执行机制。在我们资源申请过程中,分为粗粒度资源申请和细粒度资源申请,粗粒度资源(spark)申请既是在Application执行之前一次性申请完成资源申请,只有当全部task执行完成后,才会释放资源。这时候虽然执行速度较快但是资源无法被充分利用。而我们的细粒度资源申请是MR使用的,也就是在任务执行时需要什么资源才去申请什么资源,这样虽然资源充分利用,但会导致task的启动变慢,整个执行过程变慢。接下来说一下在spark几个关于资源调度的参数,如果没有设置total-executor,集群默认会为Application使用Spark集群中剩余的所有cores,如果没有设置executor-cores,这个Executor会使用此worker的所有合数,内存为1G,spreadOutApps参数如果不设置为false,意味着会一直在本次worker上启动executor直到资源用尽。spark内存在1.6之后默认只使用统一内存管理,我们的Executor中的内存,会有300M是JVM的,然后(总的-300M)的25%用来task的计算,剩下的一半是存储RDD的缓存数据,一半是用于Shuffle的聚合。这两者之间可以动态借用。这里的内存调优一般是在提交spark的任务的时候进行。

我们的spark同时还支持使用sql分析数据,sparksql的前身是shark,他底层依赖于Hive的解析器,查询优化器,而sparksql则完全脱离了Hive的限制,Hive只负责存储,sql的解析优化、执行都是由spark负责,当使用sparksql分析数据的时候,其底层实际是由Dataset封装成的RDD组成。而我们创建dataset的方式有多种,1.读取json格式的文件,2.通过RDD创建dataset可以使用反射,或者动态创建Schema的方式创建 3.读取parquent文件创建4.读取JDBC的数据创建。5,读取HIVE中的数据创建,当我们使用sparksql分析数据时,还可以使用自定义函数

最后就要说到sparkSteaming做准实时处理数据的流式框架了,sparksteaming支持可扩展性、高吞吐、高容错

他的数据来源可以是Kafka,Flume等,我们sparkstreaming和storm同样是做实时处理数据,但两者之间有一定的差别,sparksteaming是准实时的流式处理框架,strom是纯实时六十处理框架,strom的事务机制相对sparksteaming来说完善一些,sparksteaming擅长处理复杂的业务处理,storm不擅长,我们在sparksteaming常用的算子由foreachRDD、(。。。),最后我们sparksteaming和kafka整合的时候有两种模式,第一种receiver模式:当我们SparkStreaming程序运行起来后,Executor中会游receivertask接收kafka推送来的数据,这时候数据会被持久化,默认级别为MEMORY_AND_DISK_SER_2,receivertask会对数据进行存储和备份,发送给集群内的其他2个的Executor所在的节点,只有当备份完成后receiver task会向zookeeper提交读取数据的偏移量,最后向Driver汇报数据的位置,Driver根据数据本地化的原则,发送task到不同的节点上执行。然而我们的receive模式一般不被使用,首先当Driver挂掉的时候Executor也会挂掉,这时候可能会有一部分数据在Executor中没有被处理,1.这时候就会导致数据丢失。这时候我们会开启WAL机制,将数据在节点之间备份完后也向HDFS上备份一份,这样虽然会保证数据不会丢失,但会造成数据处理的延迟。2.这里采用了Receiver接收器,将数据接收到Executor中再处理,当任务有堆积的时候会造成内存压力过大。3.底层采用了高阶API来消费KAfka,这种模式不关系offset只要数据。我们receiver的并行度是由blockInterval决定的,默认为200ms,,如果要提高并行度可以减少blockInterval的数值,最好不要低于50ms。另一种模式是我们最常用的Direct模式,其与receiver的区别是,他是主动取kafka拉取数据,他的偏移量内部自己维护,默认偏移量是保存在内存中,如果设置了checkpoint目录,那么也会保存在checkpoint中。其并行度由kafka的topic的partition数决定。

优雅的停止sparkstream :

spark.streaming.stopGracefullyOnShutdown 设置成true

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值