1. 程式人生 > 其它 >Spark面試題(二)

Spark面試題(二)

首發於我的個人部落格:Spark面試題(二)

1、Spark有哪兩種運算元?

Transformation(轉化)運算元和Action(執行)運算元。

2、Spark有哪些聚合類的運算元,我們應該儘量避免什麼型別的運算元?

在我們的開發過程中,能避免則儘可能避免使用reduceByKey、join、distinct、repartition等會進行shuffle的運算元,儘量使用map類的非shuffle運算元。
這樣的話,沒有shuffle操作或者僅有較少shuffle操作的Spark作業,可以大大減少效能開銷。

3、如何從Kafka中獲取資料?

1)基於Receiver的方式
這種方式使用Receiver來獲取資料。Receiver是使用Kafka的高層次Consumer API來實現的。receiver從Kafka中獲取的資料都是儲存在Spark Executor的記憶體
中的,然後Spark Streaming啟動的job會去處理那些資料。
2)基於Direct的方式
這種新的不基於Receiver的直接方式,是在Spark 1.3中引入的,從而能夠確保更加健壯的機制。替代掉使用Receiver來接收資料後,這種方式會週期性地
查詢Kafka,來獲得每個topic+partition的最新的offset,從而定義每個batch的offset的範圍。當處理資料的job啟動時,就會使用Kafka的簡單consumer api來
獲取Kafka指定offset範圍的資料。

4、RDD建立有哪幾種方式?

1)使用程式中的集合建立rdd
2)使用本地檔案系統建立rdd
3)使用hdfs建立rdd
4)基於資料庫db建立rdd
5)基於Nosql建立rdd,如hbase
6)基於s3建立rdd
7)基於資料流,如socket建立rdd

5、Spark並行度怎麼設定比較合適?

spark並行度,每個core承載24個partition,如,32個core,那麼64128之間的並行度,也就是設定64~128個partion,並行讀和資料規模無關,
只和記憶體使用量和cpu使用時間有關。

6、Spark如何處理不能被序列化的物件?

將不能序列化的內容封裝成object。

7、collect功能是什麼,其底層是怎麼實現的?

driver通過collect把叢集中各個節點的內容收集過來彙總成結果,collect返回結果是Array型別的,collect把各個節點上的資料抓過來,
抓過來資料是Array型,collect對Array抓過來的結果進行合併,合併後Array中只有一個元素,是tuple型別(KV型別的)的。

8、為什麼Spark Application在沒有獲得足夠的資源,job就開始執行了,可能會導致什麼什麼問題發生?

會導致執行該job時候叢集資源不足,導致執行job結束也沒有分配足夠的資源,分配了部分Executor,該job就開始執行task,應該是task的排程執行緒
和Executor資源申請是非同步的;如果想等待申請完所有的資源再執行job的:
需要將
spark.scheduler.maxRegisteredResourcesWaitingTime設定的很大;
spark.scheduler.minRegisteredResourcesRatio 設定為1,但是應該結合實際考慮
否則很容易出現長時間分配不到資源,job一直不能執行的情況。

9、map與flatMap的區別?

map:對RDD每個元素轉換,檔案中的每一行資料返回一個數組物件。
flatMap:對RDD每個元素轉換,然後再扁平化。
將所有的物件合併為一個物件,檔案中的所有行資料僅返回一個數組物件,會拋棄值為null的值。

10、Spark on Mesos中,什麼是的粗粒度分配,什麼是細粒度分配,各自的優點和缺點是什麼?

1)粗粒度:啟動時就分配好資源, 程式啟動,後續具體使用就使用分配好的資源,不需要再分配資源;優點:作業特別多時,資源複用率高,適合粗粒度;
缺點:容易資源浪費,假如一個job有1000個task,完成了999個,還有一個沒完成,那麼使用粗粒度,999個資源就會閒置在那裡,資源浪費。
2)細粒度分配:用資源的時候分配,用完了就立即回收資源,啟動會麻煩一點,啟動一次分配一次,會比較麻煩。

11、driver的功能是什麼?

1)一個Spark作業執行時包括一個Driver程序,也是作業的主程序,具有main函式,並且有SparkContext的例項,是程式的入口點;
2)功能:負責向叢集申請資源,向master註冊資訊,負責了作業的排程,負責作業的解析、生成Stage並排程Task到Executor上。包括DAGScheduler,
TaskScheduler。

12、Spark技術棧有哪些元件,每個元件都有什麼功能,適合什麼應用場景?

