Spark的面試準備(一)
1、Hadoop中的MR與Spark有什麼區別?為什麼Spark有優勢?
MR的大致過程是:
Map端從HDFS中讀取到檔案,並簡單的進行資料處理,處理後將結果Spill(溢寫)到磁碟;Reduce從磁碟讀取Map產生的結果,進行處理後通常還是寫回到HDFS上。
這樣的處理過程會多次的進行磁碟讀寫,而磁碟讀取速度遠遠低於記憶體,所以效能有一定的瓶頸。
Spark是使用記憶體對資料進行操作,輸入資料、處理中間結果、儲存最終結果。
優勢:記憶體處理速度遠遠大於磁碟處理速度;Spark提供了許多API,方便開發人員對其進行多種多樣的資料處理操作。
2、懶載入
在Spark中,對RDD(一個特殊的集合型別,有容錯機制,有分割槽機制)的操作有兩種,其中轉換(Transformation)就是懶操作
3、RDD的特點
彈性分散式資料集,可以將其看做是一種特殊的集合型別,具有容錯機制,也具有分割槽機制(即可以分散式的儲存和處理資料集)
彈性:資料集中的分割槽可以由使用者指定
分散式:RDD的分割槽機制
容錯機制:通過RDD之間的依賴關係實現資料的恢復(擴充套件:在分散式的環境中,可能會使得不同網路下的RDD之間存在依賴,此時為了讓減少網路傳輸的資料量,可以部分中間結果儲存到磁碟上)
4、Stage的劃分
在多個計算邏輯在一起時,就會形成多個RDD之間的依賴關係,這些依賴關係就是DAG。在DAG中,當遇到Action(Spark中的方法有來那個兩種,一個是轉換-Transformation,
Stage可以理解為一組task的集合,一個分割槽對應一個task
5、Spark程式執行的過程
1)在叢集啟動時,Master會收集叢集中每臺Worker的資源情況;
2)當程式執行後,Master接受sc的請求,檢查可用的Worker,並且啟動一個可用的Worker;
3)Master將啟動的Worker的列表通知給sc;
4)sc找到對應的Worker,在Worker中啟動Executor,執行Task;
5)Task執行完後,Executor將結果返回給sc。
6、TaskScheduler的排程過程
1)從DAGScheduler中接受不同的Stage的任務;
2)向Cluster Manager申請資源;
3)得到資源後,為任務分配資源;
4)將分配好的結果返回給SchedulerBacked,之後,由SchedulerBacked將任務提交。
7、簡述Spark中任務排程流程
1)在Client生成Job;
2)通過DAGScheduler對Job劃分不同的Stage,並且進行提交;
3)DAGScheduler為需要計算的Partition生成TaskSet;
4)TaskScheduler提交計算任務;
5)排程器SchedulerBuilder排程任務;
6)TaskScheduler為任務分配資源;
7)SchedulerBacked將任務提交到Executor上執行。
8、說一下Spark的Shuffle
Shuffle,中文意思是洗牌,就是將具有共同特徵的一類資料彙集到一起的過程。
在Spark Shuffle的實際使用中,可能會有很複雜,例如資料量很大、發生多次磁碟讀寫、為了減少頻寬壓力而進行的壓縮帶來時間增加、資料傳輸。
在資料落地,會有爭議,若是不將資料寫入磁碟,會導致資料丟失後,需要重新計算依賴所有RDD。
資料持久化的兩種方法:
1)Hash Based write Shuffle,此方法的特點是生成的中間檔案較多(等於上游Task的數量乘以下游Task的數量),在Task數量較少時,可以使用,但Task數量很大時,就推薦使用Sort Based Write Shuffle;
2)Sort Based Write Shuffle,其生成的中間檔案數等於上游Task的數量,同時會生成相同數量的index檔案,該檔案是用於說明中間檔案的,在下游讀取中間檔案時,會通過index檔案進行讀取資料。
9、那麼Sort Based Write Shuffle有什麼缺點呢?
Sort Based Write會通過key對Partition進行排序,這就有點不符合最初避免計算時排序的初衷了,因為Spark比Hadoop的MapReduce快的原因之一就是不自動的對計算結果排序。
10、Spark中的快取
在Spark中,實現快取有兩種方法,一是呼叫cache(),二是呼叫persist(指定的級別)。
快取的級別:
1)MEMORY_ONIY:預設級別,也是cache()對應的級別。將RDD以反序列化的Java物件的形式儲存在JVM中。如果記憶體空間不夠,部分資料分割槽將不會被快取,這部分資料再次使用需要重新計算;
2)MEMORY_AND_DISK:將RDD以反序列化的Java物件的形式儲存在JVM中。如果記憶體空間不夠,將未快取的資料分割槽儲存到磁碟,使用時從磁碟讀取;
3)MEMORY_ONLY_SER:將RDD以序列化的Java物件的形式進行儲存(每個分割槽為一個byte陣列)。這種方式會比反序列化物件的方式節省很多空間,尤其是在使用fast serialize時節省更多的空間,但是在讀取時會使得CPU的read變得更加密集。如果記憶體空間不夠,部分資料分割槽將不會被快取,在每次需要用到這些資料時重新計算;
4)MEMORY_AND_DISK_SER:將RDD以序列化的Java物件的形式進行儲存(每個分割槽為一個byte陣列)。但是記憶體空間不夠,將未快取的資料分割槽儲存到磁碟,在需要使用這些資料時從磁碟讀取;
5)DISK_ONLY:只在磁碟快取RDD;
6)在上述級別後新增_2,表示每個分割槽在叢集中的兩個節點建立副本;
7)OFF_HEAP:將資料儲存在off-heap memory(堆外記憶體)中。
以上的快取可以等待自動被清理,也可以手動清理RDD..unpersist()。