目錄
- HDFS概述
- HDFS的架構分析
- HDFS的作用
- 主從結構
- 主節點(namenode)
- 主節點的作用
- 主節點的位置
- 從節點(datanode)
- 從節點的作用
- 從節點的位置
- secondarynamenode
- 合并(chickpiont)
- Client讀取多副本檔案程序
- HDFS讀寫資料流程
- HDFS讀資料
- HDFS寫資料
HDFS概述
- 資料量越來越多,在一個作業系統管轄的范圍存不下了,那么就分配到更多的作業系統管理的磁盤中,但是不方便管理和維護,因此迫切需要一種系統來管理多臺機器上的檔案,這就是分布式檔案管理系統 ,
- 是一種允許檔案通過網路在多臺主機上分享的檔案系統,可讓多機器上的多用戶分享檔案和存盤空間,
- 通透性,(可以理解為把底層的操作做了一個隱藏)讓實際上是通過網路來訪問檔案的動作,由程式與用戶看來,就像是訪問本地的磁盤一般,
- 容錯,即使系統中有某些節點宕機,整體來說系統仍然可以持續運作而不會有資料損失【通過副本機制實作】(Redis中有去中心化、主從結構),
- 分布式檔案管理系統很多,hdfs只是其中一種,不合適小檔案
HDFS的架構分析
HDFS的作用
負責資料的分布式存盤
主從結構
主節點(namenode)
主節點,可以有兩個:namenode
是整個檔案系統的管理節點,它維護著整個檔案系統的檔案目錄樹,檔案/目錄的元資訊和每個檔案對應的資料塊串列,接收用戶的操作請求,
檔案包括:(元資料存盤在記憶體中,每一次關倍訓器,再重新打開,發現資料還在,說明肯定做了一個存盤,存到了硬碟中)
- fsimage:元資料鏡像檔案(備份),存盤某一時段NameNode記憶體元資料資訊,
- edits:操作日志檔案,namenode啟動后一些新增元資訊日志,(存的是hdfs的操作記錄)
- fstime:保存最近一次checkpoint的時間

檔案存盤在:Linux的檔案系統中
hdfs-site.xml的dfs.namenode.name.dir屬性
主節點的作用
- 管理元資料(正常情況在記憶體中),元資料包含了許多資訊:當前資料存盤在哪個位置,當前資料有幾個block塊,block大小多大,在哪等等
- 接收用戶的操作請求,是用戶操作的入口
- 維護檔案系統的目錄結構,稱作命名空間
主節點的位置

從節點(datanode)
從節點,有多個:datanode
主從結構中從節點掛了還可以正常運行,主節點掛了就沒了
- 提供真實檔案資料的存盤服務,
- 檔案塊(block):最基本的存盤單位,對于檔案內容而言,一個檔案的長度大小是size,那么從檔案的0偏移開始,按照固定的大小,順序對檔案進行劃分并編號,劃分好的每一個塊稱一個Block,2.0以后HDFS默認Block大小是128MB,以一個256MB檔案,共有256/128=2個Block.
hdfs-site.xml中dfs.blocksize屬性 - 不同于普通檔案系統的是,HDFS中,如果一個檔案小于一個資料塊的大小,并不占用整個資料塊存盤空間
- Replication,多復本,默認是三個,
hdfs-site.xml的dfs.replication屬性
從節點的作用
存盤資料
從節點的位置

這里的ID都是對應的

打開從節點的資料查看一下

secondarynamenode

幫namenode來處理資料
secondarynamenode來對資料進行監控,監控時間到了之后,來通知namenode來進行處理(沒有它,namenode也可以正常用)
合并(chickpiont)
這個合并的程序叫做checkpiont
為什么要進行合并edits:假設我們做了一個操作時上傳一個檔案,那么日志里面會存盤這條記錄,并且也會記得日志存盤在哪,假設我們不對它進行合并(fsimage+edits),那么資料會發生丟失,所以進行合并產生新的fsimage

(這里的默認64MB指的是操作命令那一條指令的大小一共是64,才會進行合并,或者也可以重啟,也會合并)
Client讀取多副本檔案程序
根據一個就近原則去讀取

HDFS讀寫資料流程
HDFS讀資料

