大數據面試題——Hadoop篇

前言

結合南國 不到一年時間 學習大數據的知識梳理,加上2019年春天找實習的經歷,在這裏南國寫博客的同時會參考一些資料 寫出大數據內一些高頻的面試知識點。

1.Hadoop基礎

  1. 通常是集羣的最主要瓶頸:磁盤IO
    cpu 和內存在大數據集羣中都是可以擴充的,磁盤不行。
  2. Yarn,ClouderaManager可以作爲集羣的管理,zookeeper不可以。
    Zookeeper:是一個開源的分佈式應用程序協調服務,基於zookeeper可以實現同步服務,配置維護,命名服務。但它不能作爲集羣管理,注意區分。
  3. 請列出正常工作的Hadoop集羣中Hadoop都分別需要啓動哪些進程,它們的作用分別是什麼?
    1)NameNode它是hadoop中的主服務器,管理文件系統名稱空間和對集羣中存儲的文件的訪問,保存有metadate。
    2)SecondaryNameNode它不是namenode的冗餘守護進程,而是提供週期檢查點和清理任務。幫助NN合併editslog,減少NN啓動時間。
    3)DataNode它負責管理連接到節點的存儲(一個集羣中可以有多個節點)。每個存儲數據的節點運行一個datanode守護進程。
    4)ResourceManager(JobTracker)JobTracker負責調度DataNode上的工作。每個DataNode有一個TaskTracker,它們執行實際工作。
    5)NodeManager(TaskTracker)執行任務
    備註:這一部分南國在之前的博客中有詳細描述。

2.HDFS

  1. HDFS 中的 block 默認保存3份,默認BlockSize是64MB(Hadoop 1.x)/128MB(Hadoop 2.x)
    如果文件快默認大小爲64MB,修改爲128MB 【增加文件塊大小,需要增加磁盤的傳輸速率
  2. Client上傳文件過程:Client端將文件切分爲Block,依次上傳,它只上傳數據到一臺DataNode,然後由NameNode負責Block複製工作
  3. DataNode負責HDFS的數據存儲。
  4. 關於 SecondaryNameNode 哪項是正確的?(C)
    A.它是NameNode的熱備
    B.它對內存沒有要求
    C.他的目的使幫助NameNode合併編輯日誌,減少NameNode 啓動時間
    D. SecondaryNameNode應與NameNode 部署到一個節點
  5. 下列哪個程序通常與 NameNode 在一個節點啓動?(D)
    A.SecondaryNameNode
    B.DataNode
    C.TaskTracker
    D.JobTracker

解析:hadoop的集羣是基於master/slave模式,namenode和jobtracker屬於master,datanode和tasktracker屬於slave,master只有一個,而slave有多個。
SecondaryNameNode內存需求和NameNode在一個數量級上,所以通常secondary NameNode(運行在單獨的物理機器上)和 NameNode 運行在不同的機器上
JobTracker對應於NameNode,TaskTracker對應於DataNode。
DataNode和NameNode是針對數據存放來而言的。JobTracker和TaskTracker是對於MapReduce執行而言的。

mapreduce中幾個主要概念,mapreduce 整體上可以分爲這麼幾條執行線索:jobclient,JobTracker與TaskTracker。
1)JobClient會在用戶端通過JobClient類將已經配置參數打包成jar文件的應用存儲到hdfs,並把路徑提交到Jobtracker,然後由JobTracker創建每一個Task(即 MapTask 和 ReduceTask)並將它們分發到各個TaskTracker服務中去執行。
2)JobTracker是一master服務,軟件啓動之後JobTracker接收Job,負責調度Job的每一個子任務。task運行於TaskTracker上,並監控它們,如果發現有失敗的task就重新運行它。一般情況應該把JobTracker 部署在單獨的機器上。
3)TaskTracker是運行在多個節點上的slaver服務。TaskTracker主動與JobTracker通信,接收作業,並負責直接執行每一個任務。TaskTracker 都需要運行在HDFS的DataNode上。

7. NameNode與SecondaryNameNode 的區別與聯繫?