可以畫一個這樣的技術棧圖先,然後分別解釋下每個元件的功能和場景
1)Spark core:是其它元件的基礎,spark的核心,主要包含:有向迴圈圖、RDD、Lingage、Cache、broadcast等,並封裝了底層通訊框架,
是Spark的基礎。
2)SparkStreaming是一個對實時資料流進行高通量、容錯處理的流式處理系統,可以對多種資料來源(如Kafka、Flume、Twitter、Zero和TCP 套接字)
進行類似Map、Reduce和Join等複雜操作,將流式計算分解成一系列短小的批處理作業。
3)Spark sql:Shark是SparkSQL的前身,Spark SQL的一個重要特點是其能夠統一處理關係表和RDD,使得開發人員可以輕鬆地使用SQL命令進行外部查詢,
同時進行更復雜的資料分析。
4)BlinkDB :是一個用於在海量資料上執行互動式 SQL 查詢的大規模並行查詢引擎,它允許使用者通過權衡資料精度來提升查詢響應時間,其資料的精度
被控制在允許的誤差範圍內。
5)MLBase是Spark生態圈的一部分專注於機器學習,讓機器學習的門檻更低,讓一些可能並不瞭解機器學習的使用者也能方便地使用MLbase。
MLBase分為四部分:MLlib、MLI、ML Optimizer和MLRuntime。
6)GraphX是Spark中用於圖和圖平行計算。

13、Spark中Worker的主要工作是什麼?

主要功能:管理當前節點記憶體,CPU的使用狀況,接收master分配過來的資源指令,通過ExecutorRunner啟動程式分配任務,worker就類似於包工頭,
管理分配新程序,做計算的服務,相當於process服務。
需要注意的是:
1)worker會不會彙報當前資訊給master,worker心跳給master主要只有workid,它不會發送資源資訊以心跳的方式給mater,master分配的時候就知道work,
只有出現故障的時候才會傳送資源。
2)worker不會執行程式碼,具體執行的是Executor是可以執行具體appliaction寫的業務邏輯程式碼,操作程式碼的節點,它不會執行程式的程式碼的。

14、Mapreduce和Spark的都是平行計算,那麼他們有什麼相同和區別?

兩者都是用mr模型來進行平行計算:
1)hadoop的一個作業稱為job,job裡面分為map task和reduce task,每個task都是在自己的程序中執行的,當task結束時,程序也會結束。
2)spark使用者提交的任務成為application,一個application對應一個SparkContext,app中存在多個job,每觸發一次action操作就會產生一個job。
這些job可以並行或序列執行,每個job中有多個stage,stage是shuffle過程中DAGSchaduler通過RDD之間的依賴關係劃分job而來的,每個stage裡面有多個task,
組成taskset有TaskSchaduler分發到各個executor中執行,executor的生命週期是和app一樣的,即使沒有job執行也是存在的,所以task可以快速啟動讀取記憶體
進行計算。
3)hadoop的job只有map和reduce操作,表達能力比較欠缺而且在mr過程中會重複的讀寫hdfs,造成大量的io操作,多個job需要自己管理關係。
4)spark的迭代計算都是在記憶體中進行的,API中提供了大量的RDD操作如join,groupby等,而且通過DAG圖可以實現良好的容錯。

15、RDD機制?

rdd分散式彈性資料集,簡單的理解成一種資料結構,是spark框架上的通用貨幣。 所有運算元都是基於rdd來執行的,不同的場景會有不同的rdd實現類,
但是都可以進行互相轉換。rdd執行過程中會形成dag圖,然後形成lineage保證容錯性等。 從物理的角度來看rdd儲存的是block和node之間的對映。

16、什麼是RDD寬依賴和窄依賴?

RDD和它依賴的parent RDD(s)的關係有兩種不同的型別,即窄依賴(narrow dependency)和寬依賴(wide dependency)
1)窄依賴指的是每一個parent RDD的Partition最多被子RDD的一個Partition使用
2)寬依賴指的是多個子RDD的Partition會依賴同一個parent RDD的Partition

17、cache和pesist的區別?

cache和persist都是用於將一個RDD進行快取的,這樣在之後使用的過程中就不需要重新計算了,可以大大節省程式執行時間
1) cache只有一個預設的快取級別MEMORY_ONLY ,cache呼叫了persist,而persist可以根據情況設定其它的快取級別;
2)executor執行的時候,預設60%做cache,40%做task操作,persist是最根本的函式,最底層的函式。

18、 cache後面能不能接其他運算元,它是不是action操作?

cache可以接其他運算元,但是接了運算元之後,起不到快取應有的效果,因為會重新觸發cache。
cache不是action操作。

19、reduceByKey是不是action?

不是,很多人都會以為是action,reduce rdd是action

20、 RDD通過Linage(記錄資料更新)的方式為何很高效?

1)lazy記錄了資料的來源,RDD是不可變的,且是lazy級別的,且RDD之間構成了鏈條,lazy是彈性的基石。由於RDD不可變,所以每次操作就產生新的rdd,
不存在全域性修改的問題,控制難度下降,所有有計算鏈條將複雜計算鏈條儲存下來,計算的時候從後往前回溯 900步是上一個stage的結束,要麼就checkpoint。
2)記錄原資料,是每次修改都記錄,代價很大如果修改一個集合,代價就很小,官方說rdd是粗粒度的操作,是為了效率,為了簡化,每次都是操作資料集合,
寫或者修改操作,都是基於集合的rdd的寫操作是粗粒度的,rdd的讀操作既可以是粗粒度的也可以是細粒度,讀可以讀其中的一條條的記錄。
3)簡化複雜度,是高效率的一方面,寫的粗粒度限制了使用場景如網路爬蟲,現實世界中,大多數寫是粗粒度的場景。