首先,再回顧一下HDFS的架構圖
HDFS寫數據流程
- 客戶端發送請求,調用DistributedFileSystem API的create方法去請求namenode,並告訴namenode上傳文件的文件名、文件大小、文件擁有者。
- namenode根據以上信息算出文件需要切成多少塊block,以及block要存放在哪個datanode上,並將這些信息返回給客戶端。
- 客戶端調用FSDataInputStream API的write方法首先將其中一個block寫在datanode上。
- 每一個block多個副本(默認3個),由已經上傳了block的datanode產生新的線程,按照放置副本規則往其它datanode寫副本。(並不是由客戶端分別往3個datanode上寫3份,這樣的優勢就是快。)
- 寫完後返回給客戶端一個信息,然後客戶端在將信息反饋給namenode。更新元數據。
HDFS讀流程
- 客戶端通過調用FileSystem對象中的open()方法來讀取需要的數據
- DistributedFileSystem會通過RPC協議調用NameNode來查找文件塊所在的位置
**NameNode只會返回所調用文件中開始的幾個塊而不是全部返回。對於每個返回的塊,都包含塊所在的DataNode的地址。隨後,這些返回的DataNode會按照Hadoop集羣的拓撲結構得出客戶端的距離,然後再進行排序。如果客戶端本身就是DataNode,那麼它就從本地讀取文件。**其次,DistributedFileSystem會向客戶端返回一個支持定位的輸入流對象FSDataInputStream,用於給客戶端讀取數據。FSDataInputStream包含一個DFSInputStream對象,這個對象來管理DataNode和NameNode之間的IO
-
當以上步驟完成時,客戶端便會在這個輸入流上調用read()方法
-
DFSInputStream對象中包含文件開始部分數據塊所在的DataNode地址,首先它會連接文件第一個塊最近的DataNode,隨後在數據流中重複調用read方法,直到這個塊讀完爲止。
-
當第一個塊讀取完畢時,DFSInputStream會關閉連接,並查找存儲下一個數據塊距離客戶端最近的DataNode,以上這些步驟對客戶端來說都是透明的。
-
當完成所有塊的讀取時,客戶端則會在DFSInputStream中調用close()方法。