HDFS原理學(xué)習(xí)筆記

一、HDFS概述

HDFS的是一個Master/Slave分布式系統(tǒng)(NameNode是主節(jié)點,DataNode是從節(jié)點)


1.數(shù)據(jù)塊(Block):

數(shù)據(jù)塊的默認(rèn)大小是128MB,HDFS將數(shù)據(jù)塊的冗余備份(默認(rèn)冗余3份)保存到不同的數(shù)據(jù)節(jié)點上,

2.NameNode

NameNode負(fù)責(zé)管理文件系統(tǒng)的命名空間(包括文件系統(tǒng)目錄樹、文件/目錄信息和文件的數(shù)據(jù)庫索引,這些信息以文件的形式永久保存在NameNode的本地磁盤)以及數(shù)據(jù)塊到具體DataNode節(jié)點的映射等信息(這部分?jǐn)?shù)據(jù)不保存在NameNode本地磁盤上,而是在NameNode啟動時動態(tài)構(gòu)建的)。

3.DataNode

DataNode會不斷地向NameNode發(fā)送心跳,數(shù)據(jù)塊匯報和緩存匯報,NameNode可以向DataNode發(fā)送指令,如創(chuàng)建、刪除或復(fù)制數(shù)據(jù)。

二、Hadoop RPC

RPC(Remote Procedure CallProtocol)允許本地程序像調(diào)用本地方法一樣調(diào)用遠程機器上應(yīng)用程序的應(yīng)用服務(wù),Hadoop底層通過JavaNIO、Java動態(tài)代理和Protobuf等實現(xiàn)。


2.1 Hadoop RPC的實現(xiàn)步驟:

1.定義RPC協(xié)議:

即定義客戶端和服務(wù)器之間的RPC調(diào)用的接口,這樣客戶端就知道Server提供了那些服務(wù);

2.實現(xiàn)RPC協(xié)議:

即服務(wù)端程序需要實現(xiàn)RPC協(xié)議,對RPC請求能夠做響應(yīng)的處理;

3.客戶端獲取代理對象:

客戶端使用RPC.getProtocolProxy()獲取一個RPC協(xié)議的代理對象,然后通過代理對象調(diào)用RPC協(xié)議的方法(通過JAVA動態(tài)代理機制);

4.服務(wù)器構(gòu)造并啟動RPC Server:

服務(wù)器通過調(diào)用RPC.Builder.build()方法構(gòu)造Server對象,然后start來啟用server對象來相應(yīng)客戶端的RPC請求。

2.2 客戶端獲取Proxy對象

DFSClient通過ProxyInfo類來調(diào)用NameNodeProxies.createProxy()方法創(chuàng)建代理(默認(rèn)使用ProtobufRpcEngine序列化引擎實現(xiàn)),根據(jù)Hadoop的配置判斷當(dāng)前HDFS是否是HA模式。

1.非HA模式:

客戶端通過createProxy() 調(diào)用createNonHaProxy()創(chuàng)建普通的ClientProtocol對象;

2.HA模式(即兩個NameNode實例):

DFSClient通過代理對象發(fā)送請求后,代理對象來講請求發(fā)送到Active NameNode,如果連接失敗則會重試,重試達到一定的次數(shù)后,DFSClient的代理對象又將請求發(fā)送給StandBy NameNode。

2.3 服務(wù)器獲取Rpc Server對象

NameNodeRpcServer實現(xiàn)了ClientProtocol、NameNodeProtocol、DataNodeProtocol和HAServiceProtocol在內(nèi)的所有需要與Namenode進行交互的RPC協(xié)議接口。Namenode主要構(gòu)造兩個RPC Server,即ClientRpcServer(負(fù)責(zé)相應(yīng)HDFS的客戶端的RPC請求)和ServiceRpcServer(負(fù)責(zé)相應(yīng)Datanode的RPC請求)

三、Namenode

HDFS文件系統(tǒng)的命名空間是在Namenode的內(nèi)存中以樹的結(jié)構(gòu)來存儲的,不管是目錄還是文件,都被當(dāng)做INode節(jié)點。如果是目錄,則對應(yīng)的類為INodeDirectory(包含一個成員集合變量children);如果是文件,則對應(yīng)的類為INodeFile。INodeDirectory和INodeFile是INode的派生類。

