大數(shù)據(jù)離線階段-03
HDFS入門
HDFS基本概念
HDFS介紹
HDFS是Hadoop Distribute File System 的簡稱,意為:Hadoop分布式文件系統(tǒng)。是Hadoop核心組件之一,作為最底層的分布式存儲服務(wù)而存在。
分布式文件系統(tǒng)解決的問題就是大數(shù)據(jù)存儲。它們是橫跨在多臺計算機(jī)上的存儲系統(tǒng)。分布式文件系統(tǒng)在大數(shù)據(jù)時代有著廣泛的應(yīng)用前景,它們?yōu)榇鎯吞幚沓笠?guī)模數(shù)據(jù)提供所需的擴(kuò)展能力。

HDFS設(shè)計目標(biāo)
硬件故障是常態(tài), HDFS將有成百上千的服務(wù)器組成,每一個組成部分都有可能出現(xiàn)故障。因此故障的檢測和自動快速恢復(fù)是HDFS的核心架構(gòu)目標(biāo)。
HDFS上的應(yīng)用與一般的應(yīng)用不同,它們主要是以流式讀取數(shù)據(jù)。HDFS被設(shè)計成適合批量處理,而不是用戶交互式的。相較于數(shù)據(jù)訪問的反應(yīng)時間,更注重數(shù)據(jù)訪問的高吞吐量。
典型的HDFS文件大小是GB到TB的級別。所以,HDFS被調(diào)整成支持大文件。它應(yīng)該提供很高的聚合數(shù)據(jù)帶寬,一個集群中支持?jǐn)?shù)百個節(jié)點,一個集群中還應(yīng)該支持千萬級別的文件。
大部分HDFS應(yīng)用對文件要求的是write-one-read-many訪問模型。一個文件一旦創(chuàng)建、寫入、關(guān)閉之后就不需要修改了。這一假設(shè)簡化了數(shù)據(jù)一致性問題,使高吞吐量的數(shù)據(jù)訪問成為可能。
移動計算的代價比之移動數(shù)據(jù)的代價低。一個應(yīng)用請求的計算,離它操作的數(shù)據(jù)越近就越高效,這在數(shù)據(jù)達(dá)到海量級別的時候更是如此。將計算移動到數(shù)據(jù)附近,比之將數(shù)據(jù)移動到應(yīng)用所在顯然更好。
在異構(gòu)的硬件和軟件平臺上的可移植性。這將推動需要大數(shù)據(jù)集的應(yīng)用更廣泛地采用HDFS作為平臺。
HDFS重要特性
首先,它是一個文件系統(tǒng),用于存儲文件,通過統(tǒng)一的命名空間目錄樹來定位文件;
其次,它是分布式的,由很多服務(wù)器聯(lián)合起來實現(xiàn)其功能,集群中的服務(wù)器有各自的角色。

master/slave架構(gòu)
HDFS采用master/slave架構(gòu)。一般一個HDFS集群是有一個Namenode和一定數(shù)目的Datanode組成。
Namenode是HDFS集群主節(jié)點,Datanode是HDFS集群從節(jié)點,兩種角色各司其職,共同協(xié)調(diào)完成分布式的文件存儲服務(wù)。
分塊存儲
HDFS中的文件在物理上是分塊存儲(block)的,塊的大小可以通過配置參數(shù)來規(guī)定,默認(rèn)大小在hadoop2.x版本中是128M。
名字空間(NameSpace)
HDFS支持傳統(tǒng)的層次型文件組織結(jié)構(gòu)。用戶或者應(yīng)用程序可以創(chuàng)建目錄,然后將文件保存在這些目錄里。文件系統(tǒng)名字空間的層次結(jié)構(gòu)和大多數(shù)現(xiàn)有的文件系統(tǒng)類似:用戶可以創(chuàng)建、刪除、移動或重命名文件。
Namenode負(fù)責(zé)維護(hù)文件系統(tǒng)的名字空間,任何對文件系統(tǒng)名字空間或?qū)傩缘男薷亩紝⒈籒amenode記錄下來。
HDFS會給客戶端提供一個統(tǒng)一的抽象目錄樹,客戶端通過路徑來訪問文件,形如:hdfs://namenode:port/dir-a/dir-b/dir-c/file.data。
Namenode元數(shù)據(jù)管理
我們把目錄結(jié)構(gòu)及文件分塊位置信息叫做元數(shù)據(jù)。Namenode負(fù)責(zé)維護(hù)整個hdfs文件系統(tǒng)的目錄樹結(jié)構(gòu),以及每一個文件所對應(yīng)的block塊信息(block的id,及所在的datanode服務(wù)器)。
Datanode數(shù)據(jù)存儲
文件的各個block的具體存儲管理由datanode節(jié)點承擔(dān)。每一個block都可以在多個datanode上。Datanode需要定時向Namenode匯報自己持有的block信息。
副本機(jī)制
為了容錯,文件的所有block都會有副本。每個文件的block大小和副本系數(shù)都是可配置的。應(yīng)用程序可以指定某個文件的副本數(shù)目。副本系數(shù)可以在文件創(chuàng)建的時候指定,也可以在之后改變。
副本數(shù)量也可以通過參數(shù)設(shè)置dfs.replication,默認(rèn)是3。
一次寫入,多次讀出
HDFS是設(shè)計成適應(yīng)一次寫入,多次讀出的場景,且不支持文件的修改。
正因為如此,HDFS適合用來做大數(shù)據(jù)分析的底層存儲服務(wù),并不適合用來做.網(wǎng)盤等應(yīng)用,因為,修改不方便,延遲大,網(wǎng)絡(luò)開銷大,成本太高。
HDFS基本操作
Shell 命令行客戶端
Hadoop提供了文件系統(tǒng)的shell命令行客戶端,使用方法如下:
hadoop ?fs <args>
文件系統(tǒng)shell包括與Hadoop分布式文件系統(tǒng)(HDFS)以及Hadoop支持的其他文件系統(tǒng)(如本地FS,HFTP FS,S3 FS等)直接交互的各種類似shell的命令。所有FS shell命令都將路徑URI作為參數(shù)。
URI格式為scheme://authority/path。對于HDFS,該scheme是hdfs,對于本地FS,該scheme是file。scheme和authority是可選的。如果未指定,則使用配置中指定的默認(rèn)方案。
對于HDFS,命令示例如下:
hadoop fs -ls ?hdfs://namenode:host/parent/child
hadoop fs -ls ?/parent/child ? ?fs.defaultFS中有配置
對于本地文件系統(tǒng),命令示例如下:
hadoop fs -ls file:///root/
如果使用的文件系統(tǒng)是HDFS,則使用hdfs dfs也是可以的,此時
hadoop fs <args> = hdfs dfs <args>

