天天看點

【最全的大資料面試系列】Spark面試題大全(二)

🚀 作者 :“大資料小禅”

🚀 **專欄簡介 **:本專欄主要分享收集的大資料相關的面試題,涉及到Hadoop,Spark,Flink,Zookeeper,Flume,Kafka,Hive,Hbase等大資料相關技術。大資料面試專欄位址。

🚀 **個人首頁 **:大資料小禅

🚀 **粉絲福利 **:加入小禅的大資料社群

🚀 歡迎小夥伴們 點贊👍、收藏⭐、留言💬

面試題目錄

1.Spark 的 shuffle過程?

2.Spark 的資料本地性有哪幾種?

3.Spark 為什麼要持久化,一般什麼場景下要進行 persist 操作?

4.介紹一下 join 操作優化經驗?

5.描述 Yarn 執行一個任務的過程?

6.Spark on Yarn 模式有哪些優點?

7.談談你對 container 的了解?

8.Spark 使用 parquet 檔案存儲格式能帶來哪些好處?

9.介紹 parition 和 block 有什麼關聯關系?

10.Spark 應用程式的執行過程是什麼?

11.不需要排序的 hash shuffle 是否一定比需要排序的 sort shuffle速度快?

12.Sort-based shuffle 的缺陷?

13.spark.storage.memoryFraction 參數的含義,實際生産中如何調優?

總結

從下面三點去展開

1)shuffle 過程的劃分

2)shuffle 的中間結果如何存儲

3)shuffle 的資料如何拉取過來

Spark 中的資料本地性有三種:

1)PROCESS_LOCAL 是指讀取緩存在本地節點的資料

2)NODE_LOCAL 是指讀取本地節點硬碟資料

3)ANY 是指讀取非本地節點資料

通常讀取資料 PROCESS_LOCAL>NODE_LOCAL>ANY,盡量使資料以PROCESS_LOCAL 或 NODE_LOCAL 方式讀取。其中 PROCESS_LOCAL 還和cache 有關,如果 RDD 經常用的話将該 RDD cache 到記憶體中,注意,由于cache 是 lazy 的,是以必須通過一個 action 的觸發,才能真正的将該 RDDcache 到記憶體中。

為什麼要進行持久化?

spark 所有複雜一點的算法都會有 persist 身影,spark 預設資料放在記憶體,spark 很多内容都是放在記憶體的,非常适合高速疊代,1000 個步驟隻有第一個輸入資料,中間不産生臨時資料,但分布式系統風險很高,是以容易出錯,就要容錯,rdd 出錯或者分片可以根據血統算出來,如果沒有對父 rdd 進行persist 或者 cache 的化,就需要重頭做。 以下場景會使用 persist

1)某個步驟計算非常耗時,需要進行 persist 持久化

2)計算鍊條非常長,重新恢複要算很多步驟,很好使,persist

3)checkpoint 所在的 rdd 要持久化 persist。checkpoint 前,要持久化,寫個 rdd.cache 或者 rdd.persist,将結果儲存起來,再寫 checkpoint 操作,這樣執行起來會非常快,不需要重新計算 rdd 鍊條了。checkpoint 之前一定會進行 persist。

4)shuffle 之後要 persist,shuffle 要進性網絡傳輸,風險很大,資料丢失重來,恢複代價很大

5)shuffle 之前進行 persist,架構預設将資料持久化到磁盤,這個是架構自動做的。

join 其實常見的就分為兩類: map-side join 和 reduce-side join。當大表和小表 join 時,用 map-side join 能顯著提高效率。将多份資料進行關聯是資料處理過程中非常普遍的用法,不過在分布式計算系統中,這個問題往往會變的非常麻煩,因為架構提供的 join 操作一般會将所有資料根據 key 發送到所有的 reduce 分區中去,也就是 shuffle 的過程。造成大量的網絡以及磁盤 IO消耗,運作效率極其低下,這個過程一般被稱為 reduce-side-join。如果其中有張表較小的話,我們則可以自己實作在 map 端實作資料關聯,跳過大量資料進行 shuffle 的過程,運作時間得到大量縮短,根據不同資料可能會有幾倍到數十倍的性能提升。

