Hadoop系列之HDFS初識(shí)、理論基礎(chǔ)與讀寫流程

1 HDFS初識(shí)

考慮這樣一個(gè)問題:文件切成很多小文件塊散列存儲(chǔ)在集群中時(shí),是如何知道每個(gè)小文件塊存儲(chǔ)的位置的呢?讓我們舉個(gè)例子來(lái)解釋一下,假設(shè)現(xiàn)在有100臺(tái)機(jī)器,如果有10個(gè)人拿著10批數(shù)據(jù)過來(lái)存儲(chǔ),那么他們可能會(huì)找到不同的人把他們的數(shù)據(jù)各自存儲(chǔ)在不同的機(jī)器上,過了10天之后,這些人想要取回他們的數(shù)據(jù),但是他們忘了自己的數(shù)據(jù)存儲(chǔ)在誰(shuí)那里了,那么這些數(shù)據(jù)就取不回來(lái)了。那么該如何解決這個(gè)問題呢?我們可以單獨(dú)拿出一臺(tái)機(jī)器用于記錄,那么每當(dāng)有人要存儲(chǔ)數(shù)據(jù)的時(shí)候,都先找到這臺(tái)機(jī)器,然后這臺(tái)機(jī)器會(huì)告訴他將數(shù)據(jù)存儲(chǔ)在哪,這個(gè)詢問的過程是很快的,每個(gè)人問完之后就會(huì)拿著數(shù)據(jù)去存儲(chǔ),然后下一個(gè)人過來(lái)接著問...如果這個(gè)例子你能聽懂,那么恭喜你,HDFS你已經(jīng)學(xué)會(huì)了。上述的過程其實(shí)就是指的HDFS中的NameNode和DataNode各司其職的過程,DataNode用于存儲(chǔ)數(shù)據(jù),而NameNode用于存儲(chǔ)文件的元數(shù)據(jù)描述信息。讓我們來(lái)進(jìn)一步思考一下,如果把上述例子中的文件數(shù)據(jù)換成一張一張的一百塊錢,比如有個(gè)人過來(lái)要存100塊錢,我說(shuō)你去張三那存吧,這時(shí)候我應(yīng)該立刻寫下誰(shuí)誰(shuí)誰(shuí)的100塊錢存在張三那了嗎?這是不可能的,因?yàn)橛锌赡芪矣浲曛筮@個(gè)人沒去張三那存,如果我記下了這筆帳,那個(gè)人回來(lái)找我取回那100塊錢,我讓他去張三那,那張三就有苦說(shuō)不出了,這就是所謂的數(shù)據(jù)一致性問題。數(shù)據(jù)的一致性問題一定是要非常小心的,尤其是在分布式、多節(jié)點(diǎn)多人協(xié)作的情況下。因此在上面的例子中,一定是要張三給我發(fā)送一個(gè)確認(rèn)的回報(bào)之后,我才能把這個(gè)100塊錢給記錄下來(lái)的。HDFS就是這樣一個(gè)用多個(gè)節(jié)點(diǎn)散列未來(lái)要存儲(chǔ)的數(shù)據(jù),然后用一個(gè)主節(jié)點(diǎn)進(jìn)行記賬的分布式文件系統(tǒng)。此外,記賬這件事情,一個(gè)人可以做,兩個(gè)人也可以做,但是兩個(gè)人記賬中面臨的數(shù)據(jù)一致性問題會(huì)更加復(fù)雜(兩個(gè)人之間同步信息),因此HDFS采用了一主的架構(gòu)。

分布式文件系統(tǒng)那么多,為什么hadoop項(xiàng)目中還要開發(fā)一個(gè)hdfs文件系統(tǒng)?
我們知道,在hadoop項(xiàng)目里面除了hdfs文件系統(tǒng)模塊之外,還有另外一個(gè)很重要的用于計(jì)算的模塊,因此我們可以推測(cè)出,hdfs一定會(huì)具備一個(gè)特征:它能更好的支持分布式計(jì)算。

2 HDFS理論知識(shí)點(diǎn)

  • 存儲(chǔ)模型
  • 架構(gòu)設(shè)計(jì)
  • 角色功能
  • 元數(shù)據(jù)持久化
  • 安全模式
  • 副本放置策略
  • 讀寫流程
  • 安全策略

