分布式文件系統(tǒng)(HDFS)

分布式文件系統(tǒng)HDFS(Hadoop Distributed File System)

HDFS的架構(gòu)圖之基礎(chǔ)架構(gòu)

1.NameNode是一個(gè)中心服務(wù)器,單一節(jié)點(diǎn)(簡化系統(tǒng)的設(shè)計(jì)和實(shí)現(xiàn)),負(fù)責(zé)管理文件系統(tǒng)的名字空間(namespace)以及客戶端對(duì)文件的訪問

2.文件操作,namenode是負(fù)責(zé)文件元數(shù)據(jù)的操作,datanode負(fù)責(zé)處理文件內(nèi)容的讀寫請(qǐng)求,跟文件內(nèi)容相關(guān)的數(shù)據(jù)流不經(jīng)過Namenode,只詢問它跟哪個(gè)dataNode聯(lián)系,否則NameNode會(huì)成為系統(tǒng)的瓶頸

3.副本存放在哪些Datanode上由NameNode來控制,根據(jù)全局情況作出塊放置決定,讀取文件時(shí)NameNode盡量讓用戶先讀取最近的副本,降低讀取網(wǎng)絡(luò)開銷和讀取延時(shí)

4.NameNode全權(quán)管理數(shù)據(jù)庫的復(fù)制,它周期性的從集群中的每個(gè)DataNode接收心跳信合和狀態(tài)報(bào)告,接收到心跳信號(hào)意味著DataNode節(jié)點(diǎn)工作正常,塊狀態(tài)報(bào)告包含了一個(gè)該DataNode上所有的數(shù)據(jù)列表

NameNode與Datanode的總結(jié)概述


hdfs的架構(gòu)之文件的文件副本機(jī)制以及block塊存儲(chǔ)

所有的文件都是以block塊的方式存放在HDFS文件系統(tǒng)當(dāng)中,在hadoop1當(dāng)中,文件的block塊默認(rèn)大小是64M,hadoop2當(dāng)中,文件的block塊大小默認(rèn)是128M,block塊的大小可以通過hdfs-site.xml當(dāng)中的配置文件進(jìn)行指定

1.抽象成數(shù)據(jù)塊的好處

(1)一個(gè)文件有可能大于集群中任意一個(gè)磁盤

10T*3/128 = xxx塊 2T,2T,2T 文件方式存—–>多個(gè)block塊,這些block塊屬于一個(gè)文件

(2)使用塊抽象而不是文件可以簡化存儲(chǔ)子系統(tǒng)

(3)塊非常適合用于數(shù)據(jù)備份進(jìn)而提供數(shù)據(jù)容錯(cuò)能力和可用性

2.塊緩存

通常DataNode從磁盤中讀取塊,但對(duì)于訪問頻繁的文件,其對(duì)應(yīng)的塊可能被顯示的緩存在DataNode的內(nèi)存中,以堆外塊緩存的形式存在。默認(rèn)情況下,一個(gè)塊僅緩存在一個(gè)DataNode的內(nèi)存中,當(dāng)然可以針對(duì)每個(gè)文件配置DataNode的數(shù)量。作業(yè)調(diào)度器通過在緩存塊的DataNode上運(yùn)行任務(wù),可以利用塊緩存的優(yōu)勢(shì)提高讀操作的性能。

例如一個(gè)文件130M,會(huì)被切分成2個(gè)block塊,保存在兩個(gè)block塊里面,實(shí)際占用磁盤130M空間,而不是占用256M的磁盤空間

HDFS的元數(shù)據(jù)信息FSimage以及edits和SecondaryNameNode的作用

namenode就一個(gè)的時(shí)候,所有的元數(shù)據(jù)信息都保存在了FsImage與Eidts文件當(dāng)中,這兩個(gè)文件就記錄了所有的數(shù)據(jù)的元數(shù)據(jù)信息,元數(shù)據(jù)信息的保存目錄配置在了hdfs-site.xml當(dāng)中。

客戶端對(duì)hdfs進(jìn)行寫文件時(shí)會(huì)首先被記錄在edits文件中。

edits修改時(shí)元數(shù)據(jù)也會(huì)更新。

每次hdfs更新時(shí)edits先更新后客戶端才會(huì)看到最新信息。

fsimage:是namenode中關(guān)于元數(shù)據(jù)的鏡像,一般稱為檢查點(diǎn)。

一般開始時(shí)對(duì)namenode的操作都放在edits中,為什么不放在fsimage中呢?

因?yàn)閒simage是namenode的完整的鏡像,內(nèi)容很大,如果每次都加載到內(nèi)存的話生成樹狀拓?fù)浣Y(jié)構(gòu),這是非常耗內(nèi)存和CPU。

fsimage內(nèi)容包含了namenode管理下的所有datanode中文件及文件block及block所在的datanode的元數(shù)據(jù)信息。隨著edits內(nèi)容增大,就需要在一定時(shí)間點(diǎn)和fsimage合并。

HDFS的文件寫入過程

1、?client發(fā)起文件上傳請(qǐng)求,通過RPC與NameNode建立通訊,NameNode檢查目標(biāo)文件是否已存在,父目錄是否存在,返回是否可以上傳;

2、?client請(qǐng)求第一個(gè)block該傳輸?shù)侥男〥ataNode服務(wù)器上;