Shell常用命令介紹
-ls
使用方法:hadoop fs -ls [-h] [-R] <args>
功能:顯示文件、目錄信息。
示例:hadoop fs -ls /user/hadoop/file1
-mkdir
使用方法:hadoop fs -mkdir [-p] <paths>
功能:在hdfs上創(chuàng)建目錄,-p表示會創(chuàng)建路徑中的各級父目錄。
示例:hadoop fs -mkdir –p /user/hadoop/dir1
-put使用方法:hadoop fs -put [-f] [-p] [ -|<localsrc1> .. ]. <dst>
功能:將單個src或多個srcs從本地文件系統(tǒng)復(fù)制到目標(biāo)文件系統(tǒng)。
-p:保留訪問和修改時間,所有權(quán)和權(quán)限。
-f:覆蓋目的地(如果已經(jīng)存在)
示例:hadoop fs -put -f localfile1 localfile2 /user/hadoop/hadoopdir
-get
使用方法:hadoop fs -get [-ignorecrc] [-crc] [-p] [-f] <src> <localdst>
-ignorecrc:跳過對下載文件的CRC檢查。
-crc:為下載的文件寫CRC校驗和。
功能:將文件復(fù)制到本地文件系統(tǒng)。
示例:hadoop fs -get hdfs://host:port/user/hadoop/file localfile
-appendToFile
使用方法:hadoop fs -appendToFile <localsrc> ... <dst>
功能:追加一個文件到已經(jīng)存在的文件末尾
示例:hadoop fs -appendToFile localfile ?/hadoop/hadoopfile
-cat
使用方法:hadoop fs -cat [-ignoreCrc] URI [URI ...]
功能:顯示文件內(nèi)容到stdout
示例:hadoop fs -cat ?/hadoop/hadoopfile
-tail
使用方法:hadoop fs -tail [-f] URI
功能:將文件的最后一千字節(jié)內(nèi)容顯示到stdout。
-f選項將在文件增長時輸出附加數(shù)據(jù)。
示例:hadoop ?fs ?-tail ?/hadoop/hadoopfile
-chgrp
使用方法:hadoop fs -chgrp [-R] GROUP URI [URI ...]
功能:更改文件組的關(guān)聯(lián)。用戶必須是文件的所有者,否則是超級用戶。
-R將使改變在目錄結(jié)構(gòu)下遞歸進(jìn)行。
示例:hadoop fs -chgrp othergroup /hadoop/hadoopfile
-chmod
功能:改變文件的權(quán)限。使用-R將使改變在目錄結(jié)構(gòu)下遞歸進(jìn)行。
示例:hadoop ?fs ?-chmod ?666 ?/hadoop/hadoopfile
-chown
功能:改變文件的擁有者。使用-R將使改變在目錄結(jié)構(gòu)下遞歸進(jìn)行。
示例:hadoop ?fs ?-chown ?someuser:somegrp ? /hadoop/hadoopfile
-cp
功能:從hdfs的一個路徑拷貝hdfs的另一個路徑
示例: hadoop ?fs ?-cp ?/aaa/jdk.tar.gz ?/bbb/jdk.tar.gz.2
-mv ?
功能:在hdfs目錄中移動文件
示例: hadoop ?fs ?-mv ?/aaa/jdk.tar.gz ?/
-getmerge
功能:合并下載多個文件
示例:比如hdfs的目錄 /aaa/下有多個文件:log.1, log.2,log.3,...
hadoop fs -getmerge /aaa/log.* ?./log.sum
-rm
功能:刪除指定的文件。只刪除非空目錄和文件。-r 遞歸刪除。
示例:hadoop fs -rm -r /aaa/bbb/
-df
功能:統(tǒng)計文件系統(tǒng)的可用空間信息
示例:hadoop ?fs ?-df ?-h ?/
-du
功能:顯示目錄中所有文件大小,當(dāng)只指定一個文件時,顯示此文件的大小。
示例:hadoop fs -du /user/hadoop/dir1
-setrep
功能:改變一個文件的副本系數(shù)。-R選項用于遞歸改變目錄下所有文件的副本系數(shù)。
示例:hadoop fs -setrep -w 3 -R /user/hadoop/dir1
HDFS基本原理
NameNode概述
NameNode是HDFS的核心。
NameNode也稱為Master。
NameNode僅存儲HDFS的元數(shù)據(jù):文件系統(tǒng)中所有文件的目錄樹,并跟蹤整個集群中的文件。
NameNode不存儲實際數(shù)據(jù)或數(shù)據(jù)集。數(shù)據(jù)本身實際存儲在DataNodes中。
NameNode知道HDFS中任何給定文件的塊列表及其位置。使用此信息NameNode知道如何從塊中構(gòu)建文件。
NameNode并不持久化存儲每個文件中各個塊所在的DataNode的位置信息,這些信息會在系統(tǒng)啟動時從數(shù)據(jù)節(jié)點重建。
NameNode對于HDFS至關(guān)重要,當(dāng)NameNode關(guān)閉時,HDFS / Hadoop集群無法訪問。
NameNode是Hadoop集群中的單點故障。
NameNode所在機(jī)器通常會配置有大量內(nèi)存(RAM)。

