昨天分享了大數據面試題之spark相關一,看到有很大的反響,今天就分享接下來的二,希望能更好的幫助到大家!
11.簡單說一下hadoop和spark的shuffle相同和差異?答:1)從 high-level 的角度來看,兩者並沒有大的差別。 都是將 mapper(Spark 裡是ShuffleMapTask)的輸出進行 partition,不同的 partition 送到不同的 reducer(Spark 裡 reducer 可能是下一個 stage 裡的 ShuffleMapTask,也可能是 ResultTask)。Reducer 以內存作緩衝區,邊 shuffle 邊 aggregate 數據,等到數據 aggregate 好以後進行 reduce() (Spark 裡可能是後續的一系列操作)。2)從 low-level 的角度來看,兩者差別不小。 Hadoop MapReduce 是 sort-based,進入 combine() 和 reduce() 的 records 必須先 sort。這樣的好處在於 combine/reduce() 可以處理大規模的數據,因為其輸入數據可以通過外排得到(mapper 對每段數據先做排序,reducer 的 shuffle 對排好序的每段數據做歸併)。目前的 Spark 默認選擇的是 hash-based,通常使用 HashMap 來對 shuffle 來的數據進行 aggregate,不會對數據進行提前排序。如果用戶需要經過排序的數據,那麼需要自己調用類似 sortByKey() 的操作;如果你是Spark 1.1的用戶,可以將spark.shuffle.manager設置為sort,則會對數據進行排序。在Spark 1.2中,sort將作為默認的Shuffle實現。3)從實現角度來看,兩者也有不少差別。 Hadoop MapReduce 將處理流程劃分出明顯的幾個階段:map(),spill, merge, shuffle, sort, reduce() 等。每個階段各司其職,可以按照過程式的編程思想來逐一實現每個階段的功能。在 Spark 中,沒有這樣功能明確的階段,只有不同的 stage 和一系列的 transformation(),所以 spill, merge, aggregate等操作需要蘊含在 transformation() 中。如果我們將 map 端劃分數據、持久化數據的過程稱為 shuffle write,而將 reducer 讀入數據、aggregate 數據的過程稱為 shuffle read。那麼在 Spark 中,問題就變為怎麼在 job 的邏輯或者物理執行圖中加入 shuffle write 和 shuffle read 的處理邏輯?以及兩個處理邏輯應該怎麼高效實現?Shuffle write由於不要求數據有序,shuffle write 的任務很簡單:將數據 partition 好,並持久化。之所以要持久化,一方面是要減少內存存儲空間壓力,另一方面也是為了 fault-tolerance。12.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需要自己管理關係。 spark的迭代計算都是在內存中進行的,API中提供了大量的RDD操作如join,groupby等,而且通過DAG圖可以實現良好的容錯。13.RDD機制? 答:rdd分布式彈性數據集,簡單的理解成一種數據結構,是spark框架上的通用貨幣。所有算子都是基於rdd來執行的,不同的場景會有不同的rdd實現類,但是都可以進行互相轉換。 rdd執行過程中會形成dag圖,然後形成lineage保證容錯性等。 從物理的角度來看rdd存儲的是block和node之間的映射。14、spark有哪些組件?答:主要有如下組件:1)master:管理集群和節點,不參與計算。 2)worker:計算節點,進程本身不參與計算,和master匯報。 3)Driver:運行程序的main方法,創建spark context對象。 4)spark context:控制整個application的生命周期,包括dagsheduler和task scheduler等組件。 5)client:用戶提交程序的入口。15、spark工作機制?答:用戶在client端提交作業後,會由Driver運行main方法並創建sparkcontext上下文。 執行add算子,形成dag圖輸入dagscheduler,按照add之間的依賴關係劃分stage輸入taskscheduler。 task scheduler會將stage劃分為task set分發到各個節點的executor中執行。16、spark的優化怎麼做?答: spark調優比較複雜,但是大體可以分為三個方面來進行,1)平臺層面的調優:防止不必要的jar包分發,提高數據的本地性,選擇高效的存儲格式如parquet,2)應用程式層面的調優:過濾操作符的優化降低過多小任務,降低單條記錄的資源開銷,處理數據傾斜,復用RDD進行緩存,作業並行化執行等等,3)JVM層面的調優:設置合適的資源量,設置合理的JVM,啟用高效的序列化方法如kyro,增大off head內存等等17.簡要描述Spark分布式集群搭建的步驟1)準備linux環境,設置集群搭建帳號和用戶組,設置ssh,關閉防火牆,關閉seLinux,配置host,hostname2)配置jdk到環境變量3)搭建hadoop集群,如果要做master ha,需要搭建zookeeper集群修改hdfs-site.xml,hadoop_env.sh,yarn-site.xml,slaves等配置文件4)啟動hadoop集群,啟動前要格式化namenode5)配置spark集群,修改spark-env.xml,slaves等配置文件,拷貝hadoop相關配置到spark conf目錄下6)啟動spark集群。18.什麼是RDD寬依賴和窄依賴?RDD和它依賴的parent RDD(s)的關係有兩種不同的類型,即窄依賴(narrowdependency)和寬依賴(wide dependency)。1)窄依賴指的是每一個parent RDD的Partition最多被子RDD的一個Partition使用2)寬依賴指的是多個子RDD的Partition會依賴同一個parent RDD的Partition19.spark-submit的時候如何引入外部jar包 方法一:spark-submit –jars根據spark官網,在提交任務的時候指定–jars,用逗號分開。這樣做的缺點是每次都要指定jar包,如果jar包少的話可以這麼做,但是如果多的話會很麻煩。命令:spark-submit --masteryarn-client --jars ***.jar,***.jar方法二:extraClassPath提交時在spark-default中設定參數,將所有需要的jar包考到一個文件裡,然後在參數中指定該目錄就可以了,較上一個方便很多:spark.executor.extraClassPath=/home/hadoop/wzq_workspace/lib/*spark.driver.extraClassPath=/home/hadoop/wzq_workspace/lib/*需要注意的是,你要在所有可能運行spark任務的機器上保證該目錄存在,並且將jar包考到所有機器上。這樣做的好處是提交代碼的時候不用再寫一長串jar了,缺點是要把所有的jar包都拷一遍。20.cache和pesist的區別 答:1)cache和persist都是用於將一個RDD進行緩存的,這樣在之後使用的過程中就不需要重新計算了,可以大大節省程序運行時間;2) cache只有一個默認的緩存級別MEMORY_ONLY,cache調用了persist,而persist可以根據情況設置其它的緩存級別;3)executor執行的時候,默認60%做cache,40%做task操作,persist最根本的函數,最底層的函數