3、?NameNode根據(jù)配置文件中指定的備份數(shù)量及機(jī)架感知原理進(jìn)行文件分配,返回可用的DataNode的地址如:A,B,C;

注:Hadoop在設(shè)計(jì)時(shí)考慮到數(shù)據(jù)的安全與高效,數(shù)據(jù)文件默認(rèn)在HDFS上存放三份,存儲(chǔ)策略為本地一份,同機(jī)架內(nèi)其它某一節(jié)點(diǎn)上一份,不同機(jī)架的某一節(jié)點(diǎn)上一份。

4、?client請(qǐng)求3臺(tái)DataNode中的一臺(tái)A上傳數(shù)據(jù)(本質(zhì)上是一個(gè)RPC調(diào)用,建立pipeline),A收到請(qǐng)求會(huì)繼續(xù)調(diào)用B,然后B調(diào)用C,將整個(gè)pipeline建立完成,后逐級(jí)返回client;

5、?client開始往A上傳第一個(gè)block(先從磁盤讀取數(shù)據(jù)放到一個(gè)本地內(nèi)存緩存),以packet為單位(默認(rèn)64K),A收到一個(gè)packet就會(huì)傳給B,B傳給C;A每傳一個(gè)packet會(huì)放入一個(gè)應(yīng)答隊(duì)列等待應(yīng)答。

6、?數(shù)據(jù)被分割成一個(gè)個(gè)packet數(shù)據(jù)包在pipeline上依次傳輸,在pipeline反方向上,逐個(gè)發(fā)送ack(命令正確應(yīng)答),最終由pipeline中第一個(gè)DataNode節(jié)點(diǎn)A將pipelineack發(fā)送給client;

7、?當(dāng)一個(gè)block傳輸完成之后,client再次請(qǐng)求NameNode上傳第二個(gè)block到服務(wù)器。

HDFS的文件讀取過程

1、 Client向NameNode發(fā)起RPC請(qǐng)求,來確定請(qǐng)求文件block所在的位置;

2、 NameNode會(huì)視情況返回文件的部分或者全部block列表,對(duì)于每個(gè)block,NameNode 都會(huì)返回含有該 block 副本的 DataNode 地址; ?這些返回的 DN 地址,會(huì)按照集群拓?fù)浣Y(jié)構(gòu)得出 DataNode 與客戶端的距離,然后進(jìn)行排序,排序兩個(gè)規(guī)則:網(wǎng)絡(luò)拓?fù)浣Y(jié)構(gòu)中距離 Client 近的排靠前;心跳機(jī)制中超時(shí)匯報(bào)的 DN 狀態(tài)為 STALE,這樣的排靠后;

3、 Client 選取排序靠前的 DataNode 來讀取 block,如果客戶端本身就是DataNode,那么將從本地直接獲取數(shù)據(jù)(短路讀取特性);

4、 底層上本質(zhì)是建立 Socket Stream(FSDataInputStream),重復(fù)的調(diào)用父類 DataInputStream 的 read 方法,直到這個(gè)塊上的數(shù)據(jù)讀取完畢;

5、 當(dāng)讀完列表的 block 后,若文件讀取還沒有結(jié)束,客戶端會(huì)繼續(xù)向NameNode 獲取下一批的 block 列表;

6、 讀取完一個(gè) block 都會(huì)進(jìn)行 checksum 驗(yàn)證,如果讀取DataNode時(shí)出現(xiàn)錯(cuò)誤,客戶端會(huì)通知 NameNode,然后再從下一個(gè)擁有該 block 副本的DataNode 繼續(xù)讀。

7、 read 方法是并行的讀取block信息,不是一塊一塊的讀取;NameNode只是返回Client請(qǐng)求包含塊的DataNode地址,并不是返回請(qǐng)求塊的數(shù)據(jù);

8、 最終讀取來所有的 block 會(huì)合并成一個(gè)完整的最終文件。

HDFS的API操作

在java中操作 HDFS,主要涉及以下 Class:

Configuration:該類的對(duì)象封轉(zhuǎn)了客戶端或者服務(wù)器的配置;FileSystem:該類的對(duì)象是一個(gè)文件系統(tǒng)對(duì)象,可以用該對(duì)象的一些方法來對(duì)文件進(jìn)行操作,通過FileSystem的靜態(tài)方法 get 獲得該對(duì)象。

FileSystem fs = FileSystem.get(conf)

get方法從 conf 中的一個(gè)參數(shù) fs.defaultFS 的配置值判斷具體是什么類型的文件系統(tǒng)。如果我們的代碼中沒有指定 fs.defaultFS,并且工程 classpath下也沒有給定相應(yīng)的配置,conf中的默認(rèn)值就來自于hadoop的jar包中的core-default.xml , 默 認(rèn) 值 為 : file:/// , 則 獲 取 的 將 不 是 一 個(gè)DistributedFileSystem 的實(shí)例,而是一個(gè)本地文件系統(tǒng)的客戶端對(duì)象

例如:

@Test

public void getFileSystem() throws URISyntaxException, IOException {

?Configuration configuration = new Configuration();

?FileSystem fileSystem = FileSystem.get(new URI("hdfs://192.168.52.100:8020"), configuration);

System.out.println(fileSystem.toString());

}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容