Hadoop_HDFS文件讀寫代碼流程解析和副本存放機制

Hadoop學習筆記總結node

01.RPC(遠程過程調用)

1. RPC概念

遠程過程指的不是同一個進程的調用。它是一種經過網絡從遠程計算機程序上請求服務,而不須要了解底層網絡技術的協議。
不能直接拿到遠程機器的服務實例:好比loginController拿不到另外一臺主機loginService的實例,須要遠程調用。一種實現:如Soap(http+xml)網絡

  1. RPC至少有兩個過程。調用方(client),被調用方(server)。
  2. client主動發起請求,調用指定ip和port的server中的方法,把調用結果返回給client。
  3. 客戶端調用服務端的方法,意味着調用服務端的對象中的方法。
  4. 若是服務端的對象容許客戶端調用,那麼這個對象必須實現接口。
  5. 若是客戶端可以調用到服務端對象的方法,那麼這些方法必定位於對象的接口中。
  6. RPC是hadoop構建的基礎。

2. 在Hadoop上的應用例子

NameNode和DataNode之間通訊,進程間的遠程調用。併發

  1. 客戶端獲取NameNode的文件信息。(如客戶端獲取元數據信息,就是客戶端經過RPC得到代理對象,調用NameNode的方法)
  2. 客戶端寫副本到DataNode,只寫一個,其他的副本都是NameNode告訴DataNode去複製。
  3. DataNode和NameNode之間的心跳機制;DataNode按期彙報給NameNode自身的block信息(主要是當某個block損壞時,NameNode須要在元數據中更新副本信息)

hadoop和hbase中的大部分服務都是經過hadoop.ipc.RPC這個類來實現的。hadoop.ipc.RPC類中有兩個重要的函數RPC.Builder和getProxy。RPC.Builder經過接口協議實現的實體來獲取真正的server,getProxy獲取遠程訪問的本地代理。框架

02.FileSystem數據流

1. 剖析文件讀取

從HDFS讀取到本地代碼函數

Configuration conf = new Configuration();
conf.set("fs.defaultFS", "hdfs://master:9000/");
FileSystem fs = FileSystem.get(conf);
FSDataInputStream is = fs.open(new Path(……));
FileOutputStream os = new FileInputStream("D:/test.txt");

FileSystem.get()方法oop

  1. FileSystem.get(conf)獲取文件對象的實例對象。經過配置文件的conf信息判斷,返回一個DistributedFileSystem的class,再經過反射DistributedFileSystem的實例並返回。
  2. DistributedFileSystem中有一個成員DFSClient,這個成員在初始化時,就是初始化本身的ClientProtocal代理對象(名稱就是namenode),ClientProtocal是使用RPC框架和NN通訊的客戶端代理對象。

FileSystem.open(path)過程
學習

  1. 首先調用FileSystem對象的open方法,其實DistributedFileSystem實例的DFSClient成員在調用open().
  2. DistributedFileSystem經過rpc(上述:DFSClient中的namenode代理)得到文件的第一批個block的locations,同一block按照重複數會返回多個locations,這些locations按照hadoop拓撲結構排序,距離客戶端近的排在前面.
  3. fs.open()方法,返回文件系統輸入流FSDataInputStream,該對象會被封裝成DFSInputStream對象,這個類管理着DataNode和NameNode的I/O。客戶端調用read方法,DFSInputStream最會找出離客戶端最近的datanode並鏈接。
  4. 數據從datanode源源不斷的流向客戶端。
  5. 若是第一塊的數據讀完了,就會關閉指向第一塊的datanode鏈接,接着讀取下一塊。這些操做對客戶端來講是透明的,客戶端的角度看來只是讀一個持續不斷的流。
  6. 若是第一批block都讀完了,DFSInputStream就會去namenode拿下一批blocks的location,而後繼續讀,若是全部的塊都讀完,這時就會關閉掉全部的流。

如下是代碼實現過程

Ps:客戶端直接鏈接datanode來讀取數據,namenode來負責爲每個block提供最優的datanode,namenode僅僅處理block location的請求,這些元數據都加載在namenode的內存中,hdfs經過datanode集羣能夠承受大量客戶端的併發訪問。ui

2. 剖析文件寫入

步驟
新建一個文件,把數據從客戶端寫入,最後關閉文件。.net

  1. 過程和讀取相似,經過FileSystem的實例對象DistributedFileSystem.create()返回FSDataOutputStream,其中的ClientProtocal代理對象就是對NameNode的RPC調用.
  2. 在文件系統命名空間建立一個文件,NameNode經過各項檢查確保這個文件不存在和客戶端建立權限。和以前類似,FSDataOutputStream封裝着一個DFSOutputStream,負責DataNode和NameNode的通訊。
  3. DFSOutputStream會將數據分紅一個個數據包,寫入內部隊列,DataStream處理數據隊列,它的責任是根據DataNode列表來要求NameNode分配合適的新塊來存儲數據副本。dataStream將數據包流式傳輸到一個DataNode中,這個DataNode會傳輸到別的DataNode中。
    詳細過程參考博客《http://blog.csdn.net/lastsweetop/article/details/9065667

03.複本的存放

NameNode節點選擇一個datanode節點去存儲block副本得過程就叫作副本存放,這個過程的策略其實就是在可靠性和讀寫帶寬間得權衡。代理

《Hadoop權威指南》中的默認方式:

  1. 第一個複本會隨機選擇,可是不會選擇存儲過滿的節點。
  2. 第二個複本放在和第一個複本不一樣且隨機選擇的機架上。
  3. 第三個和第二個放在同一個機架上的不一樣節點上。
  4. 剩餘的副本就徹底隨機節點了。

複本爲3的系統管線:

能夠看出這個方案比較合理:
1.可靠性:block存儲在兩個機架上
2.寫帶寬:寫操做僅僅穿過一個網絡交換機
3.讀操做:選擇其中得一個機架去讀
4.block分佈在整個集羣上。

參考《Hadoop權威指南》和博客《http://blog.csdn.net/lastsweetop/article/details/9065667》 初接觸,記下學習筆記,還有不少問題,望指導,謝謝。

相關文章
相關標籤/搜索