<1> Hadoop的核心優點
- 高可靠性:Hadoop支持同一數據多個副本保存機制,能有效避免數據丟失狀況
- 高擴展性:Hadoop可以很方便地擴展大量節點,用於分佈式存儲與計算
- 高效率性:Hadoop結合MapReduce的思想,支持分佈式並行工做,處理工做
- 高容錯性:在Hadoop集羣中,可以自動將失敗節點的任務從新分配
<2> Yarn的架構
- ResourceManager:負責集羣任務調度與資源分配的核心,啓動監控NM與AM
- ApplicationMaster:負責監控和調度每一個任務的進行,Client提交任務RM就會建立AM
- NodeManager:每一個節點上負責調度該節點任務的單元,管理該節點的資源
- Container:Yarn集羣每一個節點的資源抽象而成的概念,包括多個維度:CPU、磁盤等
<3> Hadoop的核心配置
- hadoop-env.sh:Hadoop的環境配置,如配置JAVA_HOME
- core-site.xml:配置集羣文件系統類型(NameNode的URL)、集羣文件存儲目錄等
- hdfs-site.xml:與HDFS有關的配置,好比指定HDFS副本數量、Block大小等;指定SecondaryNameNode
- yarn-env.sh:配置Yarn的工做環境,好比添加JAVA_HOME
- yarn-site.xml:指定Yarn的ResourceManager,指定Reducer獲取數據的方式(mapreduce_shuffle) 、配置每一個節點Container最多可申請的內存等
- mapred-env.sh:配置Mapreduce的環境
- mapred-site.xml:指定Mapreduce運行在Yarn上 -- 關聯、指定JobTracker的地址
<4> 爲何不能頻繁格式化NameNode?
- Reason1:格式化NameNode就須要刪除節點內保存的全部數據,開銷較大,且有數據丟失風險
- Reason2:NameNode第一次啓動會生成集羣id,而NameNode格式化後會生成新的集羣id,若是某些節點的數據未清理乾淨,可能致使這些DataNode持有的仍是舊集羣ID,致使節點失效
<5> Hadoop集羣搭建的要點
- 部署 JDK & Hadoop
- 設置靜態IP (關閉防火牆)
- 設置SSH免密登陸(NameNode --- ALL Node ; ResourceManager --- ALL Node)
- 配置羣啓配置文件slavers
- 設置集羣內時間同步(如每10mins同步一次)
<6> HDFS
是什麼:HDFS是分佈式文件管理系統的一種緩存
幹什麼:海量數據(單臺PC設備沒法容納)的存儲與管理安全
【優勢】網絡
- 高容錯性:支持一文件多副本存儲機制,文件丟失風險較小
- 高擴展性:很方便進行集羣的擴建,增長節點;並且節點對於設備的要求不高
- 高容納性:擴展性的前提讓HDFS自然就擁有高容納性,能存儲管理TB甚至PB級別的數據
【缺點】架構
- 響應時間較長,不適合實時數據訪問
- 不支持併發寫操做,同一時間同一文件只能由一個線程進行寫
- 不支持隨機修改,寫入數據只能append
- 沒法高效存儲小文件(NameNode機制致使)
<7> HDFS架構
- NameNode:HDFS集羣的核心管理者,存儲全部塊文件的元數據,管理DataNode,處理Client端請求
- DataNode:實際文件的存儲者;負責文件的讀寫操做
- Client:客戶端,管理操做HDFS,與NameNode交互獲取元數據 -- 與DataNode交互獲取實際數據
- SecondaryNameNode:NameNode的協助角色,幫助NameNode進行fsimage與Edits的合併,必要時輔助NamaNode的恢復重啓
<8> HDFS的文件塊大小
Hadoop1.X -- 64M Hadoop2.X -- 128M 可經過參數進行調整(hdfs-site.xml)併發
決定文件塊大小的緣由:磁盤的傳輸速率 -- 訪問數據時尋址時間爲傳輸時間的1%時爲最佳app
- 文件塊太大:傳輸時間明顯遠大於尋址時間,表現爲程序在處理文件塊時操做時間比較久
- 文件塊過小:尋址時間佔耗時比例太大,增長尋址時間,不符合分佈式的目的
<9> HDFS的寫流程
- Client端加載FileSystem類,鏈接到NameNode,併發送上傳文件請求
- NameNode檢查文件是否已存在以及檢查文件將要存放的父目錄是否存在,而後回覆是否能夠進行上傳
- Client端請求上傳第一個Block(128M) -- 文件在Client端就會切分爲塊,邏輯切分,即經過seek維護偏移量
- NameNode根據副本數分配對應數量的DataNode節點返還給Client
- 根據設置的副本數分配對應數量的DataNode節點並返還給Client端
- Client加載FSDataOutputStream類,選擇一個距離本身最近的DataNode - D1請求創建通訊,D1收到請求後會調用D2,D2再調用D3,隨後D123分別應答Client,至此成功創建數據通道
- Client,向D1傳輸Block1 -- 以Packet爲單位
- D1接受數據Packet到內存,而後拷貝寫到本地磁盤,寫完後內存中的Packet將會傳遞給D2
- D2一樣進行拷貝刷寫,而後將內存中數據傳遞給D3
- D3爲最後一站,直接將接收到的Packet寫入到磁盤
- 第一個Block上傳完後,Client將會再次發送請求到NameNode請求上傳第二個Block
- ......
<10> HDFS的讀流程
- Client端加載FileSystem類,創建與NameNode的通訊,上傳讀取(下載)數據的請求
- NameNode根據文件塊的元數據,判斷文件是否存在以及在哪一個DataNode上
- NameNode答覆Client端,不存在文件 OR 文件所在的DataNode - D1 D2 D3 (一個文件可被分爲幾個Block)
- Client實現FSDataInputStream類,創建與D0 (存放Block1) 的通訊,並請求下載數據
- D0接收到請求,將數據文件從磁盤讀取到內存,以Packet爲單位,而後發送給Client
- Client接受到Packet數據,先寫到內存緩存,而後寫入到磁盤
- Block1讀取下載完畢後,Client再和D2創建通訊,下載Block2
- ......
<11> NameNode && SecondaryNameNode
關鍵點:無論文件大小,只要是一個Block,就會分配150byte用做存儲該Block的元數據,所以小文件過多很容易致使NameNode的實際利用率很低分佈式
- 內存:存儲當前集羣全部塊文件的元數據
- FSImage:元數據在磁盤中的實際存儲文件
- Edits:以日誌形式記錄寫入操做
當NameNode關閉或異常斷電時,內存中的數據丟失,既能夠經過加載磁盤上的FSImage文件到內存,同時執行Edits中記錄的操做,就能夠恢復全部的元數據oop
關鍵點:隨着集羣運轉,Edits日誌愈來愈大怎麼辦?線程
SecondaryNameNode的主要工做即是按期幫助NameNode進行FsImage和Edits文件的合併。默認每小時或者Edits文件中記錄超過100萬條(每分鐘檢查一次)時,SecondaryNameNode會將NameNode中的兩個文件拷貝到本身的節點,並加載到內存中進行合併後生成一個新的FSimage文件,將該新的文件拷貝給NameNode,替換原來的FSImage文件。注意:在SecondaryNameNode開始工做時,NameNode會生成一個新的Edits文件,記錄合併過程當中發生的寫操做,這樣新的Fsimage和新的Edits文件就是當前最新的元數據了日誌
SecondaryNameNode並非實時進行NameNode數據的同步,所以並不能在NameNode掛掉時徹底替代後者,而是經過將上一次的FsImage文件拷貝給NameNode進行大概的數據恢復,由於上一次合併到NameNode掛掉之間的數據仍然只在NameNode中,所以該恢復方法並不能徹底保證數據的完整性,當nameNode丟失Edits文件便會有數據的丟失
PLUS: NameNode啓動過程,是將磁盤中的FsImage和Edits加載到內存進行合併,最後造成完整的元數據,在此過程集羣爲安全模式,面向Client只讀,即沒法進行寫操做
<12> DataNode
HDFS文件塊的實際存儲節點,DataNode數據包括兩部分:
- 數據塊自己,128M / per Block
- 數據塊元數據:數據塊長度(可能爲一個小文件,不足128M,但也是一個Block)、校驗和、時間戳等
DataNode運行機制:
- DataNode啓動後,會首先向NameNode註冊本身
- 每一個一個小時,週期性地向NameNode上報節點下全部數據塊的元數據信息
- 心跳機制:讓NameNode知道DataNode是否還活着,默認每3s一次,若是超過10min + 30s沒有心跳,則NameNode就會判斷DataNode掛掉,將其標記爲不可用
- 在集羣運行的時候,能夠進行DataNode的加入【白名單】和退役【黑名單】
【擴充知識點:黑白名單】
- 若是設置了白名單(dfs.hosts),那麼只有白名單上的節點纔可以接入集羣,不在名單上的節點若是當前不在集羣,那麼沒法進入集羣;已在集羣的節點,會被強制退役,且這些退役節點中的數據不會轉移到其餘節點
- 若是設置了黑名單(dfs.hosts.exclude),那麼黑名單上的節點都不能接入集羣,在名單上的節點若是當前不在集羣,那麼沒法進入集羣;已在集羣的節點,會被強制退役,不過退役前會將數據轉移到其餘節點
<13> HDFS處理小文件的方法
HDFS文件歸檔:將一個目錄下的衆多小文件歸檔成爲一個HAR文件,對內訪問時仍然是一個個獨立的文件,即讀取時還是彼此獨立的,但對NameNode而言則是一個總體,因而這些小文件將會共用一個塊的元數據
<14> HA -- HDFS高可用
總結:爲了消除單點故障,維護兩個乃至多個NameNode,同一時間只有一個在役,其餘的爲替補,噹噹前在役的NameNode掛掉後,替補的NameNode升級服役,解決單點故障的痛點
手動實現高可用 -- 可能出現故障轉移失敗:
即若當前NameNode不可用了,Client端經過命令啓用另外一臺NameNode。但因爲NameNode在集羣的惟一性,爲了不Split Brain(兩個或多個NameNode在線),候補NameNode會給原來的NameNode發送驗證消息,只有收到了恢復候補NameNode的狀態纔可以可以升級爲Active。這樣當NameNode節點設備只是NameNode進程中斷的話是可以實現NameNode切換的,但若是是由於設備損毀(如爆炸、斷電、網絡中斷等)而致使NameNode的不可用,候補NameNode節點沒法與舊NameNode創建通訊,也就沒法完成切換
經過ZooKeeper實現自動故障轉移 -- 故障轉移穩定:
- 除卻Zookeeper外,自動故障轉移還在每一個NameNode節點啓用了ZKFC,ZKFC會按期ping同機上的NameNode進程,獲得其健康狀態,此外,ZKFC在Zookeeper上還維護了一個排他鎖ZNode。此外,每一個NameNode都在Zookeeper上維護了一個持久會話,若是會話消失,則鎖被釋放,且其餘NameNode會收到消息。這樣即使原NameNode機子徹底炸了,也能實現自動的故障轉移
- 若是ZKFC發現當前NameNode健康,且此時ZNode鎖沒有被任何人持有,那麼ZKFC將會搶佔該鎖,所在節點NameNode也將成爲Active【啓動時誰搶到了誰Active】。
- 若是當前NameNode不健康了,則NameNode所在會話將會關閉,其餘候補NameNode收到消息,且ZNode鎖被釋放,則候補NameNode中誰搶到了鎖誰就變爲Active
- 假死補刀:若是當前NameNode只是網絡波動等形成的假死,那麼ZKFC會檢測出來,並經過Zookeeper通知成爲新NameNode的節點下的ZKFC進程,新NameNode節點下的ZKFC將會發送kill指令,將舊NameNode完全結束(補刀),如此防止Split Brain現象