前面幾篇簡單介紹了什么是大數據和Hadoop,也說了怎么搭建最簡單的偽分布式和全分布式的hadoop集群。接下來這篇我詳細的分享一下HDFS。
HDFS前言:
設計思想:(分而治之)將大文件、大批量文件,分布式存放在大量服務器上,以便於采取分而治之的方式對海量數據進行運算分析。
在大數據系統中作用:為各類分布式運算框架(如:mapreduce,spark,tez,……)提供數據存儲服務。
分布式文件系統:
問題引發:海量數據超過了單台物理計算機的存儲能力
解決方案:對數據分區存儲與若干台物理主機中
分布式文件系統應運而生:
1)管理網絡中跨多台計算機存儲的文件系統
2)HDFS就是這樣的一個分布式文件系統
一、HDFS概述
1.1、HDFS概述
1)HDFS集群分為兩大角色:NameNode、DataNode
2)NameNode負責管理整個文件系統的元數據
3)DataNode負責管理用戶的文件數據塊
4)文件會按照固定的大小(blocksize)切成若干塊后分布式存儲在若干台datanode上
5)每一個文件塊可以有多個副本,並存放在不同的datanode上
6)DataNode會定期向NameNode匯報自身保存的block信息,而namenode則會負責保持文件的副本數量
7)HDFS的內部工作機制對客戶端保持透明,客戶端請求訪問HDFS都是通過namenode申請來進行
1.2、HDFS的概念和特性
1)HDFS的概念
HDFS采用了主從式(Master/Slave)的體系結構,其中NameNode(NN),DataNode(DN)和Client是HDFS中的3個重要角色。HDFS也在社區的努力下不斷演進,包括支持文件追加,Federation,HA的引入等。
在一個HDFS中,有一個NN,一個SNN(Secondary NameNode)和眾多的DN,在大型的集群中可能會有數以千計的DN。而Client,一般意義上比數據節點的個數還要多。
NN管理了HDFS兩個最重要的關系:
1)目錄文件樹結構和文件與數據塊的對應關系:會持久化到物理存儲中,文件名叫做fsimage。
2)DN與數據塊的對應關系,即數據塊存儲在哪些DN中:在DN啟動時會上報到NN它所維護的數據塊。這個是動態建立的,不會持久化。因此,集群的啟動可能需要比較長的時間。
而DN則保存了數據塊。並且執行NN的命令,比如復制,拷貝,刪除等操作。Client則是使用HDFS的主題,包括寫文件,讀文件等常見操作。
總的來說:HDFS是一個文件系統,用於存儲文件,通過統一的命名空間——目錄樹來定位文件。其次,它是分布式的,由很多服務器聯合起來實現其功能,集群中的服務器有各自的角色。
2)HDFS的特性
2.1)HDFS中的文件在物理上是分塊存儲(Block),塊的大小可以通過配置參數(dfs.blocksize)來規定 默認大小在hadoop2.x版本中是128M,老版本中的64M
2.2)HDFS文件系統會給客戶端提供一個統一的抽象目錄樹,客戶端通過路徑來訪問文件,形如:hdfs://namenode:port/dir-a/dir-b/dir-c/file.data
2.3)目錄結構及文件分塊信息(元數據)的管理由namenode節點承擔 namenode是HDFS集群主節點,負責維護整個HDFS文件系統的目錄樹以及每一個路徑(文件)對應的block塊信息(block的id,以及所在的datanode服務器)
2.4)文件的各個block的存儲管理由datanode節點承擔 datanode是HDFS集群從節點,每一個block都可以在多個datanode上存儲多個副本(副本參數也可以通過參數設置dfs.replication)
2.5)HDFS適應一次寫入,多次讀出的場景,且不支持文件的修改。
注意:適合用來做數據分析,並不適合用來做網盤應用(因為不方便進行修改,延遲大,網絡開銷大,成本太高)
3)我們通過一張圖來解釋
通過上面的描述我們知道,hdfs很多特點:
保存多個副本,且提供容錯機制,副本丟失或宕機自動恢復(默認存3份)。
運行在廉價的機器上
適合大數據的處理。HDFS默認會將文件分割成block,,在hadoop2.x以上版本默認128M為1個block。然后將block按鍵值對存儲在HDFS上,並將鍵值對的映射存到內存中。如果小文件太多,那內存的負擔會很重。
如上圖所示,HDFS也是按照Master和Slave的結構。分NameNode、SecondaryNameNode、DataNode這幾個角色。
NameNode:是Master節點,是大領導。管理數據塊映射;處理客戶端的讀寫請求;配置副本策略;管理HDFS的名稱空間;
SecondaryNameNode:是一個小弟,分擔大哥namenode的工作量;是NameNode的冷備份;合並fsimage和fsedits然后再發給namenode。
DataNode:Slave節點,奴隸,干活的。負責存儲client發來的數據塊block;執行數據塊的讀寫操作。
熱備份:b是a的熱備份,如果a壞掉。那么b馬上運行代替a的工作。
冷備份:b是a的冷備份,如果a壞掉。那么b不能馬上代替a工作。但是b上存儲a的一些信息,減少a壞掉之后的損失。
fsimage:元數據鏡像文件(文件系統的目錄樹。)
edits:元數據的操作日志(針對文件系統做的修改操作記錄)
namenode內存中存儲的是=fsimage+edits。
SecondaryNameNode負責定時默認1小時,從namenode上,獲取fsimage和edits來進行合並,然后再發送給namenode。減少namenode的工作量。
1.3、HDFS的局限性
1)低延時數據訪問。在用戶交互性的應用中,應用需要在ms或者幾個s的時間內得到響應。由於HDFS為高吞吐率做了設計,也因此犧牲了快速響應。對於低延時的應用,可以考慮使用HBase或者Cassandra。
2)大量的小文件。標准的HDFS數據塊的大小是64M,存儲小文件並不會浪費實際的存儲空間,但是無疑會增加了在NameNode上的元數據,大量的小文件會影響整個集群的性能。
前面我們知道,Btrfs為小文件做了優化-inline file,對於小文件有很好的空間優化和訪問時間優化。
3)多用戶寫入,修改文件。HDFS的文件只能有一個寫入者,而且寫操作只能在文件結尾以追加的方式進行。它不支持多個寫入者,也不支持在文件寫入后,對文件的任意位置的修改。
但是在大數據領域,分析的是已經存在的數據,這些數據一旦產生就不會修改,因此,HDFS的這些特性和設計局限也就很容易理解了。HDFS為大數據領域的數據分析,提供了非常重要而且十分基礎的文件存儲功能。
1.4、HDFS保證可靠性的措施
1)冗余備份
每個文件存儲成一系列數據塊(Block)。為了容錯,文件的所有數據塊都會有副本(副本數量即復制因子,課配置)(dfs.replication)
2)副本存放
采用機架感知(Rak-aware)的策略來改進數據的可靠性、高可用和網絡帶寬的利用率
3)心跳檢測
NameNode周期性地從集群中的每一個DataNode接受心跳包和塊報告,收到心跳包說明該DataNode工作正常
4)安全模式
系統啟動時,NameNode會進入一個安全模式。此時不會出現數據塊的寫操作。
5)數據完整性檢測
HDFS客戶端軟件實現了對HDFS文件內容的校驗和(Checksum)檢查(dfs.bytes-per-checksum)。
二、HDFS基本概念
2.1、HDFS主從結構體系
2.2、數據塊(DataBlock)
HDFS將每個文件存儲成一系列的數據塊,所有的數據塊都是同樣的大小。(在配置文件中配置每個數據塊的大小,最后一塊不一定大小一樣)
文件中所有的數據塊都會有副本,每個文件的數據塊大小和副本系數都是可配置的。
HDFS中的文件都是一次寫入的,並且嚴格要求在任何時候只能有一個寫入者。
我們可以查看到通過:hdfs fsck / -file -bloks -locations
HDFS的配置參數:dfs.replication、dfs.blocksize
2.3、名字節點(主節點:NameNode)
1)概述
-NN是HDFS主從結構中主節點上運行的主要進程,它負責管理從節點DN。NN維護着整個文件系統的文件目錄樹,文件目錄的元信息和文件的數據塊索引。
這些信息以兩種信息保存在本文文件系統中,一種是文件系統鏡像(文件名字fsimage),另一種是fsimage的編輯日志(文件名字edits)。
-fsimage中保存着某一特定時刻HDFS的目錄樹、元信息和文件數據塊的索引等信息,后續的對這些信息的改動,則保存在編輯日志中,它們一起提供了一個完整的NN的第一關系。
-通過NN,Client還可以了解到數據塊所在的DN的信息。需要注意的是,NN中關於DN的信息是不會保存到NN的本地文件系統的,也就是上面提到的fsimage和edits中。
NN每次啟動時,都會通過每個DN的上報來動態的建立這些信息。這些信息也就構成了NN第二關系。
-NN還能通過DN獲取HDFS整體運行狀態的一些信息,比如系統的可用空間,已經使用的空間,各個DN的當前狀態等。
2)作用
維護着文件系統數中所有文件和目錄的元數據
協調客戶端對文件的訪問
2.4、數據節點(從節點:DataNode)
1)概述
DN是HDFS中硬盤IO最忙碌的部分:將HDFS的數據塊寫到Linux本地文件系統中,或者從這些數據塊中讀取數據。DN作為從節點,會不斷的向NN發送心跳。
初始化時,每個DN將當前節點的數據塊上報給NN。NN也會接收來自NN的指令,比如創建、移動或者刪除本地的數據塊,並且將本地的更新上報給NN。
2)作用
接受客戶端或NameNode的調度
存儲和檢索數據塊
在NameNode的統一調度下進行數據塊的創建、刪除和復制
定期向NameNode發送自身存儲的數據塊列表
2.5、SecondaryNameNode
1)定期合並edits和fsImage(如果沒有配置SecondaryNameNode由NameNode自己完成)
Secondary NameNode是用於定期合並fsimage和edits的。與NN一樣,每個集群都有一個SNN,在大規模部署的條件下,一般SNN也獨自占用一台服務器。
SNN按照集群配置的時間建個,不停的獲取HDFS某一個時間點的fsimage和edits,合並它們得到一個新的fsimage。該fsimage上傳到NN后會替換NN的老的fsimage。
2)防止edits日志文件過大
從上面可以看出,SNN會配合NN,為NN的第一關系提供了一個簡單的CheckPoint機制,並避免出現edits過大,導致NN啟動時間過長的問題。
3)提供那個NameNode的fsImage文件的檢查點,以實現NameNode故障恢復
2.6、總結NameNode和DataNode
-HDFS集群有兩種節點類型,Namenodes和Datanodes,它們工作於master-worker模式。一個namenode是master,一組datanodes是workers。namenode管理整個文件系統的namespace。
它維護一棵文件樹和所有文件/目錄的元信息。這些信息在namenode的本地磁盤上存成兩個文件,一個是該namespace的鏡像,另一個是編輯日志(edit log)。
namenode也知道每個文件的每個塊都存在哪個datanode上了,但這個信息不會被持久化下來,因為每次啟動時,這個信息會被重新生成。
-客戶端程序通過訪問namenode和datanodes來訪問HDFS文件系統。但是用戶代碼根本不知道namenode和datanodes的存在,就像訪問POSIX一樣(Portable Operating System Interface:便攜計算機系統接口)。
Datanodes是干苦力活的。當被客戶端或namenode命令時,它存儲和檢索文件塊(blocks)。它還會定期向namenode匯報它們存儲的文件塊列表。
-沒有namenode,整個文件系統就沒法用了。如果把namenode移除,整個文件系統里的文件就都丟失了,因為沒辦法知道如何重新組裝存在各個datanodes里的文件塊。
因此有必要保證namenode足夠可靠,Hadoop提供了兩種機制保證namenode里的數據安全。
-第一個機制是備份namenode上的持久化信息。可以配置hadoop,讓namenode寫持久化信息時寫到多個地方,並且這些寫操作是串行的並且是原子操作。通常的做法是寫到本地磁盤一份,同時寫到遠程NFS上。
-另一個機制是配一個secondary namenode。雖然名字上叫namenode,但secondary namenode根本不做namenode的工作,它就是定期把namenode上的namespace鏡像和編輯日志(edit log)合並到自己身上,以避免編輯日志過大。
secondary namenode通常是一台單獨的機器,因為合並工作需要大量的CPU和內存資源。因為它的狀態遲於namenode,所以,當namenode發生事故時,肯定是會有數據丟失的。
通常的做法是把namenode在NFS上的metadata文件拷貝到secondary namenode,然后啟動這個secondary namenode,讓它成為namenode。
四、單點故障(單點失效)問題
4.1、單點故障問題
如果NameNode失效,那么客戶端或MapReduce作業均無法讀寫查看文件
4.2、解決方案
1)啟動一個擁有文件系統元數據的新NameNode(這個一般不采用,因為復制元數據非常耗時間)
2)配置一對活動-備用(Active-Sandby)NameNode,活動NameNode失效時,備用NameNode立即接管,用戶不會有明顯中斷感覺。
共享編輯日志文件(借助NFS、zookeeper等)
DataNode同時向兩個NameNode匯報數據塊信息
客戶端采用特定機制處理 NameNode失效問題,該機制對用戶透明
五、細說HDFS高可用性(HA:High-Availability)
1)前面在(2. Namenodes和Datanodes)提到的通過備份namenode上的持久化信息,或者通過secondary namenode的方式,只能解決數據不丟失,但是不能提供HA(高可用性),
namenode仍然是“單點失敗”(SPOF:single point of failure)。如果namenode死掉了,所有的客戶端都不能訪問HDFS文件系統里的文件了,不能讀寫也不能列出文件列表。
六、HDFS的shell(命令行客戶端)操作
6.1、HDFS的shell操作

