HDFS
HDFS是什麼?node
Hadoop分佈式文件系統(HDFS)是指被設計成適合運行在通用硬件(commodity hardware)上的分佈式文件系統(Distributed File System)。它和現有的分佈式文件系統有不少共同點。但同時,它和其餘的分佈式文件系統的區別也是很明顯的。HDFS是一個高度容錯性的系統,適合部署在廉價的機器上。HDFS能提供高吞吐量的數據訪問,很是適合大規模數據集上的應用。HDFS放寬了一部分POSIX約束,來實現流式讀取文件系統數據的目的。HDFS在最開始是做爲Apache Nutch搜索引擎項目的基礎架構而開發的。HDFS是Apache Hadoop Core項目的一部分。linux
若是沒有HDFS!git
- 大文件的儲存咱們必需要拓展硬盤。
- 硬盤拓展到必定的量之後,咱們就不能在一個硬盤上儲存文件了,要換一個硬盤,這樣文件管理就成了問題。
- 爲了防止文件的損壞嗎,咱們須要建立副本,副本的管理也成了問題。
- 分佈式計算很是麻煩。
1 HDFS出現緣由
1.1 早期文件服務器
- 從上圖中,咱們能夠看出,存儲一個文件,咱們一直往一個機子上面存是不夠的,那麼咱們在儲存量不夠的時候就會加機子。
- 可是若是一個文件放在一臺機子上,若是該機器掛了,那麼文件就丟失了,不安全。
因此咱們會把一個文件放在多臺機子上,建立一個索引文件來儲存文件的指針,如圖中的file1存儲在node1,node2,node3上面,以此類推
- 缺點:
- 難以實現負載均衡
- 文件大小不一樣,負載均衡不易實現
- 用戶本身控制文件大小
- 難以並行化處理
- 只能利用一個節點資源處理一個文件
- 沒法動用集羣資源處理同一個文件
1.2 HDFS文件服務器
- HDFS前提和設計目標
- 存儲超大文件
- HDFS適合存儲大文件,單個文件大小一般在百MB以上
- HDFS適合存儲海量文件,總存儲量可達PB,EB級
- 硬件容錯
- 基於普通機器搭建,硬件錯誤是常態而不是異常,所以錯誤檢測和快速、自動的恢復是HDFS最核心的架構目標
- 流式數據訪問
- 簡單的一致性模型
- 一次寫入,屢次讀取
- 一個文件通過建立、寫入和關閉以後就不須要改變
- 若是是update操做實際上是增長了版本號,並無修改源文件
- 本地計算
- 將計算移動到數據附近(數據在哪一個節點就在哪裏計算)
- 從上圖咱們看出,HDFS是把一個大的數據,拆成不少個block塊,而後在將block存儲在各個機子上。
建立文件對應block的指針文件,和block對應的節點node的指針文件。
- 源自於Google的GFS論文
- 發表於2003年10月
- HDFS是GFS克隆版
- 易於擴展的分佈式文件系統
- 運行在大量普通廉價機器上,提供容錯機制
- 爲大量用戶提供性能不錯的文件存取服務
1.3 HDFS優缺點
- 優勢
- 高容錯性
- 適合批處理
- 適合大數據處理
- GB、TB、甚至PB級數據
- 百萬規模以上的文件數量
- 10K+節點規模
- 流式文件訪問
- 可構建在廉價機器上
- 缺點
- 低延遲數據訪問(慢)
- 小文件存取
- 佔用NameNode大量內存
- 尋道時間超過讀取時間
- 併發寫入、文件隨機修改
- 一個文件只能有一個寫者
- 僅支持append(追加)
- 適用場景:適合一次寫入,屢次讀出的場景,支持追加數據且不支持文件的修改。
1.4 基本構成
- 數據塊
- 文件以塊爲單位進行切分存儲,塊一般設置的比較大(最小6M,默認128M),根據網絡帶寬計算最佳值。
- 塊越大,尋址越快,讀取效率越高,但同時因爲MapReduce任務也是以塊爲最小單位來處理,因此太大的塊不利於於對數據的並行處理。
- 一個文件至少佔用一個塊(若是一個1KB文件,佔用一個塊,可是佔用空間仍是1KB)
- 咱們在讀取HDFS上文件的時候,NameNode會去尋找block地址,尋址時間爲傳輸時間的1%時,則爲最佳狀態。
- 目前磁盤的傳輸速度廣泛爲100MB/S
- 若是尋址時間約爲10ms,則傳輸時間=10ms/0.01=1000ms=1s
- 若是傳輸時間爲1S,傳輸速度爲100MB/S,那麼一秒鐘咱們就能夠向HDFS傳送100MB文件,設置塊大小128M比較合適。
- 若是帶寬爲200MB/S,那麼能夠將block塊大小設置爲256M比較合適。
- Namenode(master管理者)
- 管理HDFS的文件樹及名稱空間
- 數據複製策略
- 管理數據塊(Block)的映射信息
- 處理客戶端讀寫請求。
- Datanode(slave實際操做者)
- Client(客戶端)
- 文件切分,上傳HDFS時,將文件切分紅一個一個Block,而後進行上傳。
- 與Namenode交互,獲取文件位置信息。
- 與Datanode交互,讀取或者寫入數據。
- 提供API來管理HDFS。
- SecondaryNameNode
- 並不是是NameNode的熱備,當NameNode掛掉的時候,它並不能立刻替換NameNode並提供服務。
- 輔助NameNode,好比根據檢查點,按期合併Fsimage和Edits,並推送給NameNode。
1.5 所處角色
2 HDFS物理網絡環境(集羣結構)
- 比較重要服務功能最好能部署在不一樣的節點上,如:NN。
- 不重要的能夠在一個節點上,如:DN。
- 副本選擇機制:當副本爲3的時候,第一個爲本地最近的節點,第二個爲同機架的不一樣節點,第三個爲不一樣機架的不一樣節點。
3 HDFS 讀寫工做原理
3.1 HDFS文件寫入流程
- 客戶端建立 DistributedFileSystem 對象.
- DistributedFileSystem 對象調用元數據節點,在文件系統的命名空間中建立一個新的文件,元數據節點首先肯定文件原來不存在,而且客戶端有建立文件的權限,而後建立新文件,並標識爲「上傳中」狀態,便可以看見,但不能使用。
- DistributedFileSystem 返回 DFSOutputStream,客戶端用於寫數據。
- 客戶端開始寫入數據,DFSOutputStream 將數據分紅塊,寫入 data queue(Data queue 由 Data Streamer 讀取),並通知元數據節點分配數據節點,用來存儲數據塊(每塊默認複製 3 塊)。分配的數據節點放在一個 pipeline 裏。Data Streamer 將數據塊寫入 pipeline 中的第一個數據節點。第一個數據節點將數據塊發送給第二個數據節點。第二個數據節點將數據發送給第三個數據節點。注意:並非第一個數據節點徹底接收完 block 後再發送給後面的數據節點,而是接收到一部分 就發送,因此三個節點幾乎是同時接收到完整的 block 的。DFSOutputStream 爲發出去的數據塊保存了 ack queue,等待 pipeline 中的數據節點告知數據已經寫入成功。若是 block 在某個節點的寫入的過程當中失敗:關閉 pipeline,將 ack queue 放 至 data queue 的開始。已經寫入節點中的那些 block 部分會被元數據節點賦予新 的標示,發生錯誤的節點重啓後可以察覺其數據塊是過期的,會被刪除。失敗的節點從 pipeline 中移除,block 的其餘副本則寫入 pipeline 中的另外兩個數據節點。元數據節點則被通知此 block 的副本不足,未來會再建立第三份備份。
- ack queue 返回成功。
- 客戶端結束寫入數據,則調用 stream 的 close 函數,
- 最後通知元數據節點寫入完畢
總結:github
客戶端切分文件 Block,按 Block 線性地和 NN 獲取 DN 列表(副本數),驗證 DN 列表後以更小的單位流式傳輸數據,各節點兩兩通訊肯定可用,Block 傳輸結束後,DN 向 NN 彙報 Block 信息,DN 向 Client 彙報完成,Client 向 NN 彙報完成,獲取下一個 Block 存放的 DN 列表,最終 Client 彙報完成,NN 會在寫流程更新文件狀態。算法
3.2 HDFS文件讀取流程
- 客戶端(client)用 FileSystem 的 open()函數打開文件。
- DistributedFileSystem 調用元數據節點,獲得文件的數據塊信息。對於每個數據塊,元數據節點返回保存數據塊的數據節點的地址。
- DistributedFileSystem 返回 FSDataInputStream 給客戶端,用來讀取數據。
- 客戶端調用 stream 的 read()函數開始讀取數據(也會讀取 block 的元數據)。DFSInputStream 鏈接保存此文件第一個數據塊的最近的數據節點(優先讀取同機架的 block)。
- Data 從數據節點讀到客戶端。當此數據塊讀取完畢時,DFSInputStream 關閉和此數據節點的鏈接,而後鏈接此文件下一個數據塊的最近的數據節點。
- 當客戶端讀取完畢數據的時候,調用 FSDataInputStream 的 close 函數。
- 在讀取數據的過程當中,若是客戶端在與數據節點通訊出現錯誤,則嘗試鏈接包含此數據塊的下一個數據節點。失敗的數據節點將被記錄,之後再也不鏈接。
總結:shell
客戶端和 NN 獲取一部分 Block(獲取部分 block 信息,而不是整個文件所有的 block 信 息,讀完這部分 block 後,再獲取另外一個部分 block 的信息)副本位置列表,線性地和 DN 獲取 Block,最終合併爲一個文件,在 Block 副本列表中按距離擇優選取,若是選取到的副本完整就返回,不然找下一個副本。json
4 深刻
4.1 NameNode和SecondaryNameNode
- 做用:
- Namespace管理:負責管理文件系統中的樹狀目錄結構以及文件與數據塊的映射關係
- 塊信息管理:負責管理文件系統中文件的物理塊與實際存儲位置的映射關係BlocksMap
- 集羣信息管理:機架信息,datanode信息
- 集中式緩存管理:從Hadoop2.3 開始,支持datanode將文件緩存到內存中,這部分緩存經過NN集中管理
- 存儲結構:
- 內存: Namespace數據,BlocksMap數據,其餘信息
- 文件:
- 已持久化的namespace數據:FsImage
- 未持久化的namespace操做:Edits
合併流程:windows
- NN 建立一個新的 edits log 來接替老的 edits 的工做
- NN 將 fsimage 和舊的 edits 拷備到 SNN 上
- SNN 上進行合併操做,產生一個新的 fsimage
- 將新的 fsimage 複製一份到 NN 上
- 使用新的 fsimage 和新的 edits log
4.2 集羣啓動過程
開啓安全模式:不能執行數據修改操做api
加載fsimage緩存
逐個執行全部Edits文件中的每一條操做將操做合併到fsimage,完成後生成一個空的edits文件
接收datanode發送來的心跳消息和塊信息
根據以上信息肯定文件系統狀態
退出安全模式
4.3 安全模式
- 安全模式:文件系統只接受讀數據請求,而不接受刪除、修改等變動請求
- 什麼狀況下進入:NameNode主節點啓動時,HDFS進入安全模式
- 何時時候退出:系統達到安全標準時,HDFS退出安全模式
- dfs.namenode.safemode.min.datanodes: 最小可用datanode數量
- dfs.namenode.safemode.threshold-pct: 副本數達到最小要求的block佔系統總文件block數的百分比
- 總文件block數100個,每一個block須要有3個副本,知足3個副本的block數量爲70個,那麼pct=70%(默認0.999)
- 常見進入安全模式不退出就是由於學習機器不夠,副本數低於3,這個參數進行驗證不經過。
- dfs.namenode.safemode.extension: 穩定時間
- 相關命令:
- hdfs dfsadmin -safemode get:查看當前狀態
- hdfs dfsadmin -safemode enter:進入安全模式
- hdfs dfsadmin -safemode leave:強制離開安全模式
- hdfs dfsadmin -safemode wait:一直等待直到安全模式結束
5 HDFS Federation (聯邦)
經過多個 namenode/namespace 把元數據的存儲和管理分散到多個節點中,使到namenode/namespace 能夠經過增長機器來進行水平擴展。能把單個 namenode 的負載分散到多個節點中,在 HDFS 數據規模較大的時候不會也下降 HDFS 的性能。能夠經過多個namespace 來隔離不一樣類型的應用,把不一樣類型應用的 HDFS 元數據的存儲和管理分派到不一樣的 namenode 中。核心:多臺 namenode 管理的是同一個集羣!
假設服務器內存:128G=137438953472字節 ,一個塊大概使用150字節,那麼能夠存儲的塊數量爲:916259689g個,由於一個默認塊大小爲128M,那麼能夠儲存的文件大小爲109PB左右,遠遠達不到大數據的規模(目前有些大公司能達到一臺NameNode管理上EB的數據),這個時候就須要Federation(聯邦),多個NameNode管理一套集羣。
6 HDFS HA(High Availability高可用)
6.1 高可用架構圖
- 主備 NameNode,解決單點故障:
- ANN:ActiveNameNode,對外提供服務,SNN 同步 ANN 元數據,以待切換。
- SNN:StandbyNameNode,完成了 edits.log 文件的合併產生新的 image,推送回 ANN。
- JNN:JournalNode,ANN 和 SNN 經過 JNN 集羣來共享信息。兩個 NameNode 爲了數據同步,會經過一組稱做 JournalNodes 的獨立進程進行相互通訊。當 ANN 的命名空間有任何修改時,會告知大部分的 JournalNodes 進程。SNN 有能力讀取 JNs 中的變動信息,而且一直監控 edit log 的變化,把變化應用於本身的命名空間。SNN 能夠確保在集羣出錯時,命名空間狀態已經徹底同步了。在 HA 架構裏面 SecondaryNameNode 這個冷備角色已經不存在了,爲了保持 SNN 實時的與 ANN 的元數據保持一致,他們之間交互經過一系列守護的輕量級進程 JournalNode。基本原理就是用 2N+1 臺 JN 存儲 editlog,每次寫數據操做有超過 半數(>=N+1)返回成功時即認爲該次寫成功,數據不會丟失了。固然這個算法所能容忍 的是最多有 N 臺機器掛掉,若是多於 N 臺掛掉,這個算法就失效了。任何修改操做在 ANN上執行時,JN 進程同時也會記錄修改 log 到至少半數以上的 JN 中,這時 SNN 監測到 JN 裏面的同步 log 發生變化了會讀取 JN 裏面的修改 log,而後同步到本身的的目錄鏡像樹裏面。當發生故障時,ANN 掛掉後,SNN 會在它成爲 ANN 前,讀取全部的 JN 裏面的修改日誌,這樣就能高可靠的保證與掛掉的 NN 的目錄鏡像樹一致,而後無縫的接替它的職責,維護來自客戶端請求,從而達到一個高可用的目的。
- DN:同時向兩個 NameNode 彙報數據塊信息(位置)。
- 兩個 NN 之間的切換:
- 手動切換:經過命令實現主備之間的切換,能夠用 HDFS 升級等場合。
- 自動切換:基於 Zookeeper 實現。
- HDFS 2.x 提供了 ZookeeperFailoverController 角色,部署在每一個 NameNode 的節點上,做爲一個 deamon 進程, 簡稱 zkfc,zkfc 主要包括三個組件:
- HealthMonitor:監控 NameNode 是否處於 unavailable 或 unhealthy 狀態。當前經過RPC 調用 NN 相應的方法完成。
- ActiveStandbyElector:管理和監控本身在 ZK 中的狀態。
- ZKFailoverController:它訂閱 HealthMonitor 和 ActiveStandbyElector 的事件,並管理NameNode 的狀態。
- 簡稱ZKFC,就是Zookeeper客戶端。
- ZKFailoverController 主要職責:
- 健康監測:週期性的向它監控的 NN 發送健康探測命令,從而來肯定某個NameNode 是否處於健康狀態,若是機器宕機,心跳失敗,那麼 zkfc 就會標記它處於一個不健康的狀態
- 會話管理:若是 NN 是健康的,zkfc 就會在 zookeeper 中保持一個打開的會話,若是 NameNode 同時仍是 Active 狀態的,那麼 zkfc 還會在 Zookeeper 中佔有一個類型爲短暫類型的 znode,當這個 NN 掛掉時,這個 znode 將會被刪除,而後備用的NN,將會獲得這把鎖,升級爲主 NN,同時標記狀態爲 Active,當宕機的 NN 新啓動時,它會再次註冊 zookeper,發現已經有 znode 鎖了,便會自動變爲 Standby狀態,如此往復循環,保證高可靠,須要注意,目前僅僅支持最多配置 2 個 NN.
- master 選舉:如上所述,經過在 zookeeper 中維持一個短暫類型的 znode,來實現搶佔式的鎖機制,從而判斷那個 NameNode 爲 Active 狀態。
6.2 故障轉移流程
- 上圖注意:SecondaryNameNode被另外一臺NameNode取代,edits文件交由qjournal管理。
6.3 CM配置HA注意點:
cdh01.com--------
QuorumPeerMain(zk)
DFSZKFailoverController
NameNode
JournalNode
cdh02.com--------
QuorumPeerMain(zk)
DFSZKFailoverController
JournalNode
DataNode
cdh03.com--------
QuorumPeerMain(zk)
JournalNode
DataNode
7 HDFS糾刪碼(時間換空間)
a=1
b=2
c=3
a+b+c=6
a+2b+3c=14
a+3b+4c=19
咱們須要求出a,b,c的值,那麼最少須要的方程數爲?3個
若是有4個方程,就容許丟失任意一個方程
若是有5個方程,就容許丟失任意兩個方程
a=1
b=2
c=3
視爲數據
a+b+c=6
a+2b+3c=14
a+3b+4c=19
視爲一個效驗/沉餘數據
若是是複製策略,要容許丟失任意2份數據,咱們須要3*3=9份空間
若是是究刪碼策略,要容許丟失任意2份數據,咱們須要3+2=5份空間
8 HDFS文件類型
txt,json,csv |
行式 |
文本 |
否 |
默認存儲方式(txt),數據內容能夠直接cat查看,存儲效率較高,處理效率低。壓縮比較低 |
Hadoop |
Sequence file |
行式 |
二進制 |
是 |
以key,value對的方式存儲。壓縮比中等 |
Hadoop |
Avro |
行式 |
二進制 |
是 |
數據序列化框架,同時支持RPC,數據自帶schema,支持比較豐富的數據類型。與protobuf, thrift 相似。壓縮比中等 |
Hadoop |
RC(record columnar) |
列式 |
二進制 |
是 |
列式存儲,將數據按照行組分塊,讀取以行組爲單位,可是行組中能夠跳過不須要的列。壓縮比中等 |
Hive |
ORC(optimized record columnar) |
列式 |
二進制 |
是 |
升級版的RC,使用了更優化的存儲結構,從而得到更好的性能,另外支持對數據的修改和ACID。壓縮比高 |
Hive |
Parquet |
列式 |
二進制 |
是 |
支持嵌套類型,可高效實現對列的查詢或統計。壓縮比高 |
Impala |
9 數據壓縮類型
gzip |
否 |
很高 |
比較快 |
是 |
有 |
和文本處理同樣,不須要修改 |
• 使用方便 • 當每一個文件壓縮以後在130M之內的(1個塊大小內),均可以考慮用gzip壓縮格式 |
lzo |
是 |
比較高 |
很快 |
否,須要安裝 |
有 |
須要建索引,還須要指定輸入格式 |
• 壓縮率和壓縮速度綜合考慮 • 支持split,是hadoop中最流行的壓縮格式; • 一個很大的文本文件,壓縮以後還大於200M以上的能夠考慮,並且單個文件越大,lzo優勢越明顯 • cloudera&twitter |
snappy |
否 |
比較高 |
很快 |
否,須要安裝 |
沒有 |
和文本處理同樣,不須要修改 |
• 壓縮率和壓縮速度綜合考慮 • 當mapreduce做業的map輸出的數據比較大的時候,做爲map到reduce的中間數據的壓縮格式 • spark默認壓縮格式 • google出品 |
bzip2 |
是 |
最高 |
慢 |
是 |
有 |
和文本處理同樣,不須要修改 |
• 壓縮率高 • 適合對速度要求不高,但須要較高的壓縮率,好比數據比較大,須要壓縮存檔減小磁盤空間而且之後數據用得比較少的狀況 |
10 HDFS經常使用命令
-help
:輸出這個命令參數。如:hadoop fs -help ls (輸出ls命令的參數)
-ls
:顯示目錄信息。如:hadoop fs -ls / (查詢hdfs上根目錄的目錄,,遞歸建立加 -R參數)
-mkdir
:在hdfs上建立目錄。如:hadoop fs -mkdir /haha (根目錄下建立haha文件夾,遞歸建立加 -p參數)
-moveFromLocal
:從本地剪切粘貼到hdfs。如:hadoop fs -moveFromLocal /haha/xixi.txt / (將本地haha文件夾下的xixi.txt文件剪切粘貼到hdfs的根目錄下)
-copyFromLocal
:從本地拷貝到hdfs上。如:用法同上
-copyToLocal
:從hdfs上拷貝到本地。如:用法同上
-cp:從hdfs
的一個路徑拷貝到hdfs的另外一個路徑。如:方法同上
-mv
:從hdfs上的一個路徑移動到hdfs的另外一個路徑。如:方法同上
-appendToFile
:追加一個文件到已經存在的文件末尾。如:hadoop fs -appendToFile /haha/lala.txt /xixi.txt (將本地lala.txt文件內容追加到hdfs上xixi.txt裏)
-cat
:顯示文件內容。如:hadoop fs -cat /xixi.txt (查看xixi.txt)
-tail
:顯示一個文件的末尾。
-chmod
:修改文件權限。如:hadoop fs -chmod 777 /xixi.txt (修改xixi.txt文件的權限)
-get
:等同於copyToLocal,就是從hdfs下載文件到本地。如:hadoop fs -get /xixi.txt ./ (下載到當前本地路徑)
-getmerge
:合併下載多個文件,如:hadoop fs -getmerge /log/*.txt ./sum.txt (將hdfs上log文件夾下的全部.txt文件整合在一塊兒,下載到本地,名字爲sum.txt)
-put
:等同於copyFromLocal,就是上傳文件到hdfs。如:hadoop fs -put /xixi.txt / (上傳到hdfs的根路徑)
-rmr
:刪除文件或目錄
-df
:統計文件系統的可用空間信息。如:hadoop fs -df -h /
-du
:統計文件夾的大小信息。如:-s總大小、-h單位
-count
:統計一個指定目錄下的文件節點數。如:結果2 2 199 (第一個參數說的是最多有幾級目錄,第二個參數說的是一共有多少文件)
11 HDFS SHELL操做
11.1 hdfs經常使用基礎命令
- 查看結構:hdfs dfs -ls [/查看目錄名稱]
- 上傳:hdfs dfs -put [文件] [/上傳目錄名稱]
- 拷貝:hdfs dfs -cp [源文件名] [目標文件名]
- 修改權限(同linux):hdfs dfs -chmod [權限級別] [文件]
- 查看每一個文件佔用大小:hdfs dfs -du -h [目錄]
11.2 本地->HDFS命令
- 上傳:hdfs dfs -put [文件] [/上傳目錄名稱]
- 上傳(同put):hdfs dfs -copyFromLocal [文件] [/上傳目錄名稱]
- 剪切上傳:hdfs dfs -moveFromLocal [文件] [/上傳目錄名稱]
- 追加:hdfs dfs -appendToFile [源文件] [/須要追加的文件]
11.3 HDFS->本地命令
- 下載:hdfs dfs -get [/HDFS源文件] [本地路徑]
- 下載(同get):hdfs dfs -copyToLocal [/HDFS源文件] [本地路徑]
- 合併下載:hdfs dfs -getmerge [/HDFS源文件] [本地文件名]
11.4 合併小文件
- 打包:hadoop archive -archiveName [har包名稱] -p [/須要打包文件] [/打包文件存放地址]
- 查看包:hdfs dfs -ls har://[har包文件]
12 windows 大數據開發環境配置
- 下載winutils解壓
- 配置對應版本的環境變量名爲:HADOOP_HOME 值爲:解壓目錄如上F:\bigdatasoft\hadoop\winutils-master\hadoop-3.0.0
- 環境變量Path添加:%HADOOP_HOME%\bin
- 重啓電腦,打開cmd,輸入winutils,出現下圖證實配置成功
13 基本API使用
項目地址:https://github.com/70416450/Bigdata-Util
- 修改hdfs.properties中的配置信息
- 使用單元測試類測試每個API吧。