好程序員大數據學習路線分享分佈式文件系統HDFS

好程序員大數據學習路線分享分佈式文件系統HDFS,設計目標:

1存儲量大

2自動快速檢測應對硬件錯誤

3流式訪問數據

4移動計算比移動數據本身更划算

5簡單一致性模型

6異構平臺可移植

特點

優點:

  1. 高可靠性:Hadoop按位存儲和處理數據的能力強

  2. 高擴展性:hadoop是在可用的計算機集簇間分配數據並完成計算任務的,這些集簇可以方便地擴展到數以千計的節點中

  3. 高效性:hadoop能夠在節點之間動態地移動數據,並保證各個節點的動態平衡,因此處理速度非常快

  4. 高容錯性:hadoop能夠自動保存數據的多個副本,並且能夠自動將失敗的任務重新分配。

缺點:

  1. 不適合低延遲數據訪問

  2. 無法高效存儲大量小文件(每個文件存儲都有屬於自己的索引,元數據龐大就不高效)

  3. 不支持多用戶寫入及任意修改文件(可以刪除以及追加,只是不能修改文件中某處的數據)

重要特性:

  1. 文件在物理上是分塊存儲,塊的大小可以通過配置參數(dfs.blocksize)來規定,默認2.x版本之後是128M,老版本是64M

  2. HDFS會給哭護短提供一個統一的抽象目錄樹,客戶端通過路徑來訪問文件,刑辱:hdfs://namenode:port/dir-a/dir-b/dir-c/file.data

  3. 目錄結構及文件分塊信息(元數據)的管理由namenode承擔—namenodeHDFS集羣主節點,負責維護整個hdfs文件系統的目錄樹,以及每一個路徑(文件)所對應的block塊信息(blockid以及所在datanode服務器)

  4. 文件的各個block的存儲管理由datanode承擔—datanodeHDFS集羣從節點,每一個block都可以在多個datanode上存儲多個副本(副本參數設置dfs.replication)

  5. HDFS是設計成適應一次寫入,多次讀出的場景,且不支持文件的修改

  6. 管理文件系統的命名空間(元數據<metadata>:包含文件名稱、大小、所屬人、地址)

  7. 規定客戶端訪問文件規則

三個服務

Namenode
任務清單

a) 文件大小是否已經超載(超過集羣的負載)

b) 是否已經存在相同的文件

c) 是否具有創建該文件的權限

  1. 對文件執行命令,關閉,打開文件或者打開路徑等操作

  2. 所有的數據節點發送心跳給NameNode,他需要確保數據節點DataNode是否在線,一個數據塊報告包含所有這個數據節點上的所有block的狀況

  3. 首先將fsimage(鏡像)載入內存,並讀取執行日誌editlog的各項操作

  4. 一旦在內存中建立文件系統元數據映射,則創建一個新的fsimage文件(這個過程不需要secondaryNamenode)和一個空的editlog

  5. 在安全模式下,各個datanode會向namenode發送塊列表的最新情況

  6. 此刻namenode運行在安全模式。即NameNode的文件系統對於客戶端來說是隻讀

  7. NameNode開始監聽RPCHTTP請求

啓動過程

RPC:Remote Procedure Call Protocol---遠程過程通過協議

它是一種通過網絡從遠程計算機程序上請求服務,而不需要了解底層網絡技術的協議

  1. 系統中數據塊的位置並不是由namenode維護的,而是以塊列表形式存儲在datanode

  2. 在系統的正常操作期間,namenode會在內存中保留所有塊信息的映射信息

  3. fsimage:元數據鏡像文件(保存文件系統的目錄樹)

  4. edit.log:元數據操作日誌(針對目錄樹的修改操作)

兩個重要文件
元數據鏡像

a) 內存中保存一份最新的

b) 內存中鏡像=fsimage+edits

SecondaryNamenode
工作任務

定期合併fsimageedits

c) Edits文件過大將導致NamenNode重啓速度緩慢

d) SecondaryNameNode負責定期合併他們

 

Datanode


hdfs的寫過程