2)運行一個文件系統命令在Hadoop集群支持的文件系統中
6.2、HDFS DFS命令詳解
檢查需要處理的數據(假定數據已經存放在hdfs的/user/hadoop⽬錄下)
$> hadoop fs -ls /user/hadoop
看到測試數據⽬錄weather_test,完整數據⽬錄weather,專利數據⽬錄patent即可,若沒有則請從服務器下載並上傳⾃⼰的⽬錄下
1)建⽴⽬錄(在hdfs的/user/xxx⽬錄下操作)
$> hdfs dfs -mkdir input
2)查看⽂件或⽬錄
$> hdfs dfs -ls
3)⽂件上傳(將本地⽂件local_file上傳到hdfs的/user/xxx⽬錄下)
$> hdfs dfs -put local_file input
4)下載⽂件或⽬錄到本地當前⽬錄下
$> hdfs dfs -get input .
5)瀏覽hdfs中的⽂件
$> hdfs dfs -cat input/local_file
6)刪除⽂件或者⽬錄
$> hdfs dfs -rm input/local_file
7)在hdfs中復制⽂件或⽬錄
$> hdfs dfs -cp input/local_file input/local_file.bak
8)修改權限
9)查看命令幫助
$> hdfs dfs -help [cmd]
6.3、HDFS管理命令
1)系統⽬錄檢查
$> hdfs fsck /user/xxx系統⽬錄詳細檢測
$> hdfs fsck /user/xxx -files -blocks -locations -racks
2)檢測DataNode報告
$> hdfs dfsadmin -report
3)權限管理
$> hdfs fs -chmod 666 /user/xxx
4)hdfs空間⽬錄配額設置
$> hdfs dfsadmin -setSpaceQuota [N] /user/xxx
5)hdfs空間⽬錄配額清除
$> hdfs dfsadmin -clrSpaceQuota /user/xxx
6)查看⽬錄配額設置
$> hdfs fs -count -q /user/xxx
7)刪除DataNode
$> hdfs dfsadmin -refreshNodes
總結:
注意HDFS中的文件系統也是和linux文件系統一樣的。既然是文件系統也有根目錄和家目錄,在HDFS中“/”代表的就是根目錄,而“/user”等於linux中的“/usr”下一級目錄代表的就是用戶了。
但是HDFS沒有這個用戶,所以就有了虛擬用戶,也就是你當前HDFS的Linux系統當前用戶就會默認為它的虛擬用戶。當我們有一個zyh用戶時,所以你就可以創建一個/user/zyh/下面的目錄,就代表着家目錄。