2.1 存儲(chǔ)模型

  • 文件線性按字節(jié)切割成塊(block),具有offset,id
    • offset就是指偏移量,文件的第一個(gè)block塊偏移量為0,后續(xù)block塊的偏移量可以通過block塊的大小來(lái)計(jì)算,只要有了offset,就能把所有的block塊拼成一個(gè)完整的文件。
    • id標(biāo)識(shí)了每個(gè)block塊的名字,用于映射
  • 文件與文件的block大小可以不一樣
  • 一個(gè)文件除最后一個(gè)block,其他block大小一致
    • 比如block大小為4個(gè)字節(jié),而最后一個(gè)block塊的大小可能不夠4個(gè)字節(jié)
  • block的大小依據(jù)硬件的I/O特性調(diào)整
  • block被分散存放在集群的節(jié)點(diǎn)中,具有l(wèi)ocation(block塊所在節(jié)點(diǎn)的位置)
  • Block具有副本(replication),沒有主從概念,副本不能出現(xiàn)在同一個(gè)節(jié)點(diǎn)中
    • 如果副本放在一個(gè)節(jié)點(diǎn)中,那么如果這個(gè)節(jié)點(diǎn)掛掉了,所有副本都讀取不到了
  • 副本是滿足可靠性和性能的關(guān)鍵
  • 文件上傳可以指定block大小和副本數(shù),上傳后只能修改副本數(shù)
  • 一次寫入多次讀取,不支持修改
    • 比如在文件中增加一些內(nèi)容,這會(huì)導(dǎo)致修改位置所在的block大小變大,這時(shí)候會(huì)將這個(gè)block塊中多出來(lái)的內(nèi)容轉(zhuǎn)移到下一個(gè)block塊中,而這又會(huì)導(dǎo)致下一個(gè)block塊大小變大...這是一個(gè)泛洪的操作,這會(huì)導(dǎo)致集群中很多的節(jié)點(diǎn),它們的CPU、內(nèi)存、網(wǎng)卡會(huì)參與到因?yàn)橐粋€(gè)修改的事情而造成的資源的高度使用,網(wǎng)絡(luò)一直被瘋狂的傳輸數(shù)據(jù),因此hdfs設(shè)計(jì)者做了一個(gè)折中的方案,就是hdfs作為一個(gè)文件系統(tǒng),它可以存,可以讀,可以批量計(jì)算,它可以支持很多程序進(jìn)行計(jì)算,它可以讓每個(gè)程序都跑得很快,但是它不支持修改。
  • 支持追加數(shù)據(jù)
    • 追加數(shù)據(jù)只是在文件的最后一個(gè)block塊中添加內(nèi)容,或者是在文件的最后添加block塊,因此是可以支持的。

無(wú)論是什么文件,在計(jì)算機(jī)中存儲(chǔ)的都是二進(jìn)制,二進(jìn)制在計(jì)算機(jī)中就是一個(gè)個(gè)二進(jìn)制位,但是在計(jì)算機(jī)中,一般很少用二進(jìn)制位去描述文件,而是會(huì)用字節(jié)去描述,我們看到的文件大小一般都是用字節(jié)作為單位的,文件本質(zhì)上都是字節(jié)數(shù)組。

2.2 架構(gòu)設(shè)計(jì)

  • HDFS是一個(gè)主從(Master/Slaves)架構(gòu)
  • 由一個(gè)NameNode(主)和一些DataNode(從)組成
  • 面向文件包含:文件數(shù)據(jù)(data)和文件元數(shù)據(jù)(metadata)
  • NameNode負(fù)責(zé)存儲(chǔ)和管理文件元數(shù)據(jù),并維護(hù)了一個(gè)層次型的文件目錄樹
  • DataNode負(fù)責(zé)存儲(chǔ)文件數(shù)據(jù)(block塊),并提供block的讀寫
  • DataNode與NameNode維持心跳,并匯報(bào)自己持有的block信息
  • Client和NameNode交互文件元數(shù)據(jù)、和DataNode交互文件block數(shù)據(jù)
HDFS架構(gòu)
塊復(fù)制