簡化描述
1、open,打開HDFS的檔案存盤系統
2、向下找某一個具體的資料;這就需要去找namenode了,namenode里面存盤了它的元資料資訊(包括位置在哪,大小是多少等等)
3、開始讀資料了(多個block就按順序讀)
掛了就找副本
4、讀完就關閉
原描述
1.首先呼叫FileSystem物件的open方法,其實是一個DistributedFileSystem的實體
2.DistributedFileSystem通過rpc獲得檔案的第一個block的locations(namenode查出來的),同一block按照副本數(一個block的檔案有三個備份)會回傳多個locations(回傳給open方法),這些locations按照hadoop拓撲結構(遠近)排序,距離客戶端近的排在前面.
3.前兩步會回傳一個(io流物件,封裝成)FSDataInputStream物件,該物件會被封裝成DFSInputStream物件,DFSInputStream可以方便的管理datanode和namenode資料流,客戶端呼叫read方法,DFSInputStream最會找出離客戶端最近的datanode并連接,
4.資料從datanode源源不斷的流向客戶端,
5.如果第一塊的資料讀完了,就會關閉指向第一塊的datanode連接,接著讀取下一塊,(有多個block就還繼續按照上面的順序接著讀取)這些操作對客戶端來說是透明的(也就是用戶不需要知道下面都做了什么),客戶端的角度看來只是讀一個持續不斷的流,
6.如果第一批block都讀完了,DFSInputStream就會去namenode拿下一批blocks的location,然后繼續讀,如果所有的塊都讀完,這時就會關閉掉所有的流,
如果在讀資料的時候,DFSInputStream和datanode的通訊發生例外,就會嘗試正在讀的block的排第二近的datanode,并且會記錄哪個datanode發生錯誤,剩余的blocks讀的時候就會直接跳過該datanode,DFSInputStream也會檢查block資料校驗和,如果發現一個壞的block,就會先報告到namenode節點,然后DFSInputStream在其他的datanode上讀該block的鏡像
該設計的方向就是客戶端直接連接datanode來檢索資料并且namenode來負責為每一個block提供最優的datanode,namenode僅僅處理block location的請求,這些資訊都加載在namenode的記憶體中,hdfs通過datanode集群可以承受大量客戶端的并發訪問,
HDFS寫資料

寫資料的時候要注意副本問題,要么同時成功,要么同時失敗,具有原子性;不存在一個副本寫入成功,一個副本寫入失敗的問題
簡化描述
1、create,打開了FileSystem
2、打開namenode;namenode要了解這個新的檔案的資訊(檔案寫在了哪,大小多少等等)
3、寫資料
4、包的形式做資料傳輸,namenode告訴流,哪個地方存盤比較合適
5、回傳做驗證,驗證是否寫成功,要是一個失敗,那就全部失敗(原子性),打開ack,監聽是否成功
6、關閉流
7、將資料傳給namenode做分配
原描述
1.客戶端通過呼叫DistributedFileSystem的create方法創建新檔案
2.DistributedFileSystem通過RPC呼叫namenode去創建一個沒有blocks關聯的新檔案(這時候還沒有決定存在哪個位置),創建前,namenode會做各種校驗,比如檔案是否存在,客戶端有無權限去創建等,如果校驗通過,namenode就會記錄下新檔案,否則就會拋出IO例外.
3.前兩步結束后會回傳FSDataOutputStream的物件,像讀檔案的時候相似,FSDataOutputStream被封裝成DFSOutputStream.DFSOutputStream可以協調namenode和datanode,客戶端開始寫資料到DFSOutputStream,DFSOutputStream會把資料切成一個個小packet,然后排成佇列data quene(理解為快取,將資料進行排列,有序的,方便切分,比如資料到了128MB,可以進行切分),
4.DataStreamer會去處理接受data queue,他先問詢namenode這個新的block最適合存盤的在哪幾個datanode里,比如副本數是3,那么就找到3個最適合的datanode(namenode告訴了資料流,存盤到哪個地方比較合適),把他們排成一個pipeline(類似于佇列中的出堆疊,出去就沒了).DataStreamer把packet按佇列輸出到管道的第一個datanode中,第一個datanode又把packet輸出到第二個datanode中,以此類推,
5.DFSOutputStream還有一個對列叫ack queue(一個佇列是傳輸資料,一個佇列是驗證),也是由packet組成,等待datanode的收到回應,當pipeline中的所有datanode都表示已經收到的時候,這時ack queue才會把對應的packet包移除掉,(ack就是把資料搞成了兩個佇列,防止資料發生錯誤;一個佇列是出堆疊的,存盤到datanode,一個佇列是驗證的,當驗證沒有問題之后,ack才會把自己的資料丟掉,留著就是為了防止出現問題,找不到資料了)
如果在寫的程序中某個datanode發生錯誤,會采取以下幾步:1) pipeline被關閉掉;2)為了防止丟包ack queue里的packet會同步到data queue里;3)把產生錯誤的datanode上當前在寫但未完成的block刪掉;4)block剩下的部分被寫到剩下的兩個正常的datanode中;5)namenode找到另外的datanode去創建這個塊的復制(也是三個的),當然,這些操作對客戶端來說是無感知的,
6.客戶端完成寫資料后呼叫close方法關閉寫入流
7.DataStreamer把剩余得包都刷到pipeline里然后等待ack資訊,收到最后一個ack后,通知namenode把檔案標示為已完成
感謝閱讀,我是啊帥和和,一位大資料專業大四學生,祝你快樂,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/302190.html
標籤:其他
