1.什么是Spark?
Spark 大規(guī)模數(shù)據(jù)處理的快速通用的計(jì)算引擎。Spark來源于Hadoop MapReduce,同時(shí)Job中間輸出結(jié)果可以保存在內(nèi)存中,從而不再需要讀寫HDFS,內(nèi)存計(jì)算下比hadoop快100倍。
2.Spark生態(tài)系統(tǒng)?

核心為Spark Core,包含Spark的基本功能及定義了RDD。Spark庫都構(gòu)建在RDD和SparkCore之上;
上層有Spark SQL和Hive交互;Spark Streaming做實(shí)時(shí)數(shù)據(jù)流處理;MLlib常用機(jī)器學(xué)習(xí)算法庫;GraphX圖操作。
底層用HDFS做存儲(chǔ)
3. 什么是RDD?屬性有哪些?
答:RDD(Resilient Distributed Dataset)叫做分布式數(shù)據(jù)集,是spark中最基本的數(shù)據(jù)抽象,它代表一個(gè)不可變,可分區(qū),分區(qū)可改變,里面的元素可以并行計(jì)算的集合,其中數(shù)據(jù)優(yōu)先存儲(chǔ)在內(nèi)存,不夠時(shí)到磁盤中。
Resilient:表示彈性的,彈性表示
Destributed:分布式,可以并行在集群計(jì)算
Dataset:就是一個(gè)集合,用于存放數(shù)據(jù)的
五大屬性:
1.一個(gè)分區(qū)列表,RDD中的數(shù)據(jù)都存儲(chǔ)在一個(gè)分區(qū)列表中
2.作用在每一個(gè)分區(qū)中的函數(shù)
3.RDD之前的依賴關(guān)系,根據(jù)依賴關(guān)系實(shí)現(xiàn)容錯(cuò)機(jī)制
4.分區(qū)函數(shù),可選,針對(duì)于kv類型的RDD(必須產(chǎn)生shuffle)才有這個(gè)特性,決定數(shù)據(jù)的來源以及去向
5.存儲(chǔ)位置,可選,數(shù)據(jù)本地性數(shù)據(jù)位置最優(yōu),優(yōu)先分配給有數(shù)據(jù)的節(jié)點(diǎn)上進(jìn)行計(jì)算——【移動(dòng)數(shù)據(jù)不如移動(dòng)計(jì)算】
4.Spark的寬窄依賴?
RDD和它的父RDD的關(guān)系有兩種類型:窄依賴和寬依賴
寬依賴:指的是多個(gè)子RDD的Partition會(huì)依賴同一個(gè)父RDD的Partition,關(guān)系是一對(duì)多,父RDD的一個(gè)分區(qū)的數(shù)據(jù)去到子RDD的不同分區(qū)里面,會(huì)有shuffle的產(chǎn)生
窄依賴:指的是每一個(gè)父RDD的Partition最多被子RDD的一個(gè)partition使用,是一對(duì)一,也就是父RDD的一個(gè)分區(qū)去到了子RDD的一個(gè)分區(qū)中,這個(gè)過程沒有shuffle產(chǎn)生
區(qū)分的標(biāo)準(zhǔn)就是看父RDD的一個(gè)分區(qū)的數(shù)據(jù)的流向,要是流向一個(gè)partition的話就是窄依賴,否則就是寬依賴
5.stage和task概念?如何劃分?劃分的流程?
概念:Spark任務(wù)會(huì)根據(jù)RDD之間的依賴關(guān)系,形成一個(gè)DAG有向無環(huán)圖,DAG會(huì)提交給DAGScheduler,DAGScheduler會(huì)把DAG劃分相互依賴的多個(gè)stage,劃分依據(jù)就是寬窄依賴,遇到寬依賴就劃分stage,何時(shí)產(chǎn)生寬依賴就會(huì)產(chǎn)生一個(gè)新的stage,例如reduceByKey,groupByKey,join的算子,會(huì)導(dǎo)致寬依賴的產(chǎn)生;
劃分流程是從最后一個(gè)rdd開始往前推,把當(dāng)前rdd加入到一個(gè)stage中,如果遇到窄依賴,就把當(dāng)前rdd加入本stage中,如果遇到寬依賴,就從寬依賴切開,重新生成一個(gè)新的stage
每個(gè)stage包含一個(gè)或多個(gè)task,這些并行的task組成了stage,然后將這些task以taskSet的形式提交給TaskScheduler運(yùn)行。每個(gè) stage 里面 task 的數(shù)目由該 stage 最后一個(gè) RDD 中的 partition 個(gè)數(shù)決定。
6.Spark shuffle?
Shuffle 過程本質(zhì)上都是將 Map 端獲得的數(shù)據(jù)使用分區(qū)器進(jìn)行劃分,并將數(shù)據(jù)發(fā)送給對(duì)應(yīng)的 Reducer 的過程。shuffle作為處理連接map端和reduce端的樞紐,其shuffle的性能高低直接影響了整個(gè)程序的性能和吞吐量。
map端的shuffle一般為shuffle的Write階段,reduce端的shuffle一般為shuffle的read階段。
map端的Shuffle主要有input數(shù)據(jù)切分,patition內(nèi)存緩沖,spill寫回磁盤,merge文件合并
1)input, 根據(jù)split輸入數(shù)據(jù),運(yùn)行map任務(wù);
2)patition, 每個(gè)map task都有一個(gè)內(nèi)存緩沖區(qū),存儲(chǔ)著map的輸出結(jié)果;
3)spill, 當(dāng)緩沖區(qū)快滿的時(shí)候需要將緩沖區(qū)的數(shù)據(jù)以臨時(shí)文件的方式存放到磁盤;
4)merge, 當(dāng)整個(gè)map task結(jié)束后再對(duì)磁盤中這個(gè)map task產(chǎn)生的所有臨時(shí)文件做合并,生成最終的正式輸出文件,然后等待reduce task來拉數(shù)據(jù)。
Reduce 端的Shuffle簡(jiǎn)述: Copy拉取數(shù)據(jù),Merge合并,Reducer計(jì)算,Output輸出
Reduce task在執(zhí)行之前的工作就是不斷地拉取當(dāng)前job里每個(gè)map task的最終結(jié)果,然后對(duì)從不同地方拉取過來的數(shù)據(jù)不斷地做merge,也最終形成一個(gè)文件作為reduce task的輸入文件。
1)Copy過程,拉取數(shù)據(jù)。
2)Merge階段,合并拉取來的小文件
3)Reducer計(jì)算
4)Output輸出計(jì)算結(jié)果
Spark的shuffle分為兩種實(shí)現(xiàn),分別為HashShuffle和SortShuffle
HashShuffle又分為普通機(jī)制和合并機(jī)制,普通機(jī)制因?yàn)槠鋾?huì)產(chǎn)生M * R個(gè)數(shù)的巨量磁盤小文件而產(chǎn)生大量性能低下的Io操作,從而性能較低,因?yàn)槠渚蘖康拇疟P小文件還可能導(dǎo)致OOM,HashShuffle的合并機(jī)制通過重復(fù)利用buffer從而將磁盤小文件的數(shù)量降低到Core * R個(gè),但是當(dāng)Reducer端的并行任務(wù)或者是數(shù)據(jù)分片過多的時(shí)候,依然會(huì)產(chǎn)生大量的磁盤小文件。
SortShuffle也分為普通機(jī)制和bypass機(jī)制,普通機(jī)制在內(nèi)存數(shù)據(jù)結(jié)構(gòu)(默認(rèn)為5M)完成排序,會(huì)產(chǎn)生2M個(gè)磁盤小文件。而當(dāng)shuffle map task數(shù)量小于spark.shuffle.sort.bypassMergeThreshold參數(shù)的值,或者算子不是聚合類的shuffle算子(比如reduceByKey)的時(shí)候會(huì)觸發(fā)SortShuffle的bypass機(jī)制,SortShuffle的bypass機(jī)制不會(huì)進(jìn)行排序,極大的提高了其性能
在Spark 1.2以前,默認(rèn)的shuffle計(jì)算引擎是HashShuffleManager,因?yàn)镠ashShuffleManager會(huì)產(chǎn)生大量的磁盤小文件而性能低下,在Spark 1.2以后的版本中,默認(rèn)的ShuffleManager改成了SortShuffleManager。SortShuffleManager相較于HashShuffleManager來說,有了一定的改進(jìn)。主要就在于,每個(gè)Task在進(jìn)行shuffle操作時(shí),雖然也會(huì)產(chǎn)生較多的臨時(shí)磁盤文件,但是最后會(huì)將所有的臨時(shí)文件合并(merge)成一個(gè)磁盤文件,因此每個(gè)Task就只有一個(gè)磁盤文件。在下一個(gè)stage的shuffle read task拉取自己的數(shù)據(jù)時(shí),只要根據(jù)索引讀取每個(gè)磁盤文件中的部分?jǐn)?shù)據(jù)即可。
7.Spark數(shù)據(jù)傾斜
數(shù)據(jù)傾斜:通俗解釋是各節(jié)點(diǎn)上數(shù)據(jù)分布不均勻,就有的算的快有的慢
原理解釋:Shuffle必須將各個(gè)節(jié)點(diǎn)上相同的key拉取到某個(gè)節(jié)點(diǎn)上的一個(gè)task來進(jìn)行處理,比如按照key進(jìn)行聚合或join等操作。此時(shí)如果某個(gè)key對(duì)應(yīng)的數(shù)據(jù)量特別大的話,就會(huì)發(fā)生數(shù)據(jù)傾斜。
解決思路:
定位位置——groupByKey,reduceByKey,join等shuffle算子易出現(xiàn)問題,或者觀察某個(gè)stage下task分配的數(shù)據(jù)量
解決問題:
a. 數(shù)據(jù)角度:如果不重要直接過濾掉;
b. 并行度:提高shuffle操作的并行度;
c. 兩階段聚合:局部聚合(大任務(wù)劃分) + 全局聚合
8.Spark運(yùn)行架構(gòu)?