Windows和Linux文件系統(tǒng)的差異。
Windows和Linux上都會(huì)有硬盤,而硬盤上都有分區(qū),在windows上分區(qū)對(duì)應(yīng)的是盤符(c盤、d盤),這個(gè)時(shí)候如果你想要存一些目錄,需要自主去找一個(gè)分區(qū),在分區(qū)下去存一級(jí)目錄、二級(jí)目錄,而linux中雖然也有兩個(gè)分區(qū),但是它的分區(qū)會(huì)掛載到它內(nèi)存的虛擬目錄樹結(jié)構(gòu)上,它是由一個(gè)虛擬的根起,根下的A目錄可能是你的第一個(gè)分區(qū),B目錄可能是你的第二個(gè)分區(qū)。因此在你使用linux系統(tǒng)的時(shí)候,你好像感覺不到底層到底分了幾個(gè)分區(qū),而在使用windows的時(shí)候,容易混亂。比如說(shuō),如果你在windows中寫了一個(gè)軟件,這個(gè)軟件必須從G盤加載一個(gè)文件(conf、xml),那么這個(gè)軟件在其他人的電腦上面可能就跑不起來(lái)了,因?yàn)橛械碾娔X上根本就沒有G盤,而如果你使用的是linux系統(tǒng),linux系統(tǒng)除了它的根目錄結(jié)構(gòu)之外,還有它的mount掛載(/g -> disk:G分區(qū)、/b -> disk:B分區(qū)),上述軟件如果是在linux系統(tǒng)上面開發(fā)的,假如它的文件加載路徑還是寫死的,比如從/g目錄下加載文件,這時(shí)候其他電腦可能也沒有/g目錄,但是這時(shí)它可以創(chuàng)建一個(gè)/g目錄(可以掛載在不同的分區(qū)上,它的映射關(guān)系可以隨便換),因此linux相對(duì)于windows來(lái)說(shuō)使得軟件具備了移動(dòng)性。

2.3 角色功能

NameNode

  • 完全基于內(nèi)存存儲(chǔ)文件元數(shù)據(jù)、目錄結(jié)構(gòu)、文件block的映射
  • 需要持久化方案保證數(shù)據(jù)可靠性
  • 提供副本放置策略
    DataNode
  • 基于本地磁盤存儲(chǔ)block(文件的形式)
  • 并保存block的校驗(yàn)和數(shù)據(jù)保證block的可靠性
  • 與NameNode保持心跳,匯報(bào)block列表狀態(tài)

角色即進(jìn)程。
HDFS并沒有真正存儲(chǔ)數(shù)據(jù),只是管理映射。

2.4 元數(shù)據(jù)持久化

  • 任何對(duì)文件系統(tǒng)元數(shù)據(jù)產(chǎn)生修改的操作,Namenode都會(huì)使用一種稱為EditsLog的事務(wù)日志記錄下來(lái)
  • 使用FsImage存儲(chǔ)內(nèi)存所有的元數(shù)據(jù)狀態(tài)
  • 使用本地磁盤保存EditsLog和FsImage
  • EditsLog具有完整性,數(shù)據(jù)丟失少,但恢復(fù)速度慢,并有體積膨脹風(fēng)險(xiǎn)
  • FsImage具有恢復(fù)速度快,體積與內(nèi)存數(shù)據(jù)相當(dāng),但不能實(shí)時(shí)保存,數(shù)據(jù)丟失多
  • NameNode使用了FsImage+EditsLog整合的方案:
    • 滾動(dòng)將增量的EditsLog更新到FsImage,以保證更近時(shí)點(diǎn)的FsImage和更小的EditsLog體積

數(shù)據(jù)持久化方式

  • 日志文件(文本文件):記錄(append)實(shí)時(shí)發(fā)生的增刪改操作(mkdir /abc),通過讀取日志文件重放每一行指令來(lái)恢復(fù)數(shù)據(jù)
    優(yōu)點(diǎn):完整性比較好
    缺點(diǎn):加載恢復(fù)數(shù)據(jù)慢、占空間
  • 鏡像、快照、dump、db(二進(jìn)制文件):間隔的(小時(shí),天,10分鐘,1分鐘,5秒鐘),內(nèi)存全量數(shù)據(jù)基于某一時(shí)間點(diǎn)做的向磁盤的溢寫
    優(yōu)點(diǎn):恢復(fù)速度快過日志文件
    缺點(diǎn):因?yàn)槭情g隔的,容易丟失一部分?jǐn)?shù)據(jù)

HDFS:

  • EditsLog:日志文件
    體積小,記錄少:必然有優(yōu)勢(shì)
  • FsImage:鏡像、快照
    如果能更快的滾動(dòng)更新時(shí)點(diǎn),必然有優(yōu)勢(shì)

HDFS采用的是最近時(shí)點(diǎn)的FsImage + 增量的EditsLog的持久化方案。
比如現(xiàn)在10點(diǎn),HDFS中記錄了9點(diǎn)的FsImage + 9點(diǎn)到10點(diǎn)的增量的EditsLog,那么通過以下步驟就能得到關(guān)機(jī)前的全量數(shù)據(jù):

  1. 加載FsImage
  2. 加載EditsLog

