1. 程式人生 > >hadoop學習之路----HDFS原理與基本架構總結(第二講)

hadoop學習之路----HDFS原理與基本架構總結(第二講)

第二講主要內容如下
1.HDFS特點(也就是HDFS適用什麼場景)
2.HDFS缺點(也就是HDFS不適用什麼場景)
3.HDFS基本架構
4.HDFS工作原理
5.下一代HDFS介紹
下面主要聊聊其中的各個部分
1.HDFS特點(主要出自PPT)
主要有以下五點
高容錯性
       資料自動儲存多個副本       
       副本丟失後,自動恢復
              我們都知道在HDFS上資料是根據預設配置的3份副本,那麼著三份副本該如何進行選擇,下面就來簡單的介紹
 
              Hadoop預設副本存放策略是在執行客戶端的節點上放第1個複本(如果客戶端在叢集之外,就隨機選擇一個節點,不過系統會避免那些儲存太滿或太忙的節點),第2個複本放在與第1個不同且隨機另外選擇的機架中節點上(離架)第3個複本同第2個複本放在相同的機架,且隨機選擇另外一個節點。其他複本放在叢集中隨機選擇的節點上(多餘3份副本,會盡量避免相同機架放太多的副本)。上面的圖很好的展示了,這個過程。

下面還將介紹一下Hadoop的網路拓撲和機架感知
 
              在hadoop中還需要考慮的因素就是網路距離還在,海量資料處理中,其主要限制因素是節點之間資料的傳輸速率(也就是頻寬)這裡的想法是兩個節點的頻寬作為距離衡量的標準,在下面一些場景中頻寬依次遞減
              同一節點中的程序
              同一機架上的不同節點
              同一資料中心不同機架上的節點
              不同資料中心的節點
              假設,資料中心為d1,機架r1,節點n1,某個節點可以表示為/d1/r1/n1
              distance(/d1/r1/n1, /d1/r1/n1)= 0 (同一節點中的程序)

              distance(/d1/r1/n1, /d1/r1/n2)= 2 (同一機架上的不同節點)
              distance(/d1/r1/n1, /d1/r2/n3)= 4 (同一資料中心不同節點)
              distance(/d1/r1/n1, /d2/r3/n4)= 6 (不同資料中心的節點)
              上面就是Hadoop判斷網路距離的方式,但是Hadoop是不能自己獲取網路結構的(預設在同一個機架下面)下面我們將展示一個具體的配置也就是Hadoop的機架感知
              具體過程如下:
1.修改core-site.xml檔案
  1. <property>
  2. <name>topology.script.file.name</name>
  3. <value>/opt/modules/hadoop/hadoop-0.20.203.0/Utility/RackAware.py</value>
  4. </property>
複製程式碼 2.編寫 RackAware.py 指令碼
  1. #!/usr/bin/python
  2. #-*-coding:UTF-8 -*-
  3. import sys
  4. <P></P>
  5. <P style="LINE-HEIGHT: 30px; TEXT-INDENT: 2em">rack = {"hadoopnode-176.tj":"rack1",
  6. "hadoopnode-178.tj":"rack1",
  7. "hadoopnode-179.tj":"rack1",
  8. "hadoopnode-180.tj":"rack1",
  9. "hadoopnode-186.tj":"rack2",
  10. "hadoopnode-187.tj":"rack2",
  11. "hadoopnode-188.tj":"rack2",
  12. "hadoopnode-190.tj":"rack2",
  13. "192.168.1.15":"rack1",
  14. "192.168.1.17":"rack1",
  15. "192.168.1.18":"rack1",
  16. "192.168.1.19":"rack1",
  17. "192.168.1.25":"rack2",
  18. "192.168.1.26":"rack2",
  19. "192.168.1.27":"rack2",
  20. "192.168.1.29":"rack2",
  21. }</P>
  22. <P style="LINE-HEIGHT: 30px; TEXT-INDENT: 2em">if __name__=="__main__":
  23. print "/" + rack.get(sys.argv[1],"rack0")</P>
複製程式碼 3.執行命令:chmod +x RackAware.py
4.重新啟動機器               
               這樣做的好處有以下幾點
              1.可靠性:block儲存在兩個機架上              
              2.寫頻寬:寫操作僅僅穿過一個網路交換機
              3.讀操作:選擇其中得一個機架去讀
              4.block分佈在整個叢集上。

適合批處理
       移動計算而非資料(基於Host選擇演算法,待補充)
       資料位置暴露給計算框架
適合大資料處理
       GB、TB、甚至PB級資料
       百萬規模以上的檔案數量
       10K+節點規模
流式檔案訪問(推薦閱讀裡有比較好的資料)
       一次性寫入,多次讀取
       保證資料一致性
可構建在廉價機器上
       通過多副本提高可靠性(主要靠副本儲存策略)
       提供了容錯和恢復機(見下面block恢復機制)
HDFS缺點
低延遲資料訪問
       比如毫秒級 
       低延遲與高吞吐率
               HDFS的強項在於大量的資料傳輸,低延遲不適合它,不過HBase可以彌補這個缺陷
小檔案存取
       佔用大量NameNode儲存空間
       尋到時間超過讀取時間
              整個檔案系統的元資料,因此檔案的數量就會受到限制,每個檔案的元資料大約150位元組(無論檔案大小),1百萬個檔案,那麼就需要300MB記憶體