區別:
(1)NameNode負責管理整個文件系統的元數據,以及每一個路徑(文件)所對應的數據塊信息。
(2)SecondaryNameNode主要用於定期合併命名空間鏡像和命名空間鏡像的編輯日誌。
聯繫:
(1)SecondaryNameNode中保存了一份和namenode一致的鏡像文件(fsimage)和編輯日誌(edits)。
(2)在主namenode發生故障時(假設沒有及時備份數據),可以從SecondaryNameNode恢復數據。

8. NameNode HA實現原理(重要!!!)

在Hadoop 1.x版本,HDFS集羣的NameNode一直存在單點故障問題:集羣只存在一個NameNode節點,它維護了HDFS所有的元數據信息,當該節點所在服務器宕機或者服務不可用,整個HDFS集羣都將處於不可用狀態,極大限制了HDFS在生產環境的應用場景。直到Hadoop 2.0版本才提出了高可用 (High Availability, HA) 解決方案,並且經過多個版本的迭代更新,已經廣泛應用於生產環境。
解決方案:在同一個HDFS集羣,運行兩個互爲主備的NameNode節點。一臺爲主Namenode節點,處於Active狀態,一臺爲備NameNode節點,處於Standby狀態。其中只有Active NameNode對外提供讀寫服務,Standby NameNode會根據Active NameNode的狀態變化,在必要時切換成Active狀態。

爲什麼要Namenode HA?

  • NameNode High Availability即高可用。
  • NameNode 很重要,掛掉會導致存儲停止服務,無法進行數據的讀寫,基於此NameNode的計算(MR,Hive等)也無法完成。

Namenode HA 如何實現,關鍵技術難題是什麼?
1. 如何保持主和備NameNode的狀態同步,並讓Standby在Active掛掉後迅速提供服務,namenode啓動比較耗時,包括加載fsimage和editlog(獲取file to block信息),處理所有datanode第一次blockreport(獲取block to datanode信息),保持NN的狀態同步,需要這兩部分信息同步。
2. 腦裂(split-brain),指在一個高可用(HA)系統中,當聯繫着的兩個節點斷開聯繫時,本來爲一個整體的系統,分裂爲兩個獨立節點,這時兩個節點開始爭搶共享資源,結果會導致系統混亂,數據損壞。
3. NameNode切換對外透明,主Namenode切換到另外一臺機器時,不應該導致正在連接的客戶端失敗,主要包括Client,Datanode與NameNode的鏈接。
在這裏插入圖片描述
這部分內容 更多詳情參考:
https://www.jianshu.com/p/8a6cc2d72062
https://blog.csdn.net/wypersist/article/details/79797578

  1. hadoop2.x Federation
    單Active NN的架構使得HDFS在集羣擴展性和性能上都有潛在的問題,當集羣大到一定程度後,NN進程使用的內存可能會達到上百G,NN成爲了性能的瓶頸。
    爲了解決這個問題,Hadoop 2.x提供了HDFS Federation, 示意圖如下:
    在這裏插入圖片描述
    多個NN共用一個集羣裏的存儲資源,每個NN都可以單獨對外提供服務每個NN都會定義一個存儲池,有單獨的id,每個DN都爲所有存儲池提供存儲。
    DN會按照存儲池id向其對應的NN彙報塊信息,同時,DN會向所有NN彙報本地存儲可用資源情況。
    如果需要在客戶端方便的訪問若干個NN上的資源,可以使用客戶端掛載表,把不同的目錄映射到不同的NN,但NN上必須存在相應的目錄。

好處:
多namespace的方式可以直接減輕單一NameNode的壓力。
一個典型的例子就是上面提到的NameNode內存過高問題,我們完全可以將上面部分大的文件目錄移到另外一個NameNode上做管理.更重要的一點在於,這些NameNode是共享集羣中所有的DataNode的,它們還是在同一個集羣內的。