DataNode概述
DataNode負(fù)責(zé)將實際數(shù)據(jù)存儲在HDFS中。
DataNode也稱為Slave。
NameNode和DataNode會保持不斷通信。
DataNode啟動時,它將自己發(fā)布到NameNode并匯報自己負(fù)責(zé)持有的塊列表。
當(dāng)某個DataNode關(guān)閉時,它不會影響數(shù)據(jù)或群集的可用性。NameNode將安排由其他DataNode管理的塊進(jìn)行副本復(fù)制。
DataNode所在機(jī)器通常配置有大量的硬盤空間。因為實際數(shù)據(jù)存儲在DataNode中。
DataNode會定期(dfs.heartbeat.interval配置項配置,默認(rèn)是3秒)向NameNode發(fā)送心跳,如果NameNode長時間沒有接受到DataNode發(fā)送的心跳, NameNode就會認(rèn)為該DataNode失效。
block匯報時間間隔取參數(shù)dfs.blockreport.intervalMsec,參數(shù)未配置的話默認(rèn)為6小時.

HDFS的工作機(jī)制
NameNode負(fù)責(zé)管理整個文件系統(tǒng)元數(shù)據(jù);DataNode負(fù)責(zé)管理具體文件數(shù)據(jù)塊存儲;Secondary NameNode協(xié)助NameNode進(jìn)行元數(shù)據(jù)的備份。
HDFS的內(nèi)部工作機(jī)制對客戶端保持透明,客戶端請求訪問HDFS都是通過向NameNode申請來進(jìn)行。

HDFS寫數(shù)據(jù)流程

詳細(xì)步驟解析:
1.client發(fā)起文件上傳請求,通過RPC與NameNode建立通訊,NameNode檢查目標(biāo)文件是否已存在,父目錄是否存在,返回是否可以上傳;
2.client請求第一個 block該傳輸?shù)侥男〥ataNode服務(wù)器上;
3.NameNode根據(jù)配置文件中指定的備份數(shù)量及副本放置策略進(jìn)行文件分配,返回可用的DataNode的地址,如:A,B,C;注:默認(rèn)存儲策略由BlockPlacementPolicyDefault類支持。也就是日常生活中提到最經(jīng)典的3副本策略。1st replica 如果寫請求方所在機(jī)器是其中一個datanode,則直接存放在本地,否則隨機(jī)在集群中選擇一個datanode.2nd replica 第二個副本存放于不同第一個副本的所在的機(jī)架.3rd replica 第三個副本存放于第二個副本所在的機(jī)架,但是屬于不同的節(jié)點

