現(xiàn)在隨著企業(yè)規(guī)模的發(fā)展,對(duì)于數(shù)據(jù)存儲(chǔ)的要求越來越大,單機(jī)存儲(chǔ)性能已經(jīng)成為存儲(chǔ)的瓶頸,在這里我們就需要引入分布式存儲(chǔ),通過水平擴(kuò)展的方式進(jìn)行容量的擴(kuò)展,并且提高數(shù)據(jù)的一致性,安全性,可靠性等關(guān)系。
大數(shù)據(jù)也是發(fā)展的前景之一,越來越多的開發(fā)者開始進(jìn)入大數(shù)據(jù)領(lǐng)域,并且很多企業(yè)開始關(guān)注,逐步發(fā)展自己的大數(shù)據(jù)業(yè)務(wù),數(shù)據(jù)的重要性不言而喻,那么我們應(yīng)該怎么進(jìn)行數(shù)據(jù)保存,擴(kuò)展呢?這正是分布式文件系統(tǒng)需要解決的問題。
我們今天所要說的重點(diǎn)是大數(shù)據(jù)存儲(chǔ)的王者HDFS存儲(chǔ)系統(tǒng)。
HDFS
什么是HDFS呢?官網(wǎng)是這樣解答的,是一種分布式文件系統(tǒng),設(shè)計(jì)用于在商用硬件上商用,管理數(shù)以千計(jì)的服務(wù)器,數(shù)以萬計(jì)的磁盤,將大規(guī)模的服務(wù)器資源當(dāng)做一個(gè)單一的出承諾函系統(tǒng)進(jìn)行管理,操作大批量數(shù)據(jù)就像使用普通文件系統(tǒng)一樣。
簡(jiǎn)單理解其架構(gòu)
HDFS是經(jīng)典的主從架構(gòu),當(dāng)然為了保證高可用,HDFS也提供了高可用的方案,在3.0版本以上更加提供了多個(gè)主節(jié)點(diǎn)用來幫助提高系統(tǒng)的可用性。
在其設(shè)計(jì)理念上,有兩個(gè)主要的關(guān)鍵組件NameNode與DataNode.簡(jiǎn)單來說NameNode負(fù)責(zé)保存一些元數(shù)據(jù)信息,DataNode負(fù)責(zé)數(shù)據(jù)的讀取與寫入,但是真的只是這么簡(jiǎn)單嗎?
我們從Linux的文件系統(tǒng)就可以看出,文件系統(tǒng)是有目錄項(xiàng),索引節(jié)點(diǎn),邏輯塊,超級(jí)塊四大元素構(gòu)成。同樣的HDFS文件系統(tǒng)也有類似的管理操作。
NameNode
NameNode 究竟負(fù)責(zé)什么呢?我們今天就來看一下。
在3.0版本以前,NameNode是只存在兩個(gè)節(jié)點(diǎn)的,一個(gè)Active節(jié)點(diǎn),一個(gè)Standby節(jié)點(diǎn)。在3.0以后就可以支持2個(gè)以上的NameNode節(jié)點(diǎn)了,高可用性得到了提高。
責(zé)任
- NameNode(Active狀態(tài))
- 整個(gè)分布式文件系統(tǒng)的元數(shù)據(jù)(元數(shù)據(jù))管理。元數(shù)據(jù)包括文件的名字,副本數(shù),存儲(chǔ)的block-id(HDFS中使用block作為存儲(chǔ)單元,block-id包含了哪個(gè)DataNode節(jié)點(diǎn))信息。
- 接受客戶端的讀寫請(qǐng)求。告知客戶端讀取的信息去哪里讀取,寫入數(shù)據(jù)要寫入到哪個(gè)機(jī)器
- 啟動(dòng)的時(shí)候加載元數(shù)據(jù)到內(nèi)存中。內(nèi)存中存儲(chǔ)的是 fsimage(元數(shù)據(jù)鏡像文件,類似于文件系統(tǒng)的目錄樹)+edits(元數(shù)據(jù)的操作日志,針對(duì)文件系統(tǒng)做的修改操作記錄)。我們?nèi)绻到y(tǒng)出現(xiàn)錯(cuò)誤的格式化,當(dāng)另外節(jié)點(diǎn)數(shù)據(jù)好保存著可以進(jìn)行數(shù)據(jù)的恢復(fù)。
- 通過心跳的方式與DataNode進(jìn)行存活的通信。
- 數(shù)據(jù)備份告知。
- SecondryNameNode的工作
- 默認(rèn)1小時(shí)定期合并Active NameNode 下的fsimage與edits,避免edit log過大。是通過創(chuàng)建檢查點(diǎn)checkpoint來實(shí)現(xiàn)的。
- 合并完畢后,在發(fā)送給Active NameNode ,可以說不算是Active 的備份節(jié)點(diǎn)。
- HDFS的Federation
這個(gè)是用來擴(kuò)展單機(jī)NameNode 水平擴(kuò)展的問題的,管理多個(gè)命名空間,降低單機(jī)操作的讀寫的壓力。
DataNode
DadaNode 主要是數(shù)據(jù)的讀取,寫入,存儲(chǔ),冗余等內(nèi)容。
- 硬盤故障容錯(cuò),檢測(cè)到本地硬盤出現(xiàn)故障,會(huì)將其所存儲(chǔ)的BlockID內(nèi)容報(bào)告給NameNode,NameNode進(jìn)行調(diào)度按照其他服務(wù)器進(jìn)行備份處理。
- 存儲(chǔ)數(shù)據(jù)塊Block
- 啟動(dòng)線程與NameNode進(jìn)行通信,匯報(bào)其存儲(chǔ)的BlockID信息
- 保持3秒的心跳鏈接,超過一定時(shí)間認(rèn)為數(shù)據(jù)節(jié)點(diǎn)丟失。
- Block的放置策略如下(機(jī)架的問題下次再說):
- 第一個(gè)副本,放置在本機(jī)上,如果是集群外提交的,隨機(jī)選擇不太忙的節(jié)點(diǎn)存儲(chǔ)。有就近的原則
- 第二個(gè)副本,放置在與第一個(gè)副本不同機(jī)架上的節(jié)點(diǎn)上。
- 第三個(gè)副本,放置在與第二副本相同機(jī)架上的相鄰節(jié)點(diǎn)上。
- 更多副本隨機(jī)放置。
數(shù)據(jù)的讀取與寫入
讀取文件流程
- 我們程序是作為客戶端的存在,根據(jù)api進(jìn)行操作
- 然后訪問Namenode,傳輸給需要讀取的文件
- Namenode 查看需要的元數(shù)據(jù)信息,包含路徑所存在block-id信息,還有datanode信息。
- 根據(jù)返回的block-id進(jìn)行(就近原則)讀取,具有先后順序。
- 每讀取取完一個(gè)block后,會(huì)接著讀取下一個(gè)block塊
- 注意 4和5的流程是并行處理的??蛻舳藙傞_始就并行的讀取多個(gè)block塊的數(shù)據(jù),單位是packet為單位接收,本地緩存。
- 下載完畢后,在進(jìn)行組裝,根據(jù)block追加成為文件,完整的數(shù)據(jù)就完成下載了。
寫文件流程
- 客戶端 創(chuàng)建好需要的api操作。
- 打開與nameNode的鏈接,檢查目標(biāo)文件是否存在,目錄內(nèi)容是否存在等信息.
- namenode返回可以上傳的信息包含要上傳的位置datanode 節(jié)點(diǎn)信息等。
- 客戶端請(qǐng)求就近的節(jié)點(diǎn)開始上傳數(shù)據(jù),按照packet為單位,后面?zhèn)浞莸墓?jié)點(diǎn)數(shù)據(jù)是通過異步調(diào)用的通道放大建立管道傳輸數(shù)據(jù)。本質(zhì)上上傳了一個(gè)節(jié)點(diǎn),其他節(jié)點(diǎn)是通過復(fù)制傳輸完成的。
- 當(dāng)?shù)谝粋€(gè)block寫完之后,客戶端再次請(qǐng)求namenode上傳第二個(gè)block的服務(wù)器。重復(fù)以上步驟。
- 寫入也是并發(fā)的寫入。