備注:這個題目面試中非常非常大機率見到,務必搜尋相關資料掌握,這裡抛磚引玉。

1)用戶端 client 向 ResouceManager 送出 Application,ResouceManager 接受 Application 并根據叢集資源狀況選取一個 node 來啟動 Application的任務排程器 driver(ApplicationMaster)。

2)ResouceManager 找到那個 node,指令其該 node 上的nodeManager來啟動一個新的 JVM 程序運作程式的 driver(ApplicationMaster)部分, driver(ApplicationMaster)啟動時會首先向 ResourceManager 注冊,說明由自己來負責目前程式的運作。

3)driver(ApplicationMaster)開始下載下傳相關 jar包等各種資源,基于下載下傳的 jar 等資訊決定向 ResourceManager 申請具體的資源内容。

4)ResouceManager 接受到 driver(ApplicationMaster)提出的申請後,會最大化的滿足 資源配置設定請求,并發送資源的中繼資料資訊給 driver(ApplicationMaster)。

5)driver(ApplicationMaster)收到發過來的資源中繼資料資訊後會根據中繼資料資訊發指令給具體機器上的 NodeManager,讓其啟動具體的 container。

6)NodeManager 收到 driver 發來的指令,啟動 container,container 啟動後必須向 driver(ApplicationMaster)注冊。

7)driver(ApplicationMaster)收到 container 的注冊,開始進行任務的排程和計算,直到 任務完成。注意:如果 ResourceManager 第一次沒有能夠滿足 driver(ApplicationMaster)的資源請求 ,後續發現有空閑的資源,會主動向driver(ApplicationMaster)發送可用資源的中繼資料資訊以提供更多的資源用于目前程式的運作。

1)與其他計算架構共享叢集資源(Spark 架構與 MapReduce 架構同時運作,如果不用 Yarn 進行資源配置設定,MapReduce 分到的記憶體資源會很少,效率低下);資源按需配置設定,進而提高叢集資源利用等。

2)相較于 Spark 自帶的 Standalone 模式,Yarn 的資源配置設定更加細緻。

3)Application 部署簡化,例如 Spark,Storm 等多種架構的應用由用戶端送出後,由 Yarn 負責資源的管理和排程,利用 Container 作為資源隔離的機關,以它為機關去使用記憶體,cpu等。

4)Yarn 通過隊列的方式,管理同時運作在 Yarn 叢集中的多個服務,可根據不同類型的應用程式負載情況,調整對應的資源使用量,實作資源彈性管理。

1)Container 作為資源配置設定和排程的基本機關,其中封裝了的資源如記憶體,CPU,磁盤,網絡帶寬等。 目前 yarn 僅僅封裝記憶體和 CPU

2)Container 由 ApplicationMaster 向 ResourceManager 申請的,由ResouceManager 中的資源排程器異步配置設定給ApplicationMaster

3)Container 的運作是由 ApplicationMaster 向資源所在的NodeManager發起的,Container 運作時需提供内部執行的任務指令

1)如果說 HDFS 是大資料時代分布式檔案系統首選标準,那麼 parquet 則是整個大資料時代檔案存儲格式實時首選标準。

2)速度更快:從使用 spark sql 操作普通檔案 CSV 和 parquet 檔案速度對比上看,絕大多數情況會比使用 csv 等普通檔案速度提升 10 倍左右,在一些普通檔案系統無法在 spark 上成功運作的情況下,使用 parquet 很多時候可以成功運作。

3)parquet 的壓縮技術非常穩定出色,在 spark sql 中對壓縮技術的處理可能無法正常的完成工作(例如會導緻 lost task,lost executor)但是此時如果使用 parquet 就可以正常的完成。

4)極大的減少磁盤 I/o,通常情況下能夠減少 75%的存儲空間,由此可以極大的減少 spark sql 處理資料的時候的資料輸入内容,尤其是在 spark1.6x 中有個下推過濾器在一些情況下可以極大的減少磁盤的 IO 和記憶體的占用,(下推過濾器)。