併發寫入,檔案隨機修改
        一個檔案只能有一個寫入者
        僅支援追加
HDFS基本架構(下面這個架構講的非常經典沒有之一,如果你沒看過那就太可惜了,那你在對HDFS理解和別人有著非常的差別)
下面是HDFS檔案讀取和寫入的過程,(我在這裡只是拋磚引玉)

HDFS原理
HDFS Block塊概
Hadoop權威指南讀寫過程供大家參考
HDFS檔案讀取
 
       1.首先呼叫FileSystem物件的open方法,其實是一個DistributedFileSystem的例項
       2.DistributedFileSystem通過rpc獲得檔案的第一批個block的locations,同一block按照重複數會返回多個locations,這些locations按照hadoop拓撲結構排序,距離客戶端近的排在前面.
       3.前兩步會返回一個FSDataInputStream物件,該物件會被封裝成DFSInputStream物件,DFSInputStream可以方便的管理datanode和namenode資料流。客戶端呼叫read方法,DFSInputStream最會找出離客戶端最近的datanode並連線(參考第一小節)。
       4.資料從datanode源源不斷的流向客戶端。
       5.如果第一塊的資料讀完了,就會關閉指向第一塊的datanode連線,接著讀取下一塊。這些操作對客戶端來說是透明的,客戶端的角度看來只是讀一個持續不斷的流。
       6.如果第一批block都讀完了,DFSInputStream就會去namenode拿下一批blocks的location,然後繼續讀,如果所有的塊都讀完,這時就會關閉掉所有的流。

HDFS讀取發生異常處理
       如果在讀資料的時候,DFSInputStream和datanode的通訊發生異常,就會嘗試正在讀的block的排第二近的datanode,並且會記錄哪個datanode發生錯誤,剩餘的blocks讀的時候就會直接跳過該datanode。DFSInputStream也會檢查block資料校驗和,如果發現一個壞的block,就會先報告到namenode節點,然後DFSInputStream在其他的datanode上讀該block的映象
HDFS讀操作設計思考
       設計考慮就是客戶端直接連線datanode來檢索資料並且namenode來負責為每一個block提供最優的datanode,namenode僅僅處理block location的請求,這些資訊都載入在namenode的記憶體中,hdfs通過datanode叢集可以承受大量客戶端的併發訪問。

HDFS檔案寫入
 
       1.客戶端通過呼叫DistributedFileSystem的create方法建立新檔案       2.DistributedFileSystem通過RPC呼叫namenode去建立一個沒有blocks關聯的新檔案,建立前,namenode會做各種校驗,比如檔案是否存在,客戶端有無許可權去建立等。如果校驗通過,namenode就會記錄下新檔案,否則就會丟擲IO異常.
       3.前兩步結束後會返回FSDataOutputStream的物件,象讀檔案的時候相似,FSDataOutputStream被封裝成DFSOutputStream.DFSOutputStream可以協調namenode和datanode。客戶端開始寫資料到DFSOutputStream,DFSOutputStream會把資料切成一個個小packet,然後排成佇列data quene。
       4.DataStreamer會去處理接受data quene,他先問詢namenode這個新的block最適合儲存的在哪幾個datanode裡(參考第二小節),比如重複數是3,那麼就找到3個最適合的datanode,把他們排成一個pipeline.DataStreamer把packet按佇列輸出到管道的第一個datanode中,第一個datanode又把packet輸出到第二個datanode中,以此類推。
       5.DFSOutputStream還有一個對列叫ack quene,也是有packet組成,等待datanode的收到響應,當pipeline中的所有datanode都表示已經收到的時候,這時akc quene才會把對應的packet包移除掉。
       6.客戶端完成寫資料後呼叫close方法關閉寫入流
       7.DataStreamer把剩餘得包都刷到pipeline裡然後等待ack資訊,收到最後一個ack後,通知datanode把檔案標示為已完成

HDFS檔案寫入失敗
       如果在寫的過程中某個datanode發生錯誤,會採取以下幾步:
       1.pipeline被關閉
       2.為了防止防止丟包ack quene裡的packet會同步到data quene
       3.把產生錯誤的datanode上當前在寫但未完成的block刪
       4.block剩下的部分被寫到剩下的兩個正常的datanode
       5.namenode找到另外的datanode去建立這個塊的復
       這些操作對客戶端來說是無感知的。
       (客戶端執行write操作後,寫完得block才是可見的,正在寫的block對客戶端是不可見的,只有呼叫sync方法,客戶端才確保該檔案被寫操作已經全部完成,當客戶端呼叫close方法時會預設呼叫sync方法。是否需要手動呼叫取決你根據程式需要在資料健壯性和吞吐率之間的權衡。)

對於block塊的恢復詳細資訊可以檢視如下blog
http://blog.csdn.net/macyang/article/details/7983188
HadoopHA的原理文件
http://blog.csdn.net/chenpingbupt/article/details/8026735
Hadoop相關配置文件
https://www.cloudera.com/content/cloudera-content/cloudera-docs/CDH4/latest/CDH4-High-Availability-Guide/CDH4-High-Availability-Guide.html