Hadoop學習之路(十一)HDFS的讀寫詳解

2022-04-13 14:28:12 字數 4078 閱讀 3380

1、使用 hdfs 提供的客戶端 client,向遠端的 namenode 發起 rpc 請求

2、namenode 會檢查要建立的檔案是否已經存在,建立者是否有許可權進行操作,成功則會 為檔案建立乙個記錄,否則會讓客戶端丟擲異常;

3、當客戶端開始寫入檔案的時候,客戶端會將檔案切分成多個 packets,並在內部以資料佇列「data queue(資料佇列)」的形式管理這些 packets,並向 namenode 申請 blocks,獲 取用來儲存 replicas 的合適的 datanode 列表,列表的大小根據 namenode 中 replication 的設定而定;

4、開始以 pipeline(管道)的形式將 packet 寫入所有的 replicas 中。客戶端把 packet 以流的 方式寫入第乙個 datanode,該 datanode 把該 packet 儲存之後,再將其傳遞給在此 pipeline 中的下乙個 datanode,直到最後乙個 datanode,這種寫資料的方式呈流水線的形式。

5、最後乙個 datanode 成功儲存之後會返回乙個 ack packet(確認佇列),在 pipeline 裡傳遞 至客戶端,在客戶端的開發庫內部維護著"ack queue",成功收到 datanode 返回的 ack packet 後會從"data queue"移除相應的 packet。

6、如果傳輸過程中,有某個 datanode 出現了故障,那麼當前的 pipeline 會被關閉,出現故 障的 datanode 會從當前的 pipeline 中移除,剩餘的 block 會繼續剩下的 datanode 中繼續 以 pipeline 的形式傳輸,同時 namenode 會分配乙個新的 datanode,保持 replicas 設定的 數量。

7、客戶端完成資料的寫入後,會對資料流呼叫 close()方法,關閉資料流;

8、只要寫入了 dfs.replication.min(最小寫入成功的副本數)的複本數(預設為 1),寫操作 就會成功,並且這個塊可以在集群中非同步複製,直到達到其目標複本數(dfs.replication 的預設值為 3),因為 namenode 已經知道檔案由哪些塊組成,所以它在返回成功前只需 要等待資料塊進行最小量的複製。

1、客戶端發起請求:hadoop fs -put hadoop.tar.gz / 

客戶端怎麼知道請求發給那個節點的哪個程序?因為客戶端會提供一些工具來解析出來你所指定的hdfs集群的主節點是誰,以及埠號等資訊,主要是通過uri來確定,

url:hdfs://hadoop1:9000

當前請求會包含乙個非常重要的資訊: 上傳的資料的總大小

2、namenode會響應客戶端的這個請求

namenode的職責:1 管理元資料(抽象目錄樹結構)

使用者上傳的那個檔案在對應的目錄如果存在。那麼hdfs集群應該作何處理,不會處理

使用者上傳的那個檔案要儲存的目錄不存在的話,如果不存在不會建立

2、響應請求

真正的操作:做一系列的校驗,

1、校驗客戶端的請求是否合理

2、校驗客戶端是否有許可權進行上傳

3、如果namenode返回給客戶端的結果是 通過, 那就是允許上傳

namenode會給客戶端返回對應的所有的資料塊的多個副本的存放節點列表,如:

file1_blk1 hadoop02,hadoop03,hadoop04

file1_blk2 hadoop03,hadoop04,hadoop05

4、客戶端在獲取到了namenode返回回來的所有資料塊的多個副本的存放地的資料之後,就可以按照順序逐一進行資料塊的上傳操作

5、對要上傳的資料塊進行邏輯切片

切片分成兩個階段:

1、規劃怎麼切

2、真正的切

物理切片: 1 和 2

邏輯切片: 1

file1_blk1 : file1:0:128

file1_blk2 : file1:128:256

邏輯切片只是規劃了怎麼切

6、開始上傳第乙個資料塊

7、客戶端會做一系列準備操作

1、依次傳送請求去連線對應的datnaode

pipline : client - node1 - node2 - node3

按照乙個個的資料報的形式進行傳送的。

每次傳輸完乙個資料報,每個副本節點都會進行校驗,依次原路給客戶端

2、在客戶端會啟動乙個服務:

使用者就是用來等到將來要在這個pipline資料管道上進行傳輸的資料報的校驗資訊

客戶端就能知道當前從clinet到寫node1,2,3三個節點上去的資料是否都寫入正確和成功

8、clinet會正式的把這個快中的所有packet都寫入到對應的副本節點

1、block是最大的乙個單位,它是最終儲存於datanode上的資料粒度,由dfs.block.size引數決定,2.x版本預設是128m;注:這個引數由客戶端配置決定;如:system.out.println(conf.get("dfs.blocksize"));//結果是134217728

2、packet是中等的乙個單位,它是資料由dfsclient流向datanode的粒度,以dfs.write.packet.size引數為參考值,預設是64k;注:這個引數為參考值,是指真正在進行資料傳輸時,會以它為基準進行調整,調整的原因是乙個packet有特定的結構,調整的目標是這個packet的大小剛好包含結構中的所有成員,同時也保證寫到datanode後當前block的大小不超過設定值;

如:system.out.println(conf.get("dfs.write.packet.size"));//結果是65536

3、chunk是最小的乙個單位,它是dfsclient到datanode資料傳輸中進行資料校驗的粒度,由io.bytes.per.checksum引數決定,預設是512b,因而chunk寫入packet時是516b;資料與檢驗值的比值為128:1,所以對於乙個128m的block會有乙個1m的校驗檔案與之對應;

如:system.out.println(conf.get("io.bytes.per.checksum"));//結果是512

9、clinet進行校驗,如果校驗通過,表示該資料塊寫入成功

10、重複7 8 9 三個操作,來繼續上傳其他的資料塊

11、客戶端在意識到所有的資料塊都寫入成功之後,會給namenode傳送乙個反饋,就是告訴namenode當前客戶端上傳的資料已經成功。

1、客戶端呼叫filesystem 例項的open 方法,獲得這個檔案對應的輸入流inputstream。

2、通過rpc 遠端呼叫namenode ,獲得namenode 中此檔案對應的資料塊儲存位置,包括這個檔案的副本的儲存位置( 主要是各datanode的位址) 。

3、獲得輸入流之後,客戶端呼叫read 方法讀取資料。選擇最近的datanode 建立連線並讀取資料。

5、到達資料塊末端,關閉與這個datanode 的連線,然後重新查詢下乙個資料塊。

6、不斷執行第2 - 5 步直到資料全部讀完。

7、客戶端呼叫close ,關閉輸入流df s inputstream。

Hadoop學習之路

hadoop是谷歌的集群系統的開源實現 google集群系統 gfs mapreduce bigtable hadoop主要由hdfs hadoop distrubuted file system mapreduce和hbase組成。hadoop的初衷是為解決nutch的海量資料爬取和儲存的需要 h...

小強的Hadoop學習之路

本人一直在做net開發,接觸這行有6年了吧。畢業也快四年了 6年是因為大學就開始在一家小公司做門戶 哈哈哈 之前一直秉承著學要精,就一直一門心思的在做net 也是懶吧 最近的工作一直都和大資料清洗相關,想著要學學真正的大資料懶,不然都不好意思說自己是做資料清洗的。目前關於hadoop的學習資料已經非...

Hadoop之Flume採集檔案到hdfs

內容如下 定義三大元件的名稱,myagent可以自己定義 myagent.sources source1 myagent.sinks sink1 myagent.channels channel1 配置source元件 myagent.sources.source1.type spooldir 定義...