4.client請求3臺DataNode中的一臺A上傳數(shù)據(jù)(本質(zhì)上是一個RPC調(diào)用,建立pipeline),A收到請求會繼續(xù)調(diào)用B,然后B調(diào)用C,將整個pipeline建立完成,后逐級返回client;
5.client開始往A上傳第一個block(先從磁盤讀取數(shù)據(jù)放到一個本地內(nèi)存緩存),以packet為單位(默認(rèn)64K),A收到一個packet就會傳給B,B傳給C;A每傳一個packet會放入一個應(yīng)答隊列等待應(yīng)答。
6.數(shù)據(jù)被分割成一個個packet數(shù)據(jù)包在pipeline上依次傳輸,在pipeline反方向上,逐個發(fā)送ack(命令正確應(yīng)答),最終由pipeline中第一個DataNode節(jié)點A將pipeline ack發(fā)送給client;
7.當(dāng)一個block傳輸完成之后,client再次請求NameNode上傳第二個block到服務(wù)器。
HDFS讀數(shù)據(jù)流程

詳細(xì)步驟解析:
Client向NameNode發(fā)起RPC請求,來確定請求文件block所在的位置;
NameNode會視情況返回文件的部分或者全部block列表,對于每個block,NameNode都會返回含有該block副本的DataNode地址;
這些返回的DN地址,會按照集群拓?fù)浣Y(jié)構(gòu)得出DataNode與客戶端的距離,然后進(jìn)行排序,排序兩個規(guī)則:網(wǎng)絡(luò)拓?fù)浣Y(jié)構(gòu)中距離Client近的排靠前;心跳機(jī)制中超時匯報的DN狀態(tài)為STALE,這樣的排靠后;
Client選取排序靠前的DataNode來讀取block,如果客戶端本身就是DataNode,那么將從本地直接獲取數(shù)據(jù);
底層上本質(zhì)是建立FSDataInputStream,重復(fù)的調(diào)用父類DataInputStream的read方法,直到這個塊上的數(shù)據(jù)讀取完畢;一旦到達(dá)塊的末尾,DFSInputStream 關(guān)閉連接并繼續(xù)定位下一個塊的下一個 DataNode;
當(dāng)讀完列表的block后,若文件讀取還沒有結(jié)束,客戶端會繼續(xù)向NameNode獲取下一批的block列表;一旦客戶端完成讀取,它就會調(diào)用 close() 方法。
讀取完一個block都會進(jìn)行checksum驗證,如果讀取DataNode時出現(xiàn)錯誤,客戶端會通知NameNode,然后再從下一個擁有該block副本的DataNode繼續(xù)讀。
NameNode只是返回Client請求包含塊的DataNode地址,并不是返回請求塊的數(shù)據(jù);
最終讀取來所有的block會合并成一個完整的最終文件。
HDFS其他功能
不同集群之間的數(shù)據(jù)復(fù)制
在我們實際工作當(dāng)中,極有可能會遇到將測試集群的數(shù)據(jù)拷貝到生產(chǎn)環(huán)境集群,或者將生產(chǎn)環(huán)境集群的數(shù)據(jù)拷貝到測試集群,那么就需要我們在多個集群之間進(jìn)行數(shù)據(jù)的遠(yuǎn)程拷貝,hadoop自帶也有命令可以幫我們實現(xiàn)這個功能。
集群內(nèi)部文件拷貝scp
cd /export/softwares/
scp -r jdk-8u141-linux-x64.tar.gz root@node2:/export/
跨集群之間的數(shù)據(jù)拷貝distcp
bin/hadoop distcp hdfs://node1:8020/jdk-8u141-linux-x64.tar.gz ?hdfs://cluster2:9000/
Archive檔案的使用
HDFS并不擅長存儲小文件,因為每個文件最少一個block,每個block的元數(shù)據(jù)都會在NameNode占用內(nèi)存,如果存在大量的小文件,它們會吃掉NameNode節(jié)點的大量內(nèi)存。
Hadoop Archives可以有效的處理以上問題,它可以把多個文件歸檔成為一個文件,歸檔成一個文件后還可以透明的訪問每一個文件。
如何創(chuàng)建Archive
Usage: hadoop archive -archiveName name -p <parent> <src>* <dest>
其中-archiveName是指要創(chuàng)建的存檔的名稱。比如test.har,archive的名字的擴(kuò)展名應(yīng)該是*.har。 -p參數(shù)指定文件存檔文件(src)的相對路徑。
舉個例子:-p /foo/bar a/b/c e/f/g
這里的/foo/bar是a/b/c與e/f/g的父路徑,
所以完整路徑為/foo/bar/a/b/c與/foo/bar/e/f/g
例如:如果你只想存檔一個目錄/input下的所有文件:
hadoop archive -archiveName test.har -p /input ?/outputdir
這樣就會在/outputdir目錄下創(chuàng)建一個名為test.har的存檔文件。


如何查看Archive
首先我們來看下創(chuàng)建好的har文件。使用如下的命令:
hadoop fs -ls /outputdir/test.har