FsImage時(shí)點(diǎn)是怎么滾動(dòng)更新的?

  • 由NameNode8點(diǎn)溢寫一次,9點(diǎn)溢寫一次(每一小時(shí)溢寫一次,產(chǎn)生大量I/O,耗費(fèi)資源)
  • NameNode第一次開機(jī)的時(shí)候只寫一次FsImage(假設(shè)8點(diǎn)),到9點(diǎn)的時(shí)候,EditsLog記錄的是8~9點(diǎn)的日志,只需要將8~9點(diǎn)的日志的記錄,更新到8點(diǎn)的FsImage中(使用另外一臺(tái)機(jī)器:Secondary NameNode來(lái)做合并),F(xiàn)sImage的數(shù)據(jù)時(shí)點(diǎn)就變成了9點(diǎn)。

2.5 安全模式

  • HDFS搭建時(shí)會(huì)格式化,格式化操作會(huì)產(chǎn)生一個(gè)空的FsImage
  • 當(dāng)NameNode啟動(dòng)時(shí),它從硬盤中讀取EditsLog和FsImage
  • 將所有EditsLog中的事務(wù)作用在內(nèi)存中的FsImage上
  • 并將這個(gè)新版本的FsImage從內(nèi)存中保存到本地磁盤上
  • 然后刪除舊的EditsLog,因?yàn)檫@個(gè)舊的EditsLog的事務(wù)都已經(jīng)作用在FsImage上了
  1. NameNode啟動(dòng)后會(huì)進(jìn)入一個(gè)稱為安全模式的特殊狀態(tài)。
  2. 處于安全模式的NameNode是不會(huì)進(jìn)行數(shù)據(jù)塊的復(fù)制的。
  3. NameNode從所有的 DatNnode接收心跳信號(hào)和塊狀態(tài)報(bào)告。
  4. 每當(dāng)NameNode檢測(cè)確認(rèn)某個(gè)數(shù)據(jù)塊的副本數(shù)目達(dá)到這個(gè)最小值,那么該數(shù)據(jù)塊就會(huì)被認(rèn)為是副本安全(safely replicated)的。
  5. 在一定百分比(這個(gè)參數(shù)可配置)的數(shù)據(jù)塊被NameNode檢測(cè)確認(rèn)是安全之后(加上一個(gè)額外的30秒等待時(shí)間),NameNode將退出安全模式狀態(tài)。
  6. 接下來(lái)它會(huì)確定還有哪些數(shù)據(jù)塊的副本沒有達(dá)到指定數(shù)目,并將這些數(shù)據(jù)塊復(fù)制到其他DataNode上。

NameNode存的元數(shù)據(jù)主要有兩種:文件屬性、每個(gè)塊存在哪個(gè)DataNode上。
在持久化的時(shí)候,文件屬性會(huì)持久化,但是文件的每一個(gè)塊不會(huì)持久化?;謴?fù)的時(shí)候,NameNode會(huì)丟失塊的位置信息。
那么為什么NameNode不持久化塊的位置信息呢?
這就又回到了分布式時(shí)代數(shù)據(jù)一致性的問題了,假如NameNode持久化了塊的位置信息,但是由于集群?jiǎn)?dòng)時(shí)DataNode掛掉了,那么這些塊就取不回來(lái)了,這就會(huì)產(chǎn)生數(shù)據(jù)不一致的問題,因此NameNode寧可不存塊的位置信息,而是等DataNode和NameNode建立心跳,然后向它匯報(bào)塊的信息,這個(gè)過程就叫安全模式。

2.6 HDFS中的SNN

Secondary NameNode(SNN)

  • 在非Ha模式下,SNN一般是獨(dú)立的節(jié)點(diǎn),周期完成對(duì)NN的EditsLog向FsImage合并,減少EditsLog大小,減少NN啟動(dòng)時(shí)間
  • 根據(jù)配置文件設(shè)置的時(shí)間間隔fs.checkpoint.period 默認(rèn)3600秒
  • 根據(jù)配置文件設(shè)置edits log大小 fs.checkpoint.size 規(guī)定edits文件的最大值默認(rèn)是64MB

SNN存在的意義就是讓EditsLog很小、恢復(fù)很快。

SNN合并過程

2.7 Block的副本放置策略

  • 第一個(gè)副本:放置在上傳文件的DN;如果是集群外提交,則隨機(jī)挑選一臺(tái)磁盤不太滿,CPU不太忙的節(jié)點(diǎn)。
  • 第二個(gè)副本:放置在與第一個(gè)副本不同的機(jī)架的節(jié)點(diǎn)上。
  • 第三個(gè)副本:與第二個(gè)副本相同機(jī)架的節(jié)點(diǎn)。
  • 更多副本:隨機(jī)節(jié)點(diǎn)。

