hdfs簡介
hdfs是hadoop中分布式的文件存儲系統(tǒng);具有高容錯仁卷、可擴展;廣泛的用于大數(shù)據(jù)項目中(不僅僅是hadoop)
優(yōu)點
- 容錯性高
- 數(shù)據(jù)自動保存多個副本(可設(shè)置)
- 副本丟失后,自動恢復(fù)
- 適合批處理
- 移動計算而非移動數(shù)據(jù)
- 數(shù)據(jù)位置暴露給計算框架
- 適合大數(shù)據(jù)處理
- GB峰弹、TB回怜、甚至PB級數(shù)據(jù)
- 百萬規(guī)模以上的文件數(shù)量
- 10K+節(jié)點
- 可以搭建在廉價的服務(wù)器上
- 通過副本提高可靠性
- 提高了容錯和恢復(fù)機制
缺點
- 無法做到低延遲數(shù)據(jù)訪問(比如毫秒級別的)
- 不適合處理小文件
- 占用namenode大量內(nèi)存
- 尋道時間會比較長(可能占整個讀時間的80-90%)
- 并發(fā)寫入大年、文件隨機修改
-一個文件只能有一個寫者- 不支持文件的修改(2.X版本中增加了append功能,不過在生產(chǎn)環(huán)境中玉雾,絕對不會開啟該功能翔试,代價太大)
hdfs架構(gòu)
這個是1.x版本的架構(gòu)圖
NameNode
namenode主要功能是接受客戶端的讀寫請求,和管理metadata信息复旬;
- NameNode保存metadata信息包括
- 文件權(quán)限(permissions)
- 文件包含哪些塊
- Block保存在哪個DataNode(DataNode啟動時上報)
- NameNode的metadata信息會在啟動后加載到內(nèi)存中
- metadata持久化后的文件名為 fsimage
- block的位置信息不回保存到fsimage(由DataNode上報)
- edits記錄的是對metadata的操作日志
- NameNode啟動時垦缅,會將fsimage文件加載到內(nèi)存中,并將edits文件執(zhí)行一遍驹碍。這樣內(nèi)存中的文件就是最新的了壁涎。(注意:此時會將內(nèi)存中的信息持久化到fsimage文件中)
Secondary NameNode
首先需要明白一點,Secondary NameNode不是NameNode的副本(可以充當(dāng)副本的作用)志秃;
主要作用是幫助Namenode合并fsimage怔球、edits文件;在NameNode介紹中洽损,提到NameNode啟動時會將fsimage加載到內(nèi)存中庞溜,并將edits文件執(zhí)行一遍。這里會有個問題,如果系統(tǒng)運行的時間很長流码,那edits文件會非常巨大又官,那NameNode啟動的時間就會非常長(簡稱安全模式,后面會說到)漫试。
因此就出現(xiàn)了Secondary NameNode六敬;工作原理如下:
- Secondary NameNode會將NameNode上的edits和fsimage文件通過http get的方式拉取過來,NameNode會生成edits.new文件記錄接下來的操作
- SNN會將fsimage文件加載到內(nèi)存中驾荣,并執(zhí)行edits文件生成fsimage.ckpt文件
- SNN用http post方式將生成的fsimage.ckpt文件發(fā)送個NameNode文件
- NN會將fsimage文件更名為fsimage外构,edits.new更名為 edits
如何會觸發(fā)這個合并操作?
有兩個指標(biāo)播掷,一個是edits文件的大小审编,一個是時間
- dfs.namenode.checkpoint.period 默認是一個小時
- dfs.namenode.checkpoint.txns 默認是1 million,沒有合并的transactions的次數(shù)
如果在這個過程中NN節(jié)點掛掉了歧匈,會不會造成數(shù)據(jù)丟失呢垒酬?
如果只是斷電,服務(wù)器沒有損壞件炉,數(shù)據(jù)是不會丟失的勘究,edits.new會持久化到磁盤中;如果服務(wù)器徹底壞了斟冕,那edits.new中的數(shù)據(jù)就會丟失口糕。
這里有個問題需要注意下:NameNode中edits文件是實時更新的,相當(dāng)于日志文件磕蛇,而fsimage不是實時更新的景描,合并操作完之后,才會持久化到硬盤中秀撇。 也就是說只有兩個時機才回持久化fsimage文件伏伯,一是啟動hdfs時,NameNode在安全模式下合并fsimage文件捌袜,二是Secondary NameNode合并之后说搅,post給NameNode時。
DataNode
- 存儲數(shù)據(jù)(block)
- 啟動DN線程的時候向NN匯報block信息
- 通過向NN發(fā)送心跳保持聯(lián)系(3秒一次)虏等,如果NN10分鐘沒有收到DN的心跳弄唧,則認為DN已經(jīng)lost,并copy其上的block到其他的DN節(jié)點
高容錯性
這里單獨講一下霍衫,hdfs高容錯性是如何實現(xiàn)的候引;后面很多知識都是和它相關(guān)的。高容錯體現(xiàn)在hdfs會對數(shù)據(jù)有個備份敦跌,hdfs默認是>=3個副本數(shù)澄干。
如果需要修改副本數(shù)逛揩,可以修改dfs.replication參數(shù)
<property>
<name>dfs.replication</name>
<value>3</value>
</property>
hdfs會對文件進行拆分,按block進行拆分麸俘,1.x中每個block默認大小是64M辩稽,2.X中每個block默認大小是128M。也就是說一個文件是由多個block塊組成从媚。這里需要注意的是:block是一個邏輯的概念逞泄,一個129M的文件,會占用兩個block(假設(shè)block是128M)拜效,但是這個文件占用的空間還是129M喷众,不會占用256M的空間。
block放置的策略是:
- 首先會選擇一臺負載較輕紧憾,網(wǎng)絡(luò)比較好的機器放置第一個副本
- 第二副本會放在和第一臺不同的機架上
- 第三個副本一般來說會和第二個在同一個機架到千,不同服務(wù)器上。能減少網(wǎng)絡(luò)的IO
- 后面的副本隨機放置赴穗。
這個放置策略可以很好避免數(shù)據(jù)丟失的情況父阻,如果某個節(jié)點掛了,hdfs會對該節(jié)點的上block都復(fù)制一份望抽。如果該節(jié)點恢復(fù)了,hdfs不會對復(fù)制過block進行刪除操作履婉。
安全模式
安全模式是hdfs啟動時煤篙,進行一些初始化的工作;這段時間毁腿;安全模式期間NN處于一個read-only狀態(tài)辑奈,無法進行任何更新操作。
安全模式主要做的事是NN將fsimage文件加載內(nèi)存已烤,將edits文件執(zhí)行一遍鸠窗,進行合并,生成新的fsimage文件胯究,并將其持久化到硬盤中稍计;NN只有在啟動的時候才會去合并fsimage和edits文件。NN還會等待DN上報它的block信息裕循;當(dāng)hdfs中的大部分block都是可用的時候臣嚣;hdfs會自動退出安全模式;可以顯示指定 dfsadmin -safemode進入安全模式剥哑。
恢復(fù)模式
如果metadata數(shù)據(jù)只有一份硅则,并且已經(jīng)損壞了;我們可以用Recovery mode啟動NN株婴,這可以恢復(fù)大部分數(shù)據(jù)怎虫。
命令是
namenode -recover
這里會有很多步,每步都會有一些選項;可以加上 -force參數(shù)大审;這樣每次都會選擇第一個蘸际。
注意:Recovery mode 可能會造成數(shù)據(jù)的丟失;所以建議進入Recovery模式之前饥努,先備份fsimage和edits文件捡鱼。
寫流程
- 首先創(chuàng)建FileSystem,和hdfs打交道酷愧,基本上都是通過FileSystem驾诈;FileSystem調(diào)用create接口向NameNode發(fā)送請求,NameNode會進行權(quán)限的檢查溶浴,以及文件目錄是否已經(jīng)存在乍迄,父目錄是否存在等檢查。
- 第一步NameNode會返回是否可以上傳
- client先對文件進行切分士败,如果block是128M闯两,200M的文件會切分成128和72M的兩個block塊。client會首先請求NameNode第一個block塊應(yīng)該存放到那個DataNode上谅将。NameNode會返回一些DataNode
- client會選擇一個負載較輕漾狼,網(wǎng)絡(luò)較好的DataNode上傳數(shù)據(jù),RPC調(diào)用饥臂,會建立pipeline進行傳輸逊躁,第一個DataNode接收請求,會調(diào)用第二個DataNode隅熙,然后第二個調(diào)用第三個DataNode稽煤,這樣整個pipeline就建立好了。然后寫入數(shù)據(jù)(以packet為單位囚戚,每個packet為64kb)
- 第一臺DataNode收到一個packet之后酵熙,就會發(fā)送給第二臺DataNode,第二臺發(fā)給第三臺驰坊。然后第三臺應(yīng)答匾二,報告收據(jù)接收完成。重復(fù)第五步直到block寫入完成
- 然后client寫另外的block(必須在之前的block寫入完成之后拳芙,才能寫下一個block假勿,而且必須是按順序的)
- 寫入完成之后,告訴NameNode寫入完畢态鳖,然后NameNode更新元數(shù)據(jù)信息
讀流程
- 第一步還是通過FileSystem和NameNode進行交互转培。通過open方法(也會有文件是否存在的,是否有權(quán)限的一些驗證)浆竭,得到文件block的位置信息(在哪些DataNode節(jié)點上)
- client通過FSDataInputStream進行讀取浸须。
- client選擇合適一臺DataNode進行讀取block惨寿。
- 上一個block讀取完之后,再讀下一個block(一定是上一個讀取完了之后删窒,才會讀下一個裂垦,而且必須是按順序來的),直到所有的block讀取完畢