5)spark 1.6x parquet 方式極大的提升了掃描的吞吐量,極大提高了資料的查找速度 spark1.6 和 spark1.5x 相比而言,提升了大約 1 倍的速度,在spark1.6X 中,操作 parquet 時候 cpu 也進行了極大的優化,有效的降低了cpu 消耗。

6)采用 parquet 可以極大的優化 spark 的排程和執行。我們測試 spark 如果用 parquet 可以有效的減少 stage 的執行消耗,同時可以優化執行路徑。

1)hdfs 中的 block是分布式存儲的最小單元,等分,可設定備援,這樣設計有一部分磁盤空間的浪費,但是整齊的 block 大小,便于快速找到、讀取對應的内容;

2)Spark 中的 partion 是彈性分布式資料集 RDD 的最小單元,RDD 是由分布在各個節點上的 partion 組成的。partion 是指的 spark 在計算過程中,生成的資料在計算空間内最小單元,同一份資料(RDD)的 partion 大小不一,數量不定,是根據 application 裡的算子和最初讀入的資料分塊數量決定;

3)block 位于存儲空間、partion 位于計算空間,block的大小是固定的、partion 大小是不固定的,是從 2 個不同的角度去看資料。

1)建構 Spark Application 的運作環境(啟動 SparkContext),SparkContext 向資料總管(可以是 Standalone、Mesos 或 YARN)注冊并申請運作 Executor 資源;

2)資料總管配置設定 Executor 資源并啟動 StandaloneExecutorBackend,Executor 運作情況将随着心跳發送到資料總管上;

3)SparkContext 建構成 DAG 圖,将 DAG 圖分解成 Stage,并把Taskset發送給 Task Scheduler。Executor 向 SparkContext 申請 Task,TaskScheduler 将 Task 發放給 Executor 運作同時 SparkContext 将應用程式代碼發放給 Executor;4)Task 在 Executor上運作,運作完畢釋放所有資源。

不一定,當資料規模小,Hash shuffle 快于 Sorted Shuffle 資料規模大的時候;當資料量大,sorted Shuffle 會比 Hash shuffle 快很多,因為數量大的有很多小檔案,不均勻,甚至出現資料傾斜,消耗記憶體大,1.x 之前 spark 使用hash,适合進行中小規模,1.x 之後,增加了 Sorted shuffle,Spark 更能勝任大規模處理了。

1)如果 mapper 中 task的數量過大,依舊會産生很多小檔案,此時在shuffle 傳遞資料的過程中 reducer 段,reduce 會需要同時大量的記錄進行反序列化,導緻大量的記憶體消耗和 GC 的巨大負擔,造成系統緩慢甚至崩潰。 2)如果需要在分片内也進行排序,此時需要進行 mapper 段和 reducer 段的兩次排序。

1)用于設定 RDD 持久化資料在 Executor 記憶體中能占的比例,預設是 0.6,,預設 Executor 60%的記憶體,可以用來儲存持久化的 RDD 資料。根據你選擇的不同的持久化政策,如果記憶體不夠時,可能資料就不會持久化,或者資料會寫入磁盤;

2)如果持久化操作比較多,可以提高 spark.storage.memoryFraction 參數,使得更多的持久化資料儲存在記憶體中,提高資料的讀取性能,如果 shuffle 的操作比較多,有很多的資料讀寫操作到 JVM 中,那麼應該調小一點,節約出更多的記憶體給 JVM,避免過多的 JVM gc 發生。在 web ui 中觀察如果發現gc時間很長,可以設定 spark.storage.memoryFraction 更小一點。

Spark的面試題總共分成兩個篇章,内容較多,小夥伴們可以選擇自己需要的部分進行檢視。更多的大資料資料以及本文安裝包可以通過下方公衆号擷取哦,加入小禅的🏘️大資料技術社群一起交流學習,感謝支援!💪