這里可以看到har文件包括:兩個索引文件,多個part文件(本例只有一個)以及一個標(biāo)識成功與否的文件。part文件是多個原文件的集合,根據(jù)index文件去找到原文件。
例如上述的三個小文件1.txt 2.txt 3.txt內(nèi)容分別為1,2,3。進(jìn)行archive操作之后,三個小文件就歸檔到test.har里的part-0一個文件里。


archive作為文件系統(tǒng)層暴露給外界。所以所有的fs shell命令都能在archive上運行,但是要使用不同的URI。Hadoop Archives的URI是:
har://scheme-hostname:port/archivepath/fileinarchive ?
scheme-hostname格式為hdfs-域名:端口,如果沒有提供scheme-hostname,它會使用默認(rèn)的文件系統(tǒng)。這種情況下URI是這種形式:
har:///archivepath/fileinarchive ?
如果用har uri去訪問的話,索引、標(biāo)識等文件就會隱藏起來,只顯示創(chuàng)建檔案之前的原文件:



如何解壓Archive
按順序解壓存檔(串行):
Hadoop fs -cp har:///user/zoo/foo.har/dir1 ?hdfs:/user/zoo/newdir
要并行解壓存檔,請使用DistCp:
hadoop distcp har:///user/zoo/foo.har/dir1 ?hdfs:/user/zoo/newdir
Archive注意事項
Hadoop archives是特殊的檔案格式。一個Hadoop archive對應(yīng)一個文件系統(tǒng)目錄。Hadoop archive的擴(kuò)展名是*.har;
創(chuàng)建archives本質(zhì)是運行一個Map/Reduce任務(wù),所以應(yīng)該在Hadoop集群上運行創(chuàng)建檔案的命令;
創(chuàng)建archive文件要消耗和原文件一樣多的硬盤空間;
archive文件不支持壓縮,盡管archive文件看起來像已經(jīng)被壓縮過;
archive文件一旦創(chuàng)建就無法改變,要修改的話,需要創(chuàng)建新的archive文件。事實上,一般不會再對存檔后的文件進(jìn)行修改,因為它們是定期存檔的,比如每周或每日;
當(dāng)創(chuàng)建archive時,源文件不會被更改或刪除;
HDFS元數(shù)據(jù)管理機(jī)制
元數(shù)據(jù)管理概述
HDFS元數(shù)據(jù),按類型分,主要包括以下幾個部分:
1、文件、目錄自身的屬性信息,例如文件名,目錄名,修改信息等。
2、文件記錄的信息的存儲相關(guān)的信息,例如存儲塊信息,分塊情況,副本個數(shù)等。
3、記錄HDFS的Datanode的信息,用于DataNode的管理。
按形式分為內(nèi)存元數(shù)據(jù)和元數(shù)據(jù)文件兩種,分別存在內(nèi)存和磁盤上。
HDFS磁盤上元數(shù)據(jù)文件分為兩類,用于持久化存儲:
fsimage 鏡像文件:是元數(shù)據(jù)的一個持久化的檢查點,包含Hadoop文件系統(tǒng)中的所有目錄和文件元數(shù)據(jù)信息,但不包含文件塊位置的信息。文件塊位置信息只存儲在內(nèi)存中,是在 datanode加入集群的時候,namenode詢問datanode得到的,并且間斷的更新。
Edits 編輯日志:存放的是Hadoop文件系統(tǒng)的所有更改操作(文件創(chuàng)建,刪除或修改)的日志,文件系統(tǒng)客戶端執(zhí)行的更改操作首先會被記錄到edits文件中。
fsimage和edits文件都是經(jīng)過序列化的,在NameNode啟動的時候,它會將fsimage文件中的內(nèi)容加載到內(nèi)存中,之后再執(zhí)行edits文件中的各項操作,使得內(nèi)存中的元數(shù)據(jù)和實際的同步,存在內(nèi)存中的元數(shù)據(jù)支持客戶端的讀操作,也是最完整的元數(shù)據(jù)。
當(dāng)客戶端對HDFS中的文件進(jìn)行新增或者修改操作,操作記錄首先被記入edits日志文件中,當(dāng)客戶端操作成功后,相應(yīng)的元數(shù)據(jù)會更新到內(nèi)存元數(shù)據(jù)中。因為fsimage文件一般都很大(GB級別的很常見),如果所有的更新操作都往fsimage文件中添加,這樣會導(dǎo)致系統(tǒng)運行的十分緩慢。
HDFS這種設(shè)計實現(xiàn)著手于:一是內(nèi)存中數(shù)據(jù)更新、查詢快,極大縮短了操作響應(yīng)時間;二是內(nèi)存中元數(shù)據(jù)丟失風(fēng)險頗高(斷電等),因此輔佐元數(shù)據(jù)鏡像文件(fsimage)+編輯日志文件(edits)的備份機(jī)制進(jìn)行確保元數(shù)據(jù)的安全。
NameNode維護(hù)整個文件系統(tǒng)元數(shù)據(jù)。因此,元數(shù)據(jù)的準(zhǔn)確管理,影響著HDFS提供文件存儲服務(wù)的能力。
元數(shù)據(jù)目錄相關(guān)文件
在Hadoop的HDFS首次部署好配置文件之后,并不能馬上啟動使用,而是先要對文件系統(tǒng)進(jìn)行格式化。需要在NameNode(NN)節(jié)點上進(jìn)行如下的操作:
在這里要注意兩個概念,一個是文件系統(tǒng),此時的文件系統(tǒng)在物理上還不存在;二就是此處的格式化并不是指傳統(tǒng)意義上的本地磁盤格式化,而是一些清除與準(zhǔn)備工作。
格式化完成之后,將會在$dfs.namenode.name.dir/current目錄下創(chuàng)建如下的文件結(jié)構(gòu),這個目錄也正是namenode元數(shù)據(jù)相關(guān)的文件目錄:

