本文是基於石杉碼農公衆號關於HDFS的4篇文章作得總結梳理,因爲微信公衆好跳轉連接會過時,就不放上來了,有興趣的能夠直接前往公衆號查看《2018年原創匯總》文章查找。微信
Active NameNode-主節點:對外提供服務接收請求。網絡
Standby NameNode-備節點:一是接收和同步主節點的edits log以及執行按期checkpoint,二是在Active NameNode的時候進行主備切換。架構
存放NameNode元數據寫入的editLogs,供Standby NameNode拉取,主要意義是保持Active NameNode和Standby NameNode的同步,但必須高可用,因此是集羣部署。併發
存放真實數據的節點異步
一份數據會分爲多個block存放在各個DataNode上,一個block會創建副本,放入其餘的DataNode,保證一個block有三個副本在不一樣的DataNode上.優化
由於在Active NameNode向JournalNode發送editLog的時候,必須保證順序。因此須要獲取transacationId來維護這個順序,這也意味着transacationId的獲取不能併發。線程
主要是運用了double-buffer雙緩衝機制,什麼是雙緩衝勒。要發送的editLog數據是先放在緩衝區裏面,而後再由某個線程統一發送到JournalNode,提升網絡寫的效率。但這裏有個問題得解決,如何讓在網絡寫的過程當中不影響數據寫入緩衝區勒?只能引入雙緩衝機制,即將緩衝區域分爲兩份,一份用於存放即時寫入的數據,另外一份用於存放將要被網絡寫的數據,當須要網絡寫的時候將兩個區域切換,這樣兩個操做才能互相不影響。日誌
上圖第一次獲取鎖是爲了生成transacationId,第二次獲取鎖的操做就是優化網絡寫,保證每一個請求nameNode的線程不作無效的寫入請求。這裏保留一個疑問。第二次獲取鎖應該是非公平鎖把,理論上最後一個transacationId的線程獲取到鎖效率會更高一些,HDFS沒有對這裏作優化嗎?文章裏沒有提到這裏更細的解釋,這裏暫時存疑。blog
若是使用傳統的IO傳輸,將會產生頻繁的網絡傳輸,效率很低。隊列
加快磁盤寫入內存效率,默認是512Byte。
進一步緩衝要發送網絡的數據,默認64M。
注:這裏是異步的,意思是往OutPutStream寫入數據的同時,也在DataStreamer線程也在發送數據包。
爲了保證同一時間只能有一個客戶端獲取NameNode上面一個文件的契約,而後才能夠寫入數據。在寫文件的過程期間,客戶端須要開啓一個線程,不停的發送請求給NameNode進行文件續約。
NameNode若是每次都遍歷NameNode去淘汰過時的契約,效率是很是低下的,這裏的優化就是對每一個契約按最近一次續約時間進行排,序每次都把續約時間最老的契約排在最前頭。當每次檢查是否過時時,從頭開始遍歷,只要遍歷到沒有過時的就不遍歷了,由於後面的一定沒有過時。相似的,運用這種方式優化的案例還有eureka維護服務實例心跳續約使用的機制。