3.MapReduce

  1. Hadoop中定義的InputFormat,默認的是TextInputFormat.
    兩個類TextInputFormat和KeyValueInputFormat的區別是什麼?
    1)相同點:
    TextInputformat和KeyValueTextInputFormat都繼承了FileInputFormat類,都是每一行作爲一個記錄;
    2)區別:
    TextInputformat將每一行在文件中的起始偏移量作爲 key,每一行的內容作爲value。默認以\n或回車鍵作爲一行記錄。
    KeyValueTextInputFormat 適合處理輸入數據的每一行是兩列,並用 tab 分離的形式。

  2. 在一個運行的Hadoop 任務中,什麼是InputSplit?
    FileInputFormat源碼解析(input.getSplits(job))
    (1)找到你數據存儲的目錄。
    (2)開始遍歷處理(規劃切片)目錄下的每一個文件
    (3)遍歷第一個文件ss.txt

    • a)獲取文件大小fs.sizeOf(ss.txt);
    • b)計算切片大小computeSliteSize(Math.max(minSize,Math.min(maxSize,blocksize)))=blocksize=128M
    • c)默認情況下,切片大小=blocksize
    • d)開始切,形成第1個切片:ss.txt—0:128M 第2個切片ss.txt—128:256M 第3個切片ss.txt—256M:300M(每次切片時,都要判斷切完剩下的部分是否大於塊的1.1倍,不大於1.1倍就劃分一塊切片)
    • e)將切片信息寫到一個切片規劃文件中
    • f)整個切片的核心過程在getSplit()方法中完成。
    • g)數據切片只是在邏輯上對輸入數據進行分片,並不會再磁盤上將其切分成分片進行存儲。InputSplit只記錄了分片的元數據信息,比如起始位置、長度以及所在的節點列表等。
    • h)注意:block是HDFS上物理上存儲的存儲的數據,切片是對數據邏輯上的劃分
      (4)提交切片規劃文件到yarn上,yarn上的MrAppMaster就可以根據切片規劃文件計算開啓maptask個數。

3. 如何決定一個job的map和reduce的數量?

1)map數量
splitSize=max{minSize,min{maxSize,blockSize}}
map數量由處理的數據分成的block數量決定default_num = total_size / split_size;
2)reduce數量
reduce的數量job.setNumReduceTasks(x);x 爲reduce的數量。不設置的話默認爲 1。

4. MapTask(重要!!!)

一個job的map階段MapTask並行度(個數),由客戶端提交job時的切片個數決定。

關於MapTask的工作機制:
在這裏插入圖片描述
(1)Read階段:Map Task通過用戶編寫的RecordReader,從輸入InputSplit中解析出一個個key/value。
(2)Map階段:該節點主要是將解析出的key/value交給用戶編寫map()函數處理,併產生一系列新的key/value。
(3)Collect收集階段:在用戶編寫map()函數中,當數據處理完成後,一般會調用OutputCollector.collect()輸出結果。在該函數內部,它會將生成的key/value分區(調用Partitioner),並寫入一個環形內存緩衝區中。
(4)Spill階段:即“溢寫”,當環形緩衝區滿後,MapReduce會將數據寫到本地磁盤上,生成一個臨時文件。需要注意的是,將數據寫入本地磁盤之前,先要對數據進行一次本地排序,並在必要時對數據進行合併、壓縮等操作。
溢寫階段詳情:

  • 步驟1:利用快速排序算法對緩存區內的數據進行排序,排序方式是,先按照分區編號partition進行排序,然後按照key進行排序。這樣,經過排序後,數據以分區爲單位聚集在一起,且同一分區內所有數據按照key有序。
  • 步驟2:按照分區編號由小到大依次將每個分區中的數據寫入任務工作目錄下的臨時文件output/spillN.out(N表示當前溢寫次數)中。如果用戶設置了Combiner,則寫入文件之前,對每個分區中的數據進行一次聚集操作。
  • 步驟3:將分區數據的元信息寫到內存索引數據結構SpillRecord中,其中每個分區的元信息包括在臨時文件中的偏移量、壓縮前數據大小和壓縮後數據大小。如果當前內存索引大小超過1MB,則將內存索引寫到文件output/spillN.out.index中。

(5)Combine階段:當所有數據處理完成後,MapTask對所有臨時文件進行一次合併,以確保最終只會生成一個數據文件。

當所有數據處理完後,MapTask會將所有臨時文件合併成一個大文件,並保存到文件output/file.out中,同時生成相應的索引文件output/file.out.index。
在進行文件合併過程中,MapTask以分區爲單位進行合併。對於某個分區,它將採用多輪遞歸合併的方式。每輪合併io.sort.factor(默認100)個文件,並將產生的文件重新加入待合併列表中,對文件排序後,重複以上過程,直到最終得到一個大文件。
讓每個MapTask最終只生成一個數據文件,可避免同時打開大量文件和同時讀取大量小文件產生的隨機讀取帶來的開銷

