文章目錄
1. HDFS概述
HDFS(Hadoop Distributed File System)是 Apache Hadoop 項目的一個子項目. Hadoop 非常適於存儲大型數據 (比如 TB 和 PB), 其就是使用 HDFS 作爲存儲系統. HDFS 使用多臺計算機存儲文件, 並且提供統一的訪問接口, 像是訪問一個普通文件系統一樣使用分佈式文件系統.
2. 應用場景
-
適合的應用場景:
- 存儲大文件:量級TB級,高吞吐量,無延時要求
- 流式數據訪問方式:一次寫入,多次讀取
- 商業硬件:用於廉價機器上
- 高容錯性
- 需要擴展能力的數據存儲
-
不適合的應用場景:
- 低延時的數據訪問:延時要求較高,例如毫秒級別
- 大量小文件:因爲文件系統的文件數與namenode的大小有關,文件數量太多會造成較大代價
- 多方讀寫,需要任意的文件修改:HDFS採用追加(append-only)的方式寫入數據。不支持文件任意offset的修改。不支持多個寫入器
3. HDFS架構
HDFS是主/從(master/slave)架構,分爲四個部分:HDFS Client、NameNode、DataNode和Secondary NameNode
-
**Client:**客戶端
- 文件切分。文件上傳 HDFS 的時候,Client 將文件切分成 一個一個的Block,然後進行存儲。
- 與 NameNode 交互,獲取文件的位置信息。
- 與 DataNode 交互,讀取或者寫入數據。
- Client 提供一些命令來管理和訪問HDFS,比如啓動或者關閉HDFS。
-
**NameNode:**Master,管理者
- 管理HDFS的名稱空間
- 管理數據塊的映射信息
- 配置副本策略(副本位置及個數設置)
- 處理客戶端讀寫請求
-
**DataNode:**Slave,執行者
- 存儲數據塊
- 執行數據塊的讀/寫操作
-
Secondary NameNode:並非 NameNode 的熱備份,只是NameNode的輔助,和NameNode功能並非完全一樣。當NameNode 掛掉的時候,它並不能馬上替換 NameNode 並提供服務。
- 輔助 NameNode,分擔其工作量。
- 定期合併 fsimage和fsedits,並推送給NameNode。
- 在緊急情況下,可輔助恢復 NameNode。
4. NameNode和DataNode
4.1 NameNode
NameNode在內存中保存着整個文件系統的名稱空間(文件路徑)和文件數據塊的地址映射
HDFS存儲的文件數取決於NameNode的大小
-
NameNode元數據信息:文件名,文件目錄結構,文件屬性(生成時間,副本數,權限),每個文件的塊列表,以及列表中的塊與塊所在的DataNode之間的地址映射關係
-
NameNode文件操作:NameNode負責文件元數據的操作
-
NameNode副本:NameNode決定文件數據塊到底存放到哪些DataNode上,有準備的策略(機架感知)
-
NameNode心跳機制:全權管理數據塊的複製,週期性的接受心跳和塊的狀態報告信息。若接受到心跳信息,NameNode認爲DataNode工作正常,如果在10分鐘後還接受到不到DN的心跳,那麼NameNode認爲DataNode已經宕機 ,這時候NN準備要把DN上的數據塊進行重新的複製。 塊的狀態報告包含了一個DN上所有數據塊的列表,blocks report 每個1小時發送一次
4.2 DataNode
提供真實文件數據的存儲服務
-
Data Node以數據塊的形式存儲HDFS文件
-
Data Node 響應HDFS 客戶端讀寫請求
-
Data Node 週期性向NameNode彙報心跳信息
-
Data Node 週期性向NameNode彙報數據塊信息
-
Data Node 週期性向NameNode彙報緩存數據塊信息
5. HDFS的文件副本機制和機架感知
5.1 文件副本機制
在 Hadoop1 當中, 文件的 block 塊默認大小是 64M, hadoop2 當中, 文件的 block 塊大小默認是 128M, block 塊的大小可以通過 hdfs-site.xml 當中的配置文件進行指定
<property>
<name>dfs.block.size</name>
<value>塊大小 以字節爲單位</value>
</property>
切分時,每個block可以看作是邏輯單位,每個block的大小不一定相等
每個block默認三個副本,可以通過 hdfs-site.xml 當中的配置文件進行指定
<property>
<name>dfs.replication</name>
<value>block個數</value>
</property>
5.2 機架感知
HDFS分佈式文件系統的內部有一個副本存放策略:以默認的副本數=3爲例:
-
第一個副本塊存本機
-
第二個副本塊存跟本機同機架內的其他服務器節點
-
第三個副本塊存不同機架的一個服務器節點上
6. HDFS的命令行使用
先要啓動hadoop
# 啓動zookeeper
/export/servers/zookeeper-3.4.9/bin/zkServer.sh start
# 啓動HDFS
cd /export/servers/hadoop-2.7.5/
sbin/start-dfs.sh
# 啓動yarn
sbin/start-yarn.sh
# 啓動歷史完成任務
sbin/mr-jobhistory-daemon.sh start historyserver
ls
格式: hdfs dfs -ls URI
作用:類似於Linux的ls命令,顯示文件列表
hdfs dfs -ls /
ls -R
格式 : hdfs dfs -ls -R URI
作用 : 在整個目錄下遞歸執行ls, 與UNIX中的ls-R類似
hdfs dfs -ls -R /
mkdir
格式 : hdfs dfs [-p] -mkdir <paths>
作用 : 以<paths>中的URI作爲參數,創建目錄。使用-p參數可以遞歸創建目錄
put
格式 : hdfs dfs -put <源文件路徑> ... <目標路徑>
作用 : 將單個的源文件src或者多個源文件srcs從本地文件系統拷貝到目標文件系統中(<dst>對應的路徑)。也可以從標準輸入中讀取輸入,寫入目標文件系統中
hdfs dfs -put /root/a.txt /dir1
moveFromLocal
格式: hdfs dfs -moveFromLocal <源文件路徑> <目標路徑>
作用: 和put命令類似,但是源文件localsrc拷貝之後自身被刪除
hdfs dfs -moveFromLocal /root/install.log /
get
格式 hdfs dfs -get [-ignorecrc ] [-crc] <HDFS路徑> <本地路徑>
作用:將文件拷貝到本地文件系統。 CRC 校驗失敗的文件通過-ignorecrc選項拷貝。 文件和CRC校驗和可以通過-CRC選項拷貝
hdfs dfs -get /install.log /export/servers
mv
格式 : hdfs dfs -mv URI <dest>
作用: 將hdfs上的文件從原路徑移動到目標路徑(移動之後文件刪除),該命令不能跨文件系統(不能本地到HDFS)
hdfs dfs -mv /dir1/a.txt /dir2
rm
格式: hdfs dfs -rm [-r] 【-skipTrash】 URI 【URI 。。。】
作用: 刪除參數指定的文件,參數可以有多個。 此命令只刪除文件和非空目錄。
如果指定-skipTrash選項,那麼在回收站可用的情況下,該選項將跳過回收站而直接刪除文件;
否則,在回收站可用時,在HDFS Shell 中執行此命令,會將文件暫時放到回收站中。
hdfs dfs -rm -r /dir1
cp
格式: hdfs dfs -cp URI [URI ...] <dest>
作用: 將文件拷貝到目標路徑中。如果<dest> 爲目錄的話,可以將多個文件拷貝到該目錄下。
-f
選項將覆蓋目標,如果它已經存在。
-p
選項將保留文件屬性(時間戳、所有權、許可、ACL、XAttr)。
hdfs dfs -cp /dir1/a.txt /dir2/b.txt
cat
hdfs dfs -cat URI [uri ...]
作用:將參數所指示的文件內容輸出到stdout
hdfs dfs -cat /install.log
chmod
格式: hdfs dfs -chmod [-R] URI[URI ...]
作用: 改變文件權限。如果使用 -R 選項,則對整個目錄有效遞歸執行。使用這一命令的用戶必須是文件的所屬用戶,或者超級用戶。
hdfs dfs -chmod -R 777 /install.log
chown
格式: hdfs dfs -chmod [-R] URI[URI ...]
作用: 改變文件的所屬用戶和用戶組。如果使用 -R 選項,則對整個目錄有效遞歸執行。使用這一命令的用戶必須是文件的所屬用戶,或者超級用戶。
hdfs dfs -chown -R hadoop:hadoop /install.log
appendToFile
格式: hdfs dfs -appendToFile <localsrc> ... <dst>
作用: 追加一個或者多個文件到hdfs指定文件中.也可以從命令行讀取輸入.
hdfs dfs -appendToFile a.xml b.xml /big.xml
7. HDFS的其他命令
7.1 文件限額配置
hdfs文件的限額配置允許我們以文件個數,或者文件大小來限制我們在某個目錄下上傳的文件數量或者文件內容總量,以便達到我們類似百度網盤網盤等限制每個用戶允許上傳的最大的文件的量。
# 創建hdfs文件夾
hdfs dfs -mkdir -p /user/root/dir
# 查看配額信息
hdfs dfs -count -q -h /user/root/dir
- 對其進行文件數量限額和大小限額
# 給該文件夾下面設置最多上傳兩個文件,設置n個限額,實際上只能放n-1個文件
hdfs dfsadmin -setQuota 2 dir
# 限制空間大小384M,設置大小是blocksize*3的倍速
hdfs dfsadmin -setSpaceQuota 384M /user/root/dir
#生成2M大小的文件,2M=bs*count
dd if=/dev/zero of=1.txt bs=1M count=2
# 查看配額信息
hdfs dfs -count -q -h /user/root/dir
- 清除限額設置
# 清除文件數量限制
hdfs dfsadmin -clrQuota /user/root/dir
# 清除空間配額限制
hdfs dfsadmin -clrSpaceQuota /user/root/dir
# 查看配額信息
hdfs dfs -count -q -h /user/root/dir
7.2 HDFS的安全模式
安全模式是hadoop的一種保護機制,用於保證集羣中的數據塊的安全性。當集羣啓動的時候,會首先進入安全模式,當系統處於安全模式時會檢查數據塊的完整性。
假設我們設置的副本數(即參數dfs.replication)是3,那麼在datanode上就應該有3個副本存在,假設只存在2個副本,那麼比例就是2/3=0.666。hdfs默認的副本率0.999。我們的副本率0.666明顯小於0.999,因此係統會自動的複製副本到其他dataNode,使得副本率不小於0.999。如果系統中有5個副本,超過我們設定的3個副本,那麼系統也會刪除多於的2個副本。
在安全模式狀態下,文件系統只接受讀數據請求,而不接受刪除、修改等變更請求。在,當整個系統達到安全標準時,HDFS自動離開安全模式。
#查看安全模式狀態
hdfs dfsadmin -safemode get
#進入安全模式
hdfs dfsadmin -safemode enter
#離開安全模式
hdfs dfsadmin -safemode leave
可以在網頁上查看
8. HDFS基準測試
實際生產環境當中,hadoop的環境搭建完成之後,第一件事情就是進行壓力測試,測試我們的集羣的讀取和寫入速度,測試我們的網絡帶寬是否足夠等一些基準測試
8.1 寫入速度測試
向HDFS文件系統中寫入數據,10個文件,每個文件10MB,文件存放到/benchmarks/TestDFSIO中
# 對TestDFSIO進行write測試,一次測試10個文件,每個文件10M
hadoop jar /export/servers/hadoop-2.7.5/share/hadoop/mapreduce/hadoop-mapreduce-client-jobclient-2.7.5.jar TestDFSIO -write -nrFiles 10 -fileSize 10MB
8.2 讀取速度測試
在HDFS文件系統中讀入10個文件,每個文件10M
hadoop jar /export/servers/hadoop-2.7.5/share/hadoop/mapreduce/hadoop-mapreduce-client-jobclient-2.7.5.jar TestDFSIO -read -nrFiles 10 -fileSize 10MB
8.3 清除測試數據
hadoop jar /export/servers/hadoop-2.7.5/share/hadoop/mapreduce/hadoop-mapreduce-client-jobclient-2.7.5.jar TestDFSIO -clean
9. HDFS的元數據輔助管理
在Hadoop 集羣中, NameNode的所有元數據信息都保存在了 FsImage 和 Eidts 文件中
元數據的配置文件在hadoop-2.7.5/etc/hadoop/hdfs-site.xml中
<property>
<!-- 指定NameNode元數據的存放位置 -->
<name>dfs.namenode.name.dir</name>
<value>
file:///export/servers/hadoop2.7.5/hadoopDatas/namenodeDatas, file:///export/servers/hadoop-2.7.5/hadoopDatas/namenodeDatas2
</value>
</property>
<property>
<!-- 指定NameNode日誌文件的存放位置 -->
<name>dfs.namenode.edits.dir</name>
<value>file:///export/servers/hadoop-2.7.5/hadoopDatas/nn/edits</value
</property>>
9.1 FsImage
fsimage內容包含了 NameNode 管理下的所有 DataNode 文件及文件 block 及 block 所在的 DataNode 的元數據信息.
使用hdfs oiv
可以查看fsimage中的文件信息
cd /export/servers/hadoop2.7.5/hadoopDatas/namenodeDatas/current
# 將文件複製到其他路徑,再查看
cp fsimage_0000000000000000223 /export/servers/
# 用xml格式解析文件並存到my_fsimage.xml中
hdfs oiv -i fsimage_0000000000000000223 -p XML -o my_fsimage.xml
9.2 Edits
edits 存放了客戶端最近一段時間的操作日誌,客戶端對 HDFS 進行寫文件時會首先被記錄在 edits 文件中,edits 修改時元數據也會更新。隨着 edits 內容增大, 就需要在一定時間點和 fsimage合併
使用hdfs oev
可以查看fsimage中的文件信息
cd /export/servers/hadoop2.7.5/hadoopDatas/nn/edits/current
# 將文件複製到其他路徑,再查看
cp edits_0000000000000000001-0000000000000000002 /export/servers/
# 用xml格式解析文件並存到my_fsimage.xml中
hdfs oev -i edits_0000000000000000001-0000000000000000002 -p XML -o my_edits.xml
9.3 SecondaryNameNode輔助管理fsimage 與 edits 文件
SecondaryNameNode 定期合併 fsimage 和 edits得到新的fsimage,並用新的fsimage來替代原來的fsimage,合併後原來的edits數據清空,重新記錄新的數據,具體過程如下:
- SecondaryNameNode 通知 NameNode 切換 editlog
- SecondaryNameNode 從 NameNode 中獲得 fsimage 和 editlog(通過http方式)
- SecondaryNameNode 將 fsimage 載入內存, 然後開始合併 editlog, 合併之後成爲新的 fsimage
- SecondaryNameNode 將新的 fsimage 發回給 NameNode
- NameNode 用新的 fsimage 替換舊的 fsimage
SecondaryNameNode 從 NameNode 中通過 Http GET 獲得 edits, 因爲要和 fsimage 合併, 所以也是通過 Http Get 的方式把 fsimage 加載到內存, 然後逐一執行具體對文件系統的操作, 與 fsimage 合併, 生成新的 fsimage, 然後通過 Http POST 的方式把 fsimage 發送給 NameNode. NameNode 從 SecondaryNameNode 獲得了 fsimage 後會把原有的 fsimage 替換爲新的 fsimage, 把 edits.new 變成 edits. 同時會更新 fstime
SecondaryNameNode 在合併 edits 和 fsimage 時需要消耗的內存和 NameNode 差不多, 所以一般把 NameNode 和 SecondaryNameNode 放在不同的機器上