在早期的HDFS中,第一個(gè)副本和第二個(gè)副本會(huì)放在同機(jī)架,第三個(gè)副本才會(huì)出機(jī)架,這樣當(dāng)副本數(shù)設(shè)定為2的時(shí)候,如果副本所在機(jī)架掛了,會(huì)導(dǎo)致這個(gè)塊丟失,因此在2.x的時(shí)候修正了這個(gè)問題,第二個(gè)副本放在與第一個(gè)副本不同的機(jī)架上。
第二個(gè)副本和第三個(gè)副本放在同一機(jī)架是為了減少跨交換機(jī)的成本。

數(shù)據(jù)中心

2.8 HDFS讀寫流程

2.8.1 HDFS寫流程
  • Client和NN連接創(chuàng)建文件元數(shù)據(jù)
  • NN判定元數(shù)據(jù)是否有效
  • NN觸發(fā)副本放置策略,返回一個(gè)有序的DN列表
  • Client和DN建立Pipeline連接
  • Client將塊切分成packet(64KB),并使用chunk(512B)+chucksum(4B)填充
  • Client將packet放入發(fā)送隊(duì)列dataqueue中,并向第一個(gè)DN發(fā)送
  • 第一個(gè)DN收到packet后本地保存并發(fā)送給第二個(gè)DN
  • 第二個(gè)DN收到packet后本地保存并發(fā)送給第三個(gè)DN
  • 這一個(gè)過程中,上游節(jié)點(diǎn)同時(shí)發(fā)送下一個(gè)packet
  • 生活中類比工廠的流水線:結(jié)論:流式其實(shí)也是變種的并行計(jì)算
  • Hdfs使用這種傳輸方式,副本數(shù)對(duì)于client是透明的
  • 當(dāng)block傳輸完成,DN們各自向NN匯報(bào),同時(shí)client繼續(xù)傳輸下一個(gè)block
  • 所以,client的傳輸和block的匯報(bào)也是并行的
HDFS寫流程

Client在與NameNode進(jìn)行交互的時(shí)候,會(huì)觸發(fā)副本放置策略,NameNode會(huì)根據(jù)副本放置策略,在返回DataNode信息時(shí)做一個(gè)排序(根據(jù)距離),Client本機(jī)上的DataNode會(huì)排在第一位。然后Client會(huì)和第一個(gè)DataNode建立tcp連接,第一個(gè)DataNode和第二個(gè)DataNode建立tcp連接,第二個(gè)DataNode和第三個(gè)DataNode建立tcp連接,這些連接鏈路被稱為pipline。

DataNode如果掛掉會(huì)怎么辦?

  • 如果是第三個(gè)DataNode掛掉了,影響最小,因?yàn)榍懊鎯蓚€(gè)DataNode的pipline連接沒有斷,繼續(xù)傳輸packet即可。
  • 如果是第二個(gè)DataNode掛掉了,那么第一個(gè)DataNode直接與第三個(gè)DataNode建立連接,然后根據(jù)第三個(gè)DataNode已經(jīng)接收的packet來(lái)向它傳輸下一個(gè)packet即可。
  • 如果是第一個(gè)DataNode掛掉了,那么Client直接與第二個(gè)DataNode建立連接,然后把剩余的packet傳輸給第二個(gè)DataNode即可。

DataNode會(huì)向NameNode匯報(bào)狀態(tài),因此在1個(gè)DataNode掛掉之后,由于匯報(bào)時(shí)的DataNode少了一個(gè),這時(shí)NameNode會(huì)讓某個(gè)DataNode從自身再?gòu)?fù)制一個(gè)DataNode出來(lái)。

2.8.2 HDFS讀流程
  • 為了降低整體的帶寬消耗和讀取延時(shí),HDFS會(huì)盡量讓讀取程序讀取離它最近的副本。
  • 如果在讀取程序的同一個(gè)機(jī)架上有一個(gè)副本,那么就讀取該副本。
  • 如果一個(gè)HDFS集群跨越多個(gè)數(shù)據(jù)中心,那么客戶端也將首先讀本地?cái)?shù)據(jù)中心的副本。
  • 語(yǔ)義:下載一個(gè)文件:
    • Client和NN交互文件元數(shù)據(jù)獲取fileBlockLocation
    • NN會(huì)按距離策略排序返回
    • Client嘗試下載block并校驗(yàn)數(shù)據(jù)完整性
  • 語(yǔ)義:下載一個(gè)文件其實(shí)是獲取文件的所有的block元數(shù)據(jù),那么子集獲取某些block也應(yīng)該成立
    • Hdfs支持client給出文件的offset自定義連接哪些block的DN,自定義獲取數(shù)據(jù)
    • 這個(gè)是支持計(jì)算層的分治、并行計(jì)算的核心
HDFS讀流程
?著作權(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),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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