1.INode類

1.1 INode繼承的方法
(繼承自INodeAttribute接口的get方法userName/groupName/fsPermission/aclFeature/modificationTime/accessTime/XAttrFeature);
1.2 INode自帶的屬性方法(id、name、fullPathName、parent)和方法(isFile/isDirectory/isSymlink/isRoot)

2.INodeDirectory類

是HDFS的虛擬容器,主要處理器屬性children的增刪改查以及Feature和快照的處理方法等。

3.INodeFile類

INodeFIle類保存了文件頭header字段(保存了當(dāng)前文件的副本數(shù)和文件數(shù)據(jù)塊的大?。┖臀募?yīng)的數(shù)據(jù)庫塊信息blocks字段(一個BlockInfo類型的數(shù)據(jù),保存當(dāng)前文件對應(yīng)的所有數(shù)據(jù)塊信息)

private long header = 0L;  
  // 前4個比特用于保存存儲策略,中間12個比特保存文件備份系數(shù),后48個比特用戶保存數(shù)據(jù)塊的大小
private BlockInfo[] blocks;
// 保存數(shù)據(jù)塊與文件,數(shù)據(jù)塊與數(shù)據(jù)節(jié)點的對應(yīng)關(guān)系,即獲取數(shù)據(jù)塊所屬的INodeFile文件和數(shù)據(jù)塊副本的所有數(shù)據(jù)節(jié)點信息

INodeFile的主要方法,構(gòu)建(Under Construction)/快照(snapshot)等

4.INodeReference類

當(dāng)HDFS文件/目錄處于某個快照中,當(dāng)這個文件/目錄被重命名或者移動到其他路徑時,該文件/目錄通過快照訪問的路徑不會斷開,仍然可以通過快照訪問。如下圖:用戶可以通過/abc/foo以及/abc/snapshot/s0/foo訪問foo文件

當(dāng)用戶將/abc/foo重命名為/xyz/bar時,用戶可以通過/xyz/foo以及/abc/snapshot/s0/foo訪問foo文件


5.Feature類

Feature主要對應(yīng)的子類:


1.SnapshotFeature快照特性

快照是一個文件系統(tǒng)或者是某個目錄在某一時刻的鏡像,當(dāng)創(chuàng)建目標(biāo)目錄的快照之后,不論目標(biāo)目錄或者目標(biāo)目錄的子目錄發(fā)生任何變化,都可以通過快照找回快照建立時的目標(biāo)目錄的所有文件及目錄結(jié)構(gòu)。
如圖下圖快照



說明:對目錄a創(chuàng)建了快照s1和快照s2,DirectoryDiff記錄快照創(chuàng)建之后目錄a上執(zhí)行的所有操作(其中ChildrenDiff對象的c-list集合保存了快照創(chuàng)建之后所有新添加的文件或目錄,ChildrenDiff對象的d-list集合保存了快照創(chuàng)建之后所有刪除的文件或目錄,修改的元素同時放入c-list和d-list)。這樣HDFS通過s1訪問e時仍然可以訪問到,但HDFS通過快照s2訪問g時,則會返回空,因為g在c-list中,是新建的文件,表明s2創(chuàng)建時目錄下還沒有這個g文件。

6.FSEditLog類

NameNode將命名空間(namespace:文件系統(tǒng)的目錄樹、文件元數(shù)據(jù)等信息)記錄在fsimage的二進制文件中,fsimage將文件系統(tǒng)目錄樹中的每個文件或者目錄的信息保存為一條記錄(包括文件或者目錄的名稱、大小、用戶、用戶組、修改時間、創(chuàng)建時間等信息)。Namenode重啟時會讀取fsimage文件來重構(gòu)命名空間。但是fsimage始終是磁盤上的一個文件,不可能時時刻刻跟進Namenode內(nèi)存中的數(shù)據(jù)結(jié)構(gòu)保存同步,而且fsimage文件一般都很大(GB級別很常見),如果所有的更新操作都實時的寫入fsimage文件,會導(dǎo)致Namenode運行緩慢,所以HDFS每隔一段時間才更新一次fsimage文件。為解決操作記錄實時同步的問題,HDFS客戶端執(zhí)行的所有寫操作都會首先記錄保存到editlog文件中,HDFS定期地將editlog與fsimage文件合并,以保持fsimage跟Namenode內(nèi)存中記錄的namespace完全同步。