Driver:運(yùn)行Application 的main()函數(shù)
Cluster Manager: Master主節(jié)點(diǎn),控制整個(gè)集群中的worker。在YARN模式中為資源管理器
Worker節(jié)點(diǎn):從節(jié)點(diǎn),負(fù)責(zé)控制計(jì)算節(jié)點(diǎn),啟動(dòng)Executor或者Driver。
Executor:執(zhí)行器,是為某個(gè)Application運(yùn)行在worker node上的一個(gè)進(jìn)程
9. Spark運(yùn)行基本流程

1、構(gòu)建基本的運(yùn)行環(huán)境,由dirver創(chuàng)建一個(gè)SparkContext,分配并監(jiān)控資源使用情況
2、資源管理器為其分配資源,啟動(dòng)Excutor進(jìn)程
3、SparkContext根據(jù)RDD 的依賴關(guān)系構(gòu)建DAG圖,DAG圖提交給DAGScheduler解析成stage,然后提交給底層的taskscheduler處理。Excutor向SparkContext申請(qǐng)task,Taskscheduler將task發(fā)放給Executor運(yùn)行并提供應(yīng)用程序代碼
4、task在Executor運(yùn)行把結(jié)果反饋給TaskScheduler,一層層反饋上去。最后釋放資源
運(yùn)行架構(gòu)特點(diǎn):多線程運(yùn)行、運(yùn)行過程與資源管理器無關(guān)、Task采用了數(shù)據(jù)本地性和推測(cè)執(zhí)行來優(yōu)化。