5.ReduceTask(重要!!!)

在這裏插入圖片描述
(1)Copy階段:ReduceTask從各個MapTask上遠程拷貝一片數據,並針對某一片數據,如果其大小超過一定閾值,則寫到磁盤上,否則直接放到內存中。
(2)Merge階段:在遠程拷貝數據的同時,ReduceTask啓動了兩個後臺線程對內存和磁盤上的文件進行合併,以防止內存使用過多或磁盤上文件過多。
(3)Sort階段:按照MapReduce語義,用戶編寫reduce()函數輸入數據是按key進行聚集的一組數據。爲了將key相同的數據聚在一起,Hadoop採用了基於排序的策略。由於各個MapTask已經實現對自己的處理結果進行了局部排序,因此,ReduceTask只需對所有數據進行一次歸併排序即可。
(4)Reduce階段:reduce()函數將計算結果寫到HDFS上。

6. 描述MapReduce有幾種排序及排序發生的階段

1)排序的分類:

  • 部分排序:
    MapReduce根據輸入記錄的鍵對數據集排序。保證輸出的每個文件內部排序。
  • 全排序:
    如何用Hadoop產生一個全局排序的文件?最簡單的方法是使用一個分區。但該方法在處理大型文件時效率極低,因爲一臺機器必須處理所有輸出文件,從而完全喪失了MapReduce所提供的並行架構。
    替代方案:首先創建一系列排好序的文件;其次,串聯這些文件;最後,生成一個全局排序的文件。主要思路是使用一個分區來描述輸出的全局排序。例如:可以爲待分析文件創建3個分區,在第一分區中,記錄的單詞首字母a-g,第二分區記錄單詞首字母h-n, 第三分區記錄單詞首字母o-z。
  • 輔助排序:(GroupingComparator分組)
    Mapreduce框架在記錄到達reducer之前按鍵對記錄排序,但鍵所對應的值並沒有被排序。甚至在不同的執行輪次中,這些值的排序也不固定,因爲它們來自不同的map任務且這些map任務在不同輪次中完成時間各不相同。一般來說,大多數MapReduce程序會避免讓reduce函數依賴於值的排序。但是,有時也需要通過特定的方法對鍵進行排序和分組等以實現對值的排序。
  • 二次排序:
    在自定義排序過程中,如果compareTo中的判斷條件爲兩個即爲二次排序。

2)自定義排序WritableComparable
bean對象實現WritableComparable接口重寫compareTo方法,就可以實現排序。

@Override
public int compareTo(FlowBean o) {
	// 倒序排列,從大到小
	return this.sumFlow > o.getSumFlow() ? -1 : 1;
}

3)排序發生的階段:

  • 一個是在mapTask中 發生在spill後partition前。
  • 一個是在reduceTask中 發生在copy後reduce前

7. 描述mapReduce中combiner的作用是什麼,一般使用情景,哪些情況不需要,及和reduce的區別?

1)Combiner的意義就是對每一個maptask的輸出進行局部彙總,以減小網絡傳輸量。
2)Combiner能夠應用的前提是不能影響最終的業務邏輯,而且,Combiner的輸出kv應該跟reducer的輸入kv類型要對應起來。
3)Combiner和reducer的區別在於運行的位置。

  • Combiner是在每一個maptask所在的節點運行;
  • Reducer是接收全局所有Mapper的輸出結果。
  1. MapReduce如何實現TopN?
    可以自定義groupingcomparator,對結果進行降序排序。然後在reduce輸出時,只輸出前n個數,就可達到TopN輸出目的。
    具體樣例實現參考:MapReduce實現電影評分TopN

9. Hadoop的緩存機制(DistributedCache)

分佈式緩存一個最重要的應用就是在進行join操作的時候,如果一個表很大,另一個表很小,我們就可以將這個小表進行廣播處理,即每個計算節點上都存一份,然後進行map端的連接操作,這種情況下處理效率大大高於一般的reduce端join,廣播處理就運用到了分佈式緩存的技術。