寫過程語言Description:
  1. Client通過調用FileSystemget方法與namenode進程建立通道進行通信,然後調用create方法來請求創建文件。

  2. FileSystem通過對namenode發出遠程請求,在namenode裏面創建一個新的文件,但此時並不關聯任何的塊。NameNode進行很多檢查來保證不存在要創建的文件已經存在文件系統中,同時檢查是否有相應的權限來創建文件。如果這些檢查完了,nameNameNode將這個新文件的嘻嘻記錄下來,然後FileSystem返回一個DFSOutputStream給客戶端用來寫入數據。和讀的情形一樣,FSDataOutputStream將包裝一個DFSOutputStream用於和DataNodeNameNode通信。而一旦文件創建失敗,客戶端會受到一個IOException,標識文件創建失敗,停止後續任務。

  3. 客戶端開始寫數。FSDataOutputStream把要寫入的數據分成塊打成包的形式,將其寫入到DFSOutputStream對象的中間隊列中。其中的數據由Datastreamer來讀取。DataStreamer的職責是讓NameNode分配新的塊找出合適的DataNode來存儲作爲備份而複製的數據。

  4. FSDataOutputStream維護了一個內部關於packets的隊列,裏面存放等待被DataNode確認無誤的packets的信息。這個隊列被稱爲等待隊列,一個packet的信息被移出本隊列當且僅當packet被所有節點都確認無誤。

  5. 當完成數據寫入之後客戶端調用流的close方法,再通知NameNode完成寫入之前,這個方法將flush殘留的packets,並等待確認信息。NameNode已經知道文件由哪些塊組成,所以在返回成功前只需要等待數據塊進行最小複製。

Write API:
1.從本地系統上傳到hdfs

Configuration hdfsConf = new Configuration();//創建一個hdfs的環境變量

String namenodeURI=”hdfs://hadoop001:8020”;//namenode的統一資源定位符

String username=”root”;//訪問指定用戶的hdfs

FileSystem hdfs = FileSystem.get(new URI(namenodeURI),hdfsConf,username);//創建一個hdfs的文件系統對象

FileSystem local = FileSystem.getLocal(new Configuration());//創建一個本地的文件系統對象

hdfs.copyFromLocalFile(new Path(localPath),new Path(hdfsPath));

2.hdfs上創建文件並直接給定文件的內容

FSDateOutputStream out = hdfs.create(new Path(hdfsPath));

out.write(fileContent.getBytes());

out.close();

hdfs的讀過程


讀過程語言Description:
  1. 客戶端或者用戶通過調用FileSystem對象的open方法打開需要讀取的文件,這對HDFS來說是常見一個分佈式文件系統的一個讀取實例。

  2. FileSystem通過遠程協議調用NameNode確定文件的前幾個Block的位置。對於每一個BlockNamenode返回含有那個Block 的“元數據”,即文件基本信息;接下來,DataNode按照上文定義的距離來進行排序,如果Client本身就是一個DataNode優先從本地DataNode讀物數據。HDFS實例完成以上工作後,返回一個FSDataInputStream給客戶端,讓其從FSDataInputStream中讀取數據。FSDataInputStream接着包裝一個DFSInputStream用來管理DataNodeNameNodeI/O

  3. NameNode向客戶端返回一個包含數據信息的地址,客戶端格努詆譭創建一個FSDataInputStream開始對數據進行讀取。

  4. FSDataInputStream根據開始存放的前幾個BlocksDataNode的地址,連接到最近的DataNode上對數據開始從頭讀取。客戶端反覆調用read()方法,以流式方式從DataNode讀取數據

  5. 當讀到Block的結尾的時候,FSDataInputStream會關閉當前DataNode的地址,然後查找能夠讀取下一個Block的最好的DataNode。這些操作對客戶端是透明的,客戶端感覺到的是連續的流,也就是說讀取的時候就開始查找下一個塊所在的地址。

  6. 讀取完成調用close()方法,關閉FSDataInputStream

Read API:
1.hdfs上下載文件到本地

Configuration hdfsConf = new Configuration();//創建一個hdfs的環境變量

String namenodeURI=”hdfs://hadoop001:8020”;//namenode的統一資源定位符

String username=”root”;//訪問指定用戶的hdfs

FileSystem hdfs = FileSystem.get(new URI(namenodeURI),hdfsConf,username);//創建一個hdfs的文件系統對象

FileSystem local = FileSystem.getLocal(new Configuration());//創建一個本地的文件系統對象

hdfs.copyToLocalFile(new Path(hdfsPath),new Path(localPath));

3. hdfs上讀取給定文件的內容

Path path = new Path(hdfsFilePath);//文件路徑

FSDataInputStream in = hdfs.open(path);//獲取文件輸入流

FileStatus status = hdfs.getFileStatus(path);//獲取文件的元數據信息

//獲取文件元數據中的文件大小

byte[] bytes = new byte[Integer.pareInt(String.valueOf(status.getLen()))];

//將輸入流中的全部內容一次性讀取出來

in.readFully(0,bytes);

System.out.println(new String(bytes));//將讀取的文件打印輸出

in.close();

hdfs的整體過程


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章