其中的dfs.namenode.name.dir是在hdfs-site.xml文件中配置的,默認(rèn)值如下:

dfs.namenode.name.dir屬性可以配置多個目錄,各個目錄存儲的文件結(jié)構(gòu)和內(nèi)容都完全一樣,相當(dāng)于備份,這樣做的好處是當(dāng)其中一個目錄損壞了,也不會影響到Hadoop的元數(shù)據(jù),特別是當(dāng)其中一個目錄是NFS(網(wǎng)絡(luò)文件系統(tǒng)Network File System,NFS)之上,即使你這臺機(jī)器損壞了,元數(shù)據(jù)也得到保存。
下面對$dfs.namenode.name.dir/current/目錄下的文件進(jìn)行解釋。
VERSION
namespaceID/clusterID/blockpoolID 這些都是HDFS集群的唯一標(biāo)識符。標(biāo)識符被用來防止DataNodes意外注冊到另一個集群中的namenode上。這些標(biāo)識在聯(lián)邦(federation)部署中特別重要。聯(lián)邦模式下,會有多個NameNode獨立工作。每個的NameNode提供唯一的命名空間(namespaceID),并管理一組唯一的文件塊池(blockpoolID)。clusterID將整個集群結(jié)合在一起作為單個邏輯單元,在集群中的所有節(jié)點上都是一樣的。
storageType說明這個文件存儲的是什么進(jìn)程的數(shù)據(jù)結(jié)構(gòu)信息(如果是DataNode,storageType=DATA_NODE);
cTime NameNode存儲系統(tǒng)創(chuàng)建時間,首次格式化文件系統(tǒng)這個屬性是0,當(dāng)文件系統(tǒng)升級之后,該值會更新到升級之后的時間戳;
layoutVersion表示HDFS永久性數(shù)據(jù)結(jié)構(gòu)的版本信息,是一個負(fù)整數(shù)。
補(bǔ)充說明:
格式化集群的時候,可以指定集群的cluster_id,但是不能與環(huán)境中其他集群有沖突。如果沒有提供cluster_id,則會自動生成一個唯一的ClusterID。
$HADOOP_HOME/bin/hdfs namenode -format -clusterId <cluster_id>
seen_txid
$dfs.namenode.name.dir/current/seen_txid非常重要,是存放transactionId的文件,format之后是0,它代表的是namenode里面的edits_*文件的尾數(shù),namenode重啟的時候,會按照seen_txid的數(shù)字,循序從頭跑edits_0000001~到seen_txid的數(shù)字。所以當(dāng)你的hdfs發(fā)生異常重啟的時候,一定要比對seen_txid內(nèi)的數(shù)字是不是你edits最后的尾數(shù)。
Fsimage & edits
$dfs.namenode.name.dir/current目錄下在format的同時也會生成fsimage和edits文件,及其對應(yīng)的md5校驗文件。
Fsimage、Edits
概述
fsimage文件其實是Hadoop文件系統(tǒng)元數(shù)據(jù)的一個永久性的檢查點,其中包含Hadoop文件系統(tǒng)中的所有目錄和文件idnode的序列化信息;
fsimage包含Hadoop文件系統(tǒng)中的所有目錄和文件idnode的序列化信息;對于文件來說,包含的信息有修改時間、訪問時間、塊大小和組成一個文件塊信息等;而對于目錄來說,包含的信息主要有修改時間、訪問控制權(quán)限等信息。
edits文件存放的是Hadoop文件系統(tǒng)的所有更新操作的路徑,文件系統(tǒng)客戶端執(zhí)行的所以寫操作首先會被記錄到edits文件中。
NameNode起來之后,HDFS中的更新操作會重新寫到edits文件中,因為fsimage文件一般都很大(GB級別的很常見),如果所有的更新操作都往fsimage文件中添加,這樣會導(dǎo)致系統(tǒng)運行的十分緩慢,但是如果往edits文件里面寫就不會這樣,每次執(zhí)行寫操作之后,且在向客戶端發(fā)送成功代碼之前,edits文件都需要同步更新。如果一個文件比較大,使得寫操作需要向多臺機(jī)器進(jìn)行操作,只有當(dāng)所有的寫操作都執(zhí)行完成之后,寫操作才會返回成功,這樣的好處是任何的操作都不會因為機(jī)器的故障而導(dǎo)致元數(shù)據(jù)的不同步。
內(nèi)容查看
fsimage、edits兩個文件中的內(nèi)容使用普通文本編輯器是無法直接查看的,幸運的是hadoop為此準(zhǔn)備了專門的工具用于查看文件的內(nèi)容,這些工具分別為oev和oiv,可以使用hdfs調(diào)用執(zhí)行。
oev是offline edits viewer(離線edits查看器)的縮寫,該工具只操作文件因而并不需要hadoop集群處于運行狀態(tài)。
-i,--inputFile <arg>??
-o,--outputFile <arg> ?Name of output file.
在輸出文件中,每個RECORD記錄了一次操作,示例如下:

