一、hdfs上傳和下載文件流程
- hdfs上傳
客戶端向namenode發(fā)出請求建立通信獲得存儲文件塊的datanode節(jié)點,然后客戶端將文件按照塊的大小進行分塊(hadoop2.7.3開始由64MB變成128MB),客戶端按照順序?qū)lock逐個傳到響應(yīng)的datanode上,并由接收Black的datanode負(fù)責(zé)向其它的datanode復(fù)制block的副本
詳解
1.客戶端向namenode請求上傳文件,namenode檢查目標(biāo)文件,父目錄是否存在
2.namenode返回可使用資源,客戶端根據(jù)使用資源對要寫入的數(shù)據(jù)進行分塊
3.客戶端請求第一個Block上傳位置
4.namenode返回3個datanode節(jié)點,分別是data1,data2,data3
5.客戶端請求向第一個data1上傳block,data1收到請求會調(diào)用data2,然后data2會調(diào)用data3,將通道建立完成凿傅,逐級響應(yīng)客戶端
6.客戶端開始向data1上傳第一個block(先從磁盤讀取數(shù)據(jù)放到一個本地內(nèi)存緩沖),單位為packet(一個packet為64kb),在寫入data1的時候會進行數(shù)據(jù)校驗蕴侣,它并不是通過一個packet進行一次校驗而是以chunk為單位進行校驗(512byte),data1收到packet就會傳給data2,data2傳給data3,第一臺每傳一個packet會放入一個應(yīng)答隊列等待應(yīng)答
7.當(dāng)一個block傳輸完成之后,datanode進行報告給namenode存儲的塊信息,同時也告訴客戶端寫入成功
8.客戶端再次請求namenode上傳第二個block的服務(wù)器(重復(fù)執(zhí)行3-7步)
2.hdfs下載文件
客戶端向hdfs讀數(shù)據(jù),首先要和namenode建立通信來獲得需要讀取文件的元信息(主要是Block的存放文件位置信息),客戶端根據(jù)獲取的信息找到相應(yīng)datanode,逐個獲取文件的block并在客戶端本地進行數(shù)據(jù)追加,從而獲得整個文件
讀取步驟詳解:
1.client和namenode進行通信查詢元數(shù)據(jù)(block所在的datanode節(jié)點),找到block所在的datanode服務(wù)器
2.挑選一臺datanode,請求建立連接(就近原則,然后隨機),請求建立socket流
3.datanode開始發(fā)送數(shù)據(jù)(從磁盤里面讀取數(shù)據(jù)放入流,以packet為單位來做校驗)
4.客戶達以packet為單位接受,首先在本地緩沖,然后寫入目標(biāo)文件,后面的block追加合并到這個文件,最后合成最終需要的文件
二焰轻、mapreduce的shuffle過程
首先shuffle是貫徹整個mapreduce過程,可以分為2部分,map端的shuffle和reduce端的shuffle。map端shuffle,map任務(wù)執(zhí)行后的中間結(jié)果”不會立馬寫入磁盤昆雀,而是優(yōu)先存儲到map節(jié)點的“環(huán)形內(nèi)存緩沖區(qū)”(默認(rèn)100MB)辱志,當(dāng)內(nèi)存緩存區(qū)達到一定閾值(默認(rèn)0.8)就會進行溢寫到磁盤文件,溢寫之前會先進行分區(qū),然后分區(qū)內(nèi)的排序,如果客戶端自定義了Combiner,還會進行合并操作狞膘。最后如果有多個溢寫文件揩懒。會對這個多個溢寫文件進行歸并生成最終的一個已分區(qū)且已排序的大文件。reduce端shuffle先領(lǐng)取不同節(jié)點map任務(wù)執(zhí)行結(jié)束數(shù)據(jù)存儲到緩存區(qū),當(dāng)緩存區(qū)到達一定閾值,就是發(fā)生溢寫操作,溢寫之前具有相同key的鍵值對會被歸并,如果客戶端定義combiner客冈,歸并后還可以執(zhí)行combiner(合并),但溢寫文件過多,也會歸并成一個大文件旭从。輸出給Reduce任務(wù),整個shuffle才最終結(jié)束。
三和悦、hadoop1.0跟hadoop2.0區(qū)別
- 針對1.0中NameNode的單點故障問題退疫,在2.0中引入了新的HA機制
2.解決jobTracker等弊端,使用yarn資源管理系統(tǒng)
四、hadoop 數(shù)據(jù)傾斜
就是大量的相同key被partition分配到一個分區(qū)里鸽素,map /reduce程序執(zhí)行時褒繁,reduce節(jié)點大部分執(zhí)行完畢,但是有一個或者幾個reduce節(jié)點運行很慢馍忽,導(dǎo)致整個程序的處理時間很長棒坏,這是因為某一個key的條數(shù)比其他key多很多(有時是百倍或者千倍之多),這條key所在的reduce節(jié)點所處理的數(shù)據(jù)量比其他節(jié)點就大很多遭笋,從而導(dǎo)致某幾個節(jié)點遲遲運行不完坝冕。
解決方案:
1.增加jvm內(nèi)存,這適用于第一種情況(唯一值非常少,極少數(shù)值有非常多的記錄值(唯一值少于幾千)),這種情況下,往往只能通過硬件的手段來進行調(diào)優(yōu),增加jvm內(nèi)存可以顯著的提高運行效率瓦呼。
2.增加reduce的個數(shù),這適用于第二種情況(唯一值比較多喂窟,這個字段的某些值有遠遠多于其他值的記錄數(shù),但是它的占比也小于百分之一或千分之一),我們知道,這種情況下,
最容易造成的結(jié)果就是大量相同key被partition到一個分區(qū),從而一個reduce執(zhí)行了大量的工作,而如果我們增加了reduce的個數(shù),這種情況相對來說會減輕很多,畢竟計算的節(jié)點多了,就算工作量還是不均勻的,那也要小很多央串。
3.自定義分區(qū),這需要用戶自己繼承partition類,指定分區(qū)策略,這種方式效果比較顯著磨澡。
4.重新設(shè)計key,有一種方案是在map階段時給key加上一個隨機數(shù),有了隨機數(shù)的key就不會被大量的分配到同一節(jié)點(小幾率),待到reduce后再把隨機數(shù)去掉即可。
5.使用combinner合并,combinner是在map階段,reduce之前的一個中間階段,在這個階段可以選擇性的把大量的相同key數(shù)據(jù)先進行一個合并,可以看做是local reduce,然后再交給reduce來處理,這樣做的好處很多,即減輕了map端向reduce端發(fā)送的數(shù)據(jù)量(減輕了網(wǎng)絡(luò)帶寬),也減輕了map端和reduce端中間的shuffle階段的數(shù)據(jù)拉取數(shù)量(本地化磁盤IO速率),推薦使用這種方法质和。
五稳摄、hdfs不適合存小文件的原因
1.namenode會記錄文件的元數(shù)據(jù),如果小文件過多饲宿,會造成namenode消耗太大
2.hdfs的設(shè)計原理是接近磁盤讀取速度厦酬,之所以把block塊設(shè)置很大,是因為想做到尋道時間遠小于文件讀取數(shù)據(jù)塊的時間褒傅,接近磁盤讀取速度弃锐。