DistributedCache將拷貝緩存的文件到Slave節點。在任何Job在節點上執行之前,文件在每個Job中只會被拷貝一次,緩存的歸檔文件會被在Slave節點中解壓縮。將本地文件複製到HDFS中去,接着Client會通過addCacheFile() 和addCacheArchive()方法告訴DistributedCache在HDFS中的位置。當文件存放到文地時,JobClient同樣獲得DistributedCache來創建符號鏈接,其形式爲文件的URI加fragment標識。當用戶需要獲得緩存中所有有效文件的列表時,JobConf 的方法 getLocalCacheFiles() 和getLocalArchives()都返回一個指向本地文件路徑對象數組。

4.Yarn

1.Hadoop的調度器總結

(1)默認的調度器FIFO
Hadoop中默認的調度器,它先按照作業的優先級高低,再按照到達時間的先後選擇被執行的作業
(2)計算能力調度器Capacity Scheduler
支持多個隊列,每個隊列可配置一定的資源量,每個隊列採用FIFO調度策略,爲了防止同一個用戶的作業獨佔隊列中的資源,該調度器會對同一用戶提交的作業所佔資源量進行限定。調度時,首先按以下策略選擇一個合適隊列:計算每個隊列中正在運行的任務數與其應該分得的計算資源之間的比值,選擇一個該比值最小的隊列;然後按以下策略選擇該隊列中一個作業:按照作業優先級和提交時間順序選擇,同時考慮用戶資源量限制和內存限制。
(3)公平調度器Fair Scheduler
同計算能力調度器類似,支持多隊列多用戶,每個隊列中的資源量可以配置,同一隊列中的作業公平共享隊列中所有資源。
實際上,Hadoop的調度器遠不止以上三種,最近,出現了很多針對新型應用的Hadoop調度器。

2.MapReduce 2.0的容錯機制

在現實世界中,難免遇到用戶代碼錯誤、進程崩潰、機器宕機等情況。使用Hadoop的一個好處是它有能力處理這些失敗,使你的job能夠成功完成。我們需要考慮以下實體的失敗:task、application master、node manager 、resource manager。
1.Task Failure
最常見的task 失敗是在map或reduce task中的用戶代碼拋出一個運行時異常。如果發生這種情況,JVM在退出之前將向父application master報告一個錯誤,錯誤最終會被寫進用戶的日誌中。application master將task標記爲失敗,並且釋放container,以便其資源可用於其它的task。
對於Streaming task,如果Streaming Process以非零代碼退出(即非正常退出),它將被標記爲失敗。這種行爲有stream.non.zero.exit.is.failure屬性控制(默認爲true)。
另一種失敗的情況是JVM突然退出——也許有一個JVM bug導致JVM的退出。在這種情況下,node manager通知application master task進程已經退出,然後application master嘗試標記task爲失敗狀態。

2.Application Master Failure
就像MapReduce的task,對於失敗的task會嘗試幾次重新調度,同樣在YARN中的應用如果失敗了也會重新嘗試運行。嘗試運行MapReduce application master的最大次數是由mapreduce.am.max-attempts屬性控制的,默認值爲2。所以如果一個MapReduce application master失敗了兩次,那麼它將不會被再次嘗試,MapReduce Job將失敗。

3.Node Manager Failure
如果一個node manage節點因中斷或運行緩慢而失敗,那麼它將不會發送心跳到resource manager(或者發送次數較少)。如果resource manage在10分鐘內(這個配置可以通過yarn.resourcemanager.nm.liveness-monitor.expiry-interval-ms屬性設置,以毫秒爲單位)沒有接收到一個心跳,它會感知到node manager已經停了,並把它衝節點集羣中移除。

4.Resource Manager Failure
Resource manager出現故障是比較嚴重的,因爲沒有它,job 和 task都不能被啓動。默認配置,resource manager是一個單點故障,因爲在機器出現故障時,所有的job都會失敗,並且不能被恢復。
爲了實現高可用(HA),有必要以一種active-standby(活動-備用)配置模式運行一對resource manager。如果活動的resource manager出現故障,備用的resource manager可以很開的接管,並且對客戶端來說沒有明顯的中斷現象。
這部分詳細內容 參考資料:MapReduce的容錯機制

未完待續。。。。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章