oiv是offline image viewer的縮寫,用于將fsimage文件的內(nèi)容轉(zhuǎn)儲到指定文件中以便于閱讀,該工具還提供了只讀的WebHDFS API以允許離線分析和檢查hadoop集群的命名空間。oiv在處理非常大的fsimage文件時是相當(dāng)快的,如果該工具不能夠處理fsimage,它會直接退出。該工具不具備向后兼容性,比如使用hadoop-2.4版本的oiv不能處理hadoop-2.3版本的fsimage,只能使用hadoop-2.3版本的oiv。同oev一樣,就像它的名稱所提示的(offline),oiv也不需要hadoop集群處于運行狀態(tài)。
-i,--inputFile <arg> ?
-o,--outputFile <arg> ?Name of output file.
在輸出文件中,每個RECORD記錄了一次操作,示例如下:


secondary namenode

NameNode職責(zé)是管理元數(shù)據(jù)信息,DataNode的職責(zé)是負(fù)責(zé)數(shù)據(jù)具體存儲,那么SecondaryNameNode的作用是什么?對很多初學(xué)者來說是非常迷惑的。它為什么會出現(xiàn)在HDFS中。從它的名字上看,它給人的感覺就像是NameNode的備份。但它實際上卻不是。
大家猜想一下,當(dāng)HDFS集群運行一段事件后,就會出現(xiàn)下面一些問題:
edit logs文件會變的很大,怎么去管理這個文件是一個挑戰(zhàn)。
NameNode重啟會花費很長時間,因為有很多改動要合并到fsimage文件上。
如果NameNode掛掉了,那就丟失了一些改動。因為此時的fsimage文件非常舊。
因此為了克服這個問題,我們需要一個易于管理的機(jī)制來幫助我們減小edit logs文件的大小和得到一個最新的fsimage文件,這樣也會減小在NameNode上的壓力。這跟Windows的恢復(fù)點是非常像的,Windows的恢復(fù)點機(jī)制允許我們對OS進(jìn)行快照,這樣當(dāng)系統(tǒng)發(fā)生問題時,我們能夠回滾到最新的一次恢復(fù)點上。
SecondaryNameNode就是來幫助解決上述問題的,它的職責(zé)是合并NameNode的edit logs到fsimage文件中。

Checkpoint
每達(dá)到觸發(fā)條件,會由secondary namenode將namenode上積累的所有edits和一個最新的fsimage下載到本地,并加載到內(nèi)存進(jìn)行merge(這個過程稱為checkpoint),如下圖所示:

