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

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

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

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