1.logEdit的同步實現(xiàn):

logEdit成功的獲取transactionId(每次遞增1)之后,比較這個transactionId和editlog文件中的transactionId,如果當(dāng)前線程的transactionId大于editlog文件中的transactionId,則表明editlog中的文件記錄的不是最新的數(shù)據(jù)。通過輸出流暫存到緩存區(qū)中,當(dāng)logEdit方法將一個完整的操作寫入到數(shù)據(jù)流后,調(diào)用logSync方法同步當(dāng)前線程對editlog文件所做的修改。

clipboard1.png

7.FSImage類

主要負(fù)責(zé)功能:
1.保存Namenode內(nèi)存中的namespace到fsimage文件中;
2.加載磁盤上的fsimage文件中保存的namespace到Namenode的內(nèi)存中;
3.加載editlog文件到Namenode內(nèi)存中。

8.數(shù)據(jù)塊管理:
Namenode定期將文件系統(tǒng)目錄樹和文件與數(shù)據(jù)塊的對應(yīng)關(guān)系保存到fsimage文件中,但fsimage不會保存數(shù)據(jù)塊和數(shù)據(jù)節(jié)點的對應(yīng)關(guān)系,這部分?jǐn)?shù)據(jù)是由Datanode主動將自己保存的數(shù)據(jù)塊信息匯報給Namenode。

clipboard2.png

1. Block類

public class Block implements Writable, Comparable<Block> {
private long blockId; // 唯一標(biāo)示Block對象
private long numBytes; // 數(shù)據(jù)塊的大小,單位是字節(jié)
private long generationStamp; // 這個數(shù)據(jù)塊的時間戳
}

數(shù)據(jù)跨block的問題:
每個block有128MB,如果有三個block,分別為block1,block2和block3,有一行數(shù)據(jù)(比如這行數(shù)據(jù)比較長)跨了block1和block2,那么在讀取block1數(shù)據(jù)的時候,hadoop會在讀完block1之后,接著讀取block2,讀完block2之后再返回,下次接著讀取的時候,跳過block2,直接讀取block3。

2.BlockIndo類

bc字段保存了該數(shù)據(jù)塊歸屬于那個HDFS文件,即INode的引用;
triplets保存了數(shù)據(jù)塊的副本存儲在那些數(shù)據(jù)節(jié)點上,triplets數(shù)據(jù)有3 * replication個元素,假設(shè)i為第i個保存該數(shù)據(jù)塊副本的Datanode,那么triplets[3*i]是保存這個數(shù)據(jù)塊副本的第i個Datanode上的DatanodeStoreInfo對象

3.BlocksMap類
class BlocksMap {
private final int capacity;
private GSet<Block, BlockInfo> blocks; // 保存數(shù)據(jù)塊與保存這個數(shù)據(jù)塊的數(shù)據(jù)節(jié)點的對應(yīng)關(guān)系,因此可以獲取某個數(shù)據(jù)塊對應(yīng)的HDFS文件,還可以獲取數(shù)據(jù)塊保存在那些節(jié)點上.
}

8.BlockManager 類

public class BlockManager { 
// 損壞的數(shù)據(jù)塊副本集合
final CorruptReplicasMap corruptReplicas = new CorruptReplicasMap();
//等待刪除的數(shù)據(jù)塊副本集合
private final InvalidateBlocks invalidateBlocks;
// 推遲操作的數(shù)據(jù)塊副本集合
private final Set<Block> postponedMisreplicatedBlocks = Sets.newHashSet();
//多余的數(shù)據(jù)塊副本集合
public final Map<String, LightWeightLinkedSet<Block>> excessReplicateMap =
  new TreeMap<String, LightWeightLinkedSet<Block>>();
// 等待復(fù)制的數(shù)據(jù)塊副本集合
public final UnderReplicatedBlocks neededReplications = new UnderReplicatedBlocks();
// 已經(jīng)生成復(fù)制請求的數(shù)據(jù)塊副本
final PendingReplicationBlocks pendingReplications;
}
23rwerae.png