Checkpoint詳細(xì)步驟
NameNode管理著元數(shù)據(jù)信息,其中有兩類持久化元數(shù)據(jù)文件:edits操作日志文件和fsimage元數(shù)據(jù)鏡像文件。新的操作日志不會立即與fsimage進(jìn)行合并,也不會刷到NameNode的內(nèi)存中,而是會先寫到edits中(因為合并需要消耗大量的資源),操作成功之后更新至內(nèi)存。
有dfs.namenode.checkpoint.period和dfs.namenode.checkpoint.txns 兩個配置,只要達(dá)到這兩個條件任何一個,secondarynamenode就會執(zhí)行checkpoint的操作。
當(dāng)觸發(fā)checkpoint操作時,NameNode會生成一個新的edits即上圖中的edits.new文件,同時SecondaryNameNode會將edits文件和fsimage復(fù)制到本地(HTTP GET方式)。
secondarynamenode將下載下來的fsimage載入到內(nèi)存,然后一條一條地執(zhí)行edits文件中的各項更新操作,使得內(nèi)存中的fsimage保存最新,這個過程就是edits和fsimage文件合并,生成一個新的fsimage文件即上圖中的Fsimage.ckpt文件。
secondarynamenode將新生成的Fsimage.ckpt文件復(fù)制到NameNode節(jié)點。
在NameNode節(jié)點的edits.new文件和Fsimage.ckpt文件會替換掉原來的edits文件和fsimage文件,至此剛好是一個輪回,即在NameNode中又是edits和fsimage文件。
等待下一次checkpoint觸發(fā)SecondaryNameNode進(jìn)行工作,一直這樣循環(huán)操作。
Checkpoint觸發(fā)條件
Checkpoint操作受兩個參數(shù)控制,可以通過core-site.xml進(jìn)行配置:
兩次連續(xù)的checkpoint之間的時間間隔。默認(rèn)1小時
從上面的描述我們可以看出,SecondaryNamenode根本就不是Namenode的一個熱備,其只是將fsimage和edits合并。其擁有的fsimage不是最新的,因為在他從NameNode下載fsimage和edits文件時候,新的更新操作已經(jīng)寫到edit.new文件中去了。而這些更新在SecondaryNamenode是沒有同步到的!當(dāng)然,如果NameNode中的fsimage真的出問題了,還是可以用SecondaryNamenode中的fsimage替換一下NameNode上的fsimage,雖然已經(jīng)不是最新的fsimage,但是我們可以將損失減小到最少!
HDFS安全模式
安全模式概述
安全模式是HDFS所處的一種特殊狀態(tài),在這種狀態(tài)下,文件系統(tǒng)只接受讀數(shù)據(jù)請求,而不接受刪除、修改等變更請求,是一種保護(hù)機(jī)制,用于保證集群中的數(shù)據(jù)塊的安全性。
在NameNode主節(jié)點啟動時,HDFS首先進(jìn)入安全模式,集群會開始檢查數(shù)據(jù)塊的完整性。DataNode在啟動的時候會向namenode匯報可用的block信息,當(dāng)整個系統(tǒng)達(dá)到安全標(biāo)準(zhǔn)時,HDFS自動離開安全模式。
假設(shè)我們設(shè)置的副本數(shù)(即參數(shù)dfs.replication)是5,那么在Datanode上就應(yīng)該有5個副本存在,假設(shè)只存在3個副本,那么比例就是3/5=0.6。在配置文件hdfs-default.xml中定義了一個最小的副本的副本率(即參數(shù)dfs.namenode.safemode.threshold-pct)0.999。
我們的副本率0.6明顯小于0.99,因此系統(tǒng)會自動的復(fù)制副本到其他的DataNode,使得副本率不小于0.999.如果系統(tǒng)中有8個副本,超過我們設(shè)定的5個副本,那么系統(tǒng)也會刪除多余的3個副本。
如果HDFS處于安全模式下,不允許HDFS客戶端進(jìn)行任何修改文件的操作,包括上傳文件,刪除文件,重命名,創(chuàng)建文件夾,修改副本數(shù)等操作。
安全模式配置
與安全模式相關(guān)主要配置在hdfs-site.xml文件中,主要有下面幾個屬性:
dfs.namenode.replication.min: 每個數(shù)據(jù)塊最小副本數(shù)量,默認(rèn)為1. 在上傳文件時,達(dá)到最小副本數(shù),就認(rèn)為上傳是成功的。
dfs.namenode.safemode.threshold-pct: 達(dá)到最小副本數(shù)的數(shù)據(jù)塊的百分比。默認(rèn)為0.999f。當(dāng)小于這個比例,那就將系統(tǒng)切換成安全模式,對數(shù)據(jù)塊進(jìn)行復(fù)制;當(dāng)大于該比例時,就離開安全模式,說明系統(tǒng)有足夠的數(shù)據(jù)塊副本數(shù),可以對外提供服務(wù)。小于等于0意味不進(jìn)入安全模式,大于1意味一直處于安全模式。
dfs.namenode.safemode.min.datanodes: 離開安全模式的最小可用datanode數(shù)量要求,默認(rèn)為0.也就是即使所有datanode都不可用,仍然可以離開安全模式。
dfs.namenode.safemode.extension: 當(dāng)集群可用block比例,可用datanode都達(dá)到要求之后,如果在extension配置的時間段之后依然能滿足要求,此時集群才離開安全模式。單位為毫秒,默認(rèn)為30000.也就是當(dāng)滿足條件并且能夠維持30秒之后,離開安全模式。 這個配置主要是對集群穩(wěn)定程度做進(jìn)一步的確認(rèn)。避免達(dá)到要求后馬上又不符合安全標(biāo)準(zhǔn)。
總結(jié)一下,要離開安全模式,需要滿足以下條件:
1)達(dá)到副本數(shù)量要求的block比例滿足要求;
2)可用的datanode節(jié)點數(shù)滿足配置的數(shù)量要求;
3) 1、2 兩個條件滿足后維持的時間達(dá)到配置的要求
安全模式命令
手動進(jìn)入安全模式
手動進(jìn)入安全模式對于集群維護(hù)或者升級的時候非常有用,因為這時候HDFS上的數(shù)據(jù)是只讀的。手動退出安全模式可以用下面命令:
如果你想獲取到集群是否處于安全模式,可以用下面的命令獲?。?/p>