9.數(shù)據(jù)塊匯報:

1.DataNode啟動后,會與Namenode握手、注冊以及向Namenode發(fā)送第一次全量塊匯報(即Datanode上存儲的所有副本信息),之后Datanode會定期(默認(rèn)6個小時)向Namenode發(fā)送全量匯報,同時會以心跳間隔(默認(rèn)為3秒)的100倍時間間隔向Namenode發(fā)送增量匯報(即Datanode最近新添加的以及刪除的副本信息),這樣就針對增量匯報異?;蛘咧噶顏G失的情況發(fā)生時,能夠保證Namenode獲取Datanode保存的所有副本的信息。
為了提高HDFS的啟動速度,Namenode會將Datanode的全量匯報分成兩種第一次發(fā)送全量塊匯報(這時Namenode不計算要刪除的元數(shù)據(jù)和無效副本)和周期性的全量塊匯報。

10. Datanode的心跳

Datanode會以一定的間隔想Namenode發(fā)送心跳信息(Datanode的注冊信息、Datanode存儲信息、緩存信息、當(dāng)前Datanode的寫文件的連接數(shù)、讀寫數(shù)據(jù)使用的線程數(shù)據(jù)等),Namenode收到Datanode的心跳后,返回一個心跳相應(yīng),心跳相應(yīng)中包含了DatanodeCommand的數(shù)組,用來攜帶Namenode對Datanode的指令(數(shù)據(jù)塊副本的復(fù)制、刪除、緩存等)。

Namenode會啟動一個線程,負(fù)責(zé)周期性地檢測所有Datanode上報的心跳情況,對于長時間沒有上報心跳的Datanode,會刪除該Datanode。

10.HDFS緩存

HDFS機制中緩存是由分布在Datanode上的堆外內(nèi)存組成,并且有Namenode統(tǒng)一管理。Datanode會會周期性的向Namenode發(fā)送緩存報告,而Namenode會通過心跳相應(yīng)想Datanode下發(fā)緩存指令。

11. HDFS的HA架構(gòu)

HA(High Availability)架構(gòu)可以解決單節(jié)點故障問題,在一個HA集群中,會配置兩個獨立的Namenode。任意時刻,一個節(jié)點作為活動節(jié)點,另外一個處理備份狀態(tài)?;顒拥腘amenode負(fù)責(zé)執(zhí)行所有的修改namespace和刪除備份數(shù)據(jù)塊的操作,而備份的Namenode則執(zhí)行同步操作,保持與活動節(jié)點namespace的一致性(通過監(jiān)聽editlog改動,讀取并合并到當(dāng)前的namespace中)。另外,所有的Namenode會同時向這兩個Namenode發(fā)送心跳以及塊匯報信息(備份Namenode不會向Datanode發(fā)送指令(數(shù)據(jù)塊副本的復(fù)制、刪除、緩存等)),這樣活動NameNode和備份Namenode的元數(shù)據(jù)就會完全同步了,實現(xiàn)了熱備份。

四、Datanode

werweard.png

未完待續(xù)......

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

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

  • Zookeeper用于集群主備切換。 YARN讓集群具備更好的擴展性。 Spark沒有存儲能力。 Spark的Ma...
    Yobhel閱讀 7,605評論 0 34
  • 本文是對HDFS技術(shù)的一個初步學(xué)習(xí)的總結(jié),包括如下章節(jié)的內(nèi)容: 概述 架構(gòu) 命令行接口 常見HDFS命令 遠程訪問...
    我是老薛閱讀 1,436評論 0 2
  • HDFS是Hadoop Distribute File System 的簡稱,也就是Hadoop的一個分布式文件系...
    大佛愛讀書閱讀 975評論 0 0
  • 2016年6月11日的傍晚,河北省燕趙一小城公園門口處舞臺高搭、載歌載舞、人聲鼎沸,是為紀(jì)念陽光愛心社成立...
    夢醉西樓88閱讀 195評論 0 0
  • 三番佳肴落一檀,伊人唇齒未有貪。拂手又念夫君憨,卷簾方見眉目甘。 纖指蘭花傾玉簪,月灑湖畔珠光染。顏若霜沾淺見寒,...
    梵文米娜閱讀 231評論 0 1

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