轉載自微信公眾號: 五分鐘學大數(shù)據(jù)
1. HDFS概述
Hadoop 分布式系統(tǒng)框架中,首要的基礎功能就是文件系統(tǒng)炼吴,在 Hadoop 中使用 FileSystem 這個抽象類來表示我們的文件系統(tǒng),這個抽象類下面有很多子實現(xiàn)類疫衩,究竟使用哪一種硅蹦,需要看我們具體的實現(xiàn)類,在我們實際工作中闷煤,用到的最多的就是HDFS(分布式文件系統(tǒng))以及LocalFileSystem(本地文件系統(tǒng))了童芹。
在現(xiàn)代的企業(yè)環(huán)境中,單機容量往往無法存儲大量數(shù)據(jù)鲤拿,需要跨機器存儲假褪。統(tǒng)一管理分布在集群上的文件系統(tǒng)稱為分布式文件系統(tǒng)。
HDFS(Hadoop Distributed File System)是 Hadoop 項目的一個子項目近顷。是 Hadoop 的核心組件之一生音, Hadoop 非常適于存儲大型數(shù)據(jù) (比如 TB 和 PB)约谈,其就是使用 HDFS 作為存儲系統(tǒng). HDFS 使用多臺計算機存儲文件苞氮,并且提供統(tǒng)一的訪問接口鹿寨,像是訪問一個普通文件系統(tǒng)一樣使用分布式文件系統(tǒng)荆姆。
2. HDFS架構
HDFS是一個主/從(Mater/Slave)體系結構执桌,由三部分組成:NameNode 和 DataNode 以及 SecondaryNamenode:
NameNode 負責管理整個文件系統(tǒng)的元數(shù)據(jù)桅狠,以及每一個路徑(文件)所對應的數(shù)據(jù)塊信息奸笤。
DataNode 負責管理用戶的文件數(shù)據(jù)塊痕檬,每一個數(shù)據(jù)塊都可以在多個 DataNode 上存儲多個副本冤寿,默認為3個歹苦。
Secondary NameNode 用來監(jiān)控 HDFS 狀態(tài)的輔助后臺程序,每隔一段時間獲取 HDFS 元數(shù)據(jù)的快照督怜。最主要作用是輔助 NameNode 管理元數(shù)據(jù)信息殴瘦。
3. HDFS的特性
首先,它是一個文件系統(tǒng)号杠,用于存儲文件蚪腋,通過統(tǒng)一的命名空間目錄樹來定位文件;
其次姨蟋,它是分布式的屉凯,由很多服務器聯(lián)合起來實現(xiàn)其功能,集群中的服務器有各自的角色眼溶。
- 1. master/slave 架構(主從架構)
HDFS 采用 master/slave 架構悠砚。一般一個 HDFS 集群是有一個 Namenode 和一定數(shù)目的 Datanode 組成。Namenode 是 HDFS 集群主節(jié)點堂飞,Datanode 是 HDFS 集群從節(jié)點灌旧,兩種角色各司其職绑咱,共同協(xié)調(diào)完成分布式的文件存儲服務。
- 2. 分塊存儲
HDFS 中的文件在物理上是分塊存儲(block)的枢泰,塊的大小可以通過配置參數(shù)來規(guī)定描融,默認大小在 hadoop2.x 版本中是 128M。
- 3. 名字空間(NameSpace)
HDFS 支持傳統(tǒng)的層次型文件組織結構衡蚂。用戶或者應用程序可以創(chuàng)建目錄窿克,然后將文件保存在這些目錄里。文件系統(tǒng)名字空間的層次結構和大多數(shù)現(xiàn)有的文件系統(tǒng)類似:用戶可以創(chuàng)建讳窟、刪除让歼、移動或重命名文件敞恋。
Namenode 負責維護文件系統(tǒng)的名字空間丽啡,任何對文件系統(tǒng)名字空間或屬性的修改都將被 Namenode 記錄下來。
HDFS 會給客戶端提供一個統(tǒng)一的抽象目錄樹硬猫,客戶端通過路徑來訪問文件补箍,形如:hdfs://namenode:port/dir-a/dir-b/dir-c/file.data。
- 4. NameNode 元數(shù)據(jù)管理
我們把目錄結構及文件分塊位置信息叫做元數(shù)據(jù)啸蜜。NameNode 負責維護整個 HDFS 文件系統(tǒng)的目錄樹結構坑雅,以及每一個文件所對應的 block 塊信息(block 的 id,及所在的 DataNode 服務器)衬横。
- 5. DataNode 數(shù)據(jù)存儲
文件的各個 block 的具體存儲管理由 DataNode 節(jié)點承擔裹粤。每一個 block 都可以在多個 DataNode 上。DataNode 需要定時向 NameNode 匯報自己持有的 block 信息蜂林。存儲多個副本(副本數(shù)量也可以通過參數(shù)設置 dfs.replication遥诉,默認是 3)
- 6. 副本機制
為了容錯,文件的所有 block 都會有副本噪叙。每個文件的 block 大小和副本系數(shù)都是可配置的矮锈。應用程序可以指定某個文件的副本數(shù)目。副本系數(shù)可以在文件創(chuàng)建的時候指定睁蕾,也可以在之后改變苞笨。
- 7. 一次寫入,多次讀出
HDFS 是設計成適應一次寫入子眶,多次讀出的場景瀑凝,且不支持文件的修改。
正因為如此臭杰,HDFS 適合用來做大數(shù)據(jù)分析的底層存儲服務粤咪,并不適合用來做網(wǎng)盤等應用,因為修改不方便硅卢,延遲大射窒,網(wǎng)絡開銷大藏杖,成本太高。
4. HDFS 的命令行使用
如果沒有配置 hadoop 的環(huán)境變量脉顿,則在 hadoop 的安裝目錄下的bin目錄中執(zhí)行以下命令蝌麸,如已配置 hadoop 環(huán)境變量,則可在任意目錄下執(zhí)行
help
格式: hdfs dfs -help 操作命令
作用: 查看某一個操作命令的參數(shù)信息
ls
格式:hdfs dfs -ls URI
作用:類似于Linux的ls命令艾疟,顯示文件列表
lsr
格式 : hdfs dfs -lsr URI
作用 : 在整個目錄下遞歸執(zhí)行l(wèi)s, 與UNIX中的ls-R類似
mkdir
格式 :hdfs dfs -mkdir [-p] <paths>
作用 : 以<paths>中的URI作為參數(shù)来吩,創(chuàng)建目錄。使用-p參數(shù)可以遞歸創(chuàng)建目錄
put
格式 :hdfs dfs -put <localsrc > ... <dst>
作用 : 將單個的源文件src或者多個源文件srcs從本地文件系統(tǒng)拷貝到目標文件系統(tǒng)中(<dst>對應的路徑)蔽莱。
也可以從標準輸入中讀取輸入弟疆,寫入目標文件系統(tǒng)中
hdfs dfs -put /rooot/bigdata.txt /dir1
moveFromLocal
格式:hdfs dfs -moveFromLocal <localsrc> <dst>
作用: 和put命令類似,但是源文件localsrc拷貝之后自身被刪除
hdfs dfs -moveFromLocal /root/bigdata.txt /
copyFromLocal
格式: hdfs dfs -copyFromLocal <localsrc> ... <dst>
作用: 從本地文件系統(tǒng)中拷貝文件到hdfs路徑去
appendToFile
格式: hdfs dfs -appendToFile <localsrc> ... <dst>
作用: 追加一個或者多個文件到hdfs指定文件中.也可以從命令行讀取輸入.
hdfs dfs -appendToFile a.xml b.xml /big.xml
moveToLocal
# 在 hadoop 2.6.4 版本測試還未未實現(xiàn)此方法格式:
hadoop dfs -moveToLocal [-crc] <src> <dst>
作用:將本地文件剪切到 HDFS
get
格式 hdfs dfs -get [-ignorecrc ] [-crc] <src> <localdst>
作用:將文件拷貝到本地文件系統(tǒng)盗冷。
CRC 校驗失敗的文件通過-ignorecrc選項拷貝怠苔。
文件和CRC校驗可以通過-CRC選項拷貝
hdfs dfs -get /bigdata.txt /export/servers
getmerge
格式: hdfs dfs -getmerge <src> <localdst>
作用: 合并下載多個文件,比如hdfs的目錄 /aaa/下有多個文件:log.1, log.2,log.3,...
copyToLocal
格式: hdfs dfs -copyToLocal <src> ... <localdst>
作用: 從hdfs拷貝到本地
mv
格式 :hdfs dfs -mv URI <dest>
作用: 將hdfs上的文件從原路徑移動到目標路徑(移動之后文件刪除)仪糖,該命令不能跨文件系統(tǒng)
hdfs dfs -mv /dir1/bigdata.txt /dir2
rm
格式:hdfs dfs -rm [-r] 【-skipTrash】 URI 【URI 柑司。。锅劝≡艹郏】
作用: 刪除參數(shù)指定的文件,參數(shù)可以有多個故爵。
此命令只刪除文件和非空目錄玻粪。
如果指定-skipTrash選項,那么在回收站可用的情況下诬垂,該選項將跳過回收站而直接刪除文件劲室;
否則,在回收站可用時剥纷,在HDFS Shell 中執(zhí)行此命令痹籍,會將文件暫時放到回收站中。
hdfs dfs -rm -r /dir1
cp
格式: hdfs dfs -cp URI [URI ...] <dest>
作用: 將文件拷貝到目標路徑中晦鞋。
如果<dest> 為目錄的話蹲缠,可以將多個文件拷貝到該目錄下。
-f選項將覆蓋目標悠垛,如果它已經(jīng)存在线定。
-p選項將保留文件屬性(時間戳、所有權确买、許可斤讥、ACL、XAttr)。
hdfs dfs -cp /dir1/a.txt /dir2/bigdata.txt
cat
hdfs dfs -cat URI [uri ...]
作用:將參數(shù)所指示的文件內(nèi)容輸出到stdout
hdfs dfs -cat /bigdata.txt
tail
格式: hdfs dfs -tail path
作用: 顯示一個文件的末尾
text
格式:hdfs dfs -text path
作用: 以字符形式打印一個文件的內(nèi)容
chmod
格式:hdfs dfs -chmod [-R] URI[URI ...]
作用:改變文件權限芭商。
如果使用 -R 選項派草,則對整個目錄有效遞歸執(zhí)行。
使用這一命令的用戶必須是文件的所屬用戶铛楣,或者超級用戶近迁。
hdfs dfs -chmod -R 777 /bigdata.txt
chown
格式: hdfs dfs -chmod [-R] URI[URI ...]
作用:改變文件的所屬用戶和用戶組。
如果使用 -R 選項簸州,則對整個目錄有效遞歸執(zhí)行鉴竭。
使用這一命令的用戶必須是文件的所屬用戶,或者超級用戶岸浑。
hdfs dfs -chown -R hadoop:hadoop /bigdata.txt
df
格式: hdfs dfs -df -h path
作用: 統(tǒng)計文件系統(tǒng)的可用空間信息
du
格式: hdfs dfs -du -s -h path
作用: 統(tǒng)計文件夾的大小信息
count
格式: hdfs dfs -count path
作用: 統(tǒng)計一個指定目錄下的文件節(jié)點數(shù)量
setrep
格式: hdfs dfs -setrep num filePath
作用: 設置hdfs中文件的副本數(shù)量注意:
即使設置的超過了datanode的數(shù)量,
副本的數(shù)量也最多只能和datanode的數(shù)量是一致的
expunge (慎用)
格式: hdfs dfs -expunge
作用: 清空hdfs垃圾桶
5. hdfs的高級使用命令
5.1. HDFS文件限額配置
在多人共用HDFS的環(huán)境下搏存,配置設置非常重要。特別是在 Hadoop 處理大量資料的環(huán)境矢洲,如果沒有配額管理璧眠,很容易把所有的空間用完造成別人無法存取。HDFS 的配額設定是針對目錄而不是針對賬號兵钮,可以讓每個賬號僅操作某一個目錄蛆橡,然后對目錄設置配置舌界。
HDFS 文件的限額配置允許我們以文件個數(shù)掘譬,或者文件大小來限制我們在某個目錄下上傳的文件數(shù)量或者文件內(nèi)容總量,以便達到我們類似百度網(wǎng)盤網(wǎng)盤等限制每個用戶允許上傳的最大的文件的量呻拌。
hdfs dfs -count -q -h /user/root/dir1 #查看配額信息
結果:5.1.1. 數(shù)量限額
hdfs dfs -mkdir -p /user/root/dir #創(chuàng)建hdfs文件夾
hdfs dfsadmin -setQuota 2 dir # 給該文件夾下面設置最多上傳兩個文件葱轩,發(fā)現(xiàn)只能上傳一個文件
hdfs dfsadmin -clrQuota /user/root/dir # 清除文件數(shù)量限制
5.1.2. 空間大小限額
在設置空間配額時,設置的空間至少是 block_size * 3 大小
hdfs dfsadmin -setSpaceQuota 4k /user/root/dir # 限制空間大小4KB
hdfs dfs -put /root/a.txt /user/root/dir
生成任意大小文件的命令:
dd if=/dev/zero of=1.txt bs=1M count=2 #生成2M的文件
清除空間配額限制
hdfs dfsadmin -clrSpaceQuota /user/root/dir
5.2. HDFS 的安全模式
安全模式是hadoop的一種保護機制藐握,用于保證集群中的數(shù)據(jù)塊的安全性靴拱。當集群啟動的時候,會首先進入安全模式猾普。當系統(tǒng)處于安全模式時會檢查數(shù)據(jù)塊的完整性袜炕。
假設我們設置的副本數(shù)(即參數(shù)dfs.replication)是3,那么在datanode上就應該有3個副本存在初家,假設只存在2個副本偎窘,那么比例就是2/3=0.666。hdfs默認的副本率0.999溜在。我們的副本率0.666明顯小于0.999陌知,因此系統(tǒng)會自動的復制副本到其他dataNode,使得副本率不小于0.999掖肋。如果系統(tǒng)中有5個副本仆葡,超過我們設定的3個副本,那么系統(tǒng)也會刪除多于的2個副本志笼。
在安全模式狀態(tài)下沿盅,文件系統(tǒng)只接受讀數(shù)據(jù)請求把篓,而不接受刪除、修改等變更請求腰涧。在纸俭,當整個系統(tǒng)達到安全標準時,HDFS自動離開安全模式南窗。30s
安全模式操作命令
hdfs dfsadmin -safemode get #查看安全模式狀態(tài)
hdfs dfsadmin -safemode enter #進入安全模式
hdfs dfsadmin -safemode leave #離開安全模式
6. HDFS 的 block 塊和副本機制
HDFS 將所有的文件全部抽象成為 block 塊來進行存儲揍很,不管文件大小,全部一視同仁都是以 block 塊的統(tǒng)一大小和形式進行存儲万伤,方便我們的分布式文件系統(tǒng)對文件的管理窒悔。
所有的文件都是以 block 塊的方式存放在 hdfs 文件系統(tǒng)當中,在 Hadoop 1 版本當中敌买,文件的 block 塊默認大小是 64M简珠,Hadoop 2 版本當中,文件的 block 塊大小默認是128M虹钮,block塊的大小可以通過 hdfs-site.xml 當中的配置文件進行指定聋庵。
<property>
<name>dfs.block.size</name>
<value>塊大小 以字節(jié)為單位</value> //只寫數(shù)值就可以<
/property>
6.1 抽象為block塊的好處
- 一個文件有可能大于集群中任意一個磁盤
10T*3/128 = xxx塊 2T,2T芙粱,2T 文件方式存—–>多個block塊祭玉,這些block塊屬于一個文件
- 一個文件有可能大于集群中任意一個磁盤
- 使用塊抽象而不是文件可以簡化存儲子系統(tǒng)
- 塊非常適合用于數(shù)據(jù)備份進而提供數(shù)據(jù)容錯能力和可用性
6.2 塊緩存
通常 DataNode 從磁盤中讀取塊,但對于訪問頻繁的文件春畔,其對應的塊可能被顯示的緩存在 DataNode 的內(nèi)存中脱货,以堆外塊緩存的形式存在。默認情況下律姨,一個塊僅緩存在一個DataNode的內(nèi)存中振峻,當然可以針對每個文件配置DataNode的數(shù)量。作業(yè)調(diào)度器通過在緩存塊的DataNode上運行任務择份,可以利用塊緩存的優(yōu)勢提高讀操作的性能扣孟。
例如:
連接(join)操作中使用的一個小的查詢表就是塊緩存的一個很好的候選。用戶或應用通過在緩存池中增加一個cache directive來告訴namenode需要緩存哪些文件及存多久荣赶。緩存池(cache pool)是一個擁有管理緩存權限和資源使用的管理性分組凤价。
例如:
一個文件 130M,會被切分成2個block塊讯壶,保存在兩個block塊里面料仗,實際占用磁盤130M空間,而不是占用256M的磁盤空間
6.3 hdfs的文件權限驗證
hdfs的文件權限機制與linux系統(tǒng)的文件權限機制類似
r:read w:write x:execute
權限x對于文件表示忽略伏蚊,對于文件夾表示是否有權限訪問其內(nèi)容
如果linux系統(tǒng)用戶zhangsan使用hadoop命令創(chuàng)建一個文件立轧,那么這個文件在HDFS當中的owner就是zhangsan
HDFS文件權限的目的,防止好人做錯事,而不是阻止壞人做壞事氛改。HDFS相信你告訴我你是誰帐萎,你就是誰
6.4 hdfs的副本因子
為了保證block塊的安全性,也就是數(shù)據(jù)的安全性胜卤,在hadoop2當中疆导,文件默認保存三個副本,我們可以更改副本數(shù)以提高數(shù)據(jù)的安全性
葛躏、在hdfs-site.xml當中修改以下配置屬性澈段,即可更改文件的副本數(shù)
<property>
<name>dfs.replication</name>
<value>3</value>
</property>
7. HDFS 文件寫入過程(非常重要)
Client 發(fā)起文件上傳請求,通過 RPC 與 NameNode 建立通訊, NameNode 檢查目標文件是否已存在舰攒,父目錄是否存在败富,返回是否可以上傳;
Client 請求第一個 block 該傳輸?shù)侥男?DataNode 服務器上摩窃;
NameNode 根據(jù)配置文件中指定的備份數(shù)量及機架感知原理進行文件分配, 返回可用的 DataNode 的地址如:A, B, C兽叮;
Hadoop 在設計時考慮到數(shù)據(jù)的安全與高效, 數(shù)據(jù)文件默認在 HDFS 上存放三份猾愿, 存儲策略為本地一份鹦聪,同機架內(nèi)其它某一節(jié)點上一份,不同機架的某一節(jié)點上一份蒂秘。
Client 請求 3 臺 DataNode 中的一臺 A 上傳數(shù)據(jù)(本質(zhì)上是一個 RPC 調(diào)用泽本,建立 pipeline ),A 收到請求會繼續(xù)調(diào)用 B材彪,然后 B 調(diào)用 C观挎,將整個 pipeline 建立完成, 后逐級返回 client段化;
Client 開始往 A 上傳第一個 block(先從磁盤讀取數(shù)據(jù)放到一個本地內(nèi)存緩存),以 packet 為單位(默認64K)造成,A 收到一個 packet 就會傳給 B显熏,B 傳給 C。A 每傳一個 packet 會放入一個應答隊列等待應答晒屎;
數(shù)據(jù)被分割成一個個 packet 數(shù)據(jù)包在 pipeline 上依次傳輸喘蟆,在 pipeline 反方向上, 逐個發(fā)送 ack(命令正確應答)鼓鲁,最終由 pipeline 中第一個 DataNode 節(jié)點 A 將 pipelineack 發(fā)送給 Client蕴轨;
當一個 block 傳輸完成之后,Client 再次請求 NameNode 上傳第二個 block骇吭,重復步驟 2橙弱。
7.1 網(wǎng)絡拓撲概念
在本地網(wǎng)絡中,兩個節(jié)點被稱為“彼此近鄰”是什么意思?在海量數(shù)據(jù)處理中棘脐,其主要限制因素是節(jié)點之間數(shù)據(jù)的傳輸速率——帶寬很稀缺斜筐。這里的想法是將兩個節(jié)點間的帶寬作為距離的衡量標準。
節(jié)點距離:兩個節(jié)點到達最近的共同祖先的距離總和蛀缝。
例如顷链,假設有數(shù)據(jù)中心d1機架r1中的節(jié)點n1。該節(jié)點可以表示為/d1/r1/n1屈梁。利用這種標記嗤练,這里給出四種距離描述:
Distance(/d1/r1/n1, /d1/r1/n1)=0(同一節(jié)點上的進程)
Distance(/d1/r1/n1, /d1/r1/n2)=2(同一機架上的不同節(jié)點)
Distance(/d1/r1/n1, /d1/r3/n2)=4(同一數(shù)據(jù)中心不同機架上的節(jié)點)
Distance(/d1/r1/n1, /d2/r4/n2)=6(不同數(shù)據(jù)中心的節(jié)點)
7.2 機架感知(副本節(jié)點選擇)
1)低版本Hadoop副本節(jié)點選擇
第一個副本在client所處的節(jié)點上。如果客戶端在集群外在讶,隨機選一個潭苞。
第二個副本和第一個副本位于不相同機架的隨機節(jié)點上。
第三個副本和第二個副本位于相同機架真朗,節(jié)點隨機此疹。
- Hadoop2.7.2 副本節(jié)點選擇
第一個副本在client所處的節(jié)點上。如果客戶端在集群外遮婶,隨機選一個蝗碎。
第二個副本和第一個副本位于相同機架,隨機節(jié)點旗扑。
第三個副本位于不同機架蹦骑,隨機節(jié)點。
8.HDFS 文件讀取過程(非常重要)
Client向NameNode發(fā)起RPC請求臀防,來確定請求文件block所在的位置眠菇;
NameNode會視情況返回文件的部分或者全部block列表,對于每個block袱衷,NameNode 都會返回含有該 block 副本的 DataNode 地址捎废; 這些返回的 DN 地址,會按照集群拓撲結構得出 DataNode 與客戶端的距離致燥,然后進行排序登疗,排序兩個規(guī)則:網(wǎng)絡拓撲結構中距離 Client 近的排靠前;心跳機制中超時匯報的 DN 狀態(tài)為 STALE嫌蚤,這樣的排靠后辐益;
Client 選取排序靠前的 DataNode 來讀取 block,如果客戶端本身就是DataNode脱吱,那么將從本地直接獲取數(shù)據(jù)(短路讀取特性)智政;
底層上本質(zhì)是建立 Socket Stream(FSDataInputStream),重復的調(diào)用父類 DataInputStream 的 read 方法箱蝠,直到這個塊上的數(shù)據(jù)讀取完畢续捂;
當讀完列表的 block 后垦垂,若文件讀取還沒有結束,客戶端會繼續(xù)向NameNode 獲取下一批的 block 列表疾忍;
讀取完一個 block 都會進行 checksum 驗證乔外,如果讀取 DataNode 時出現(xiàn)錯誤,客戶端會通知 NameNode一罩,然后再從下一個擁有該 block 副本的DataNode 繼續(xù)讀杨幼。
read 方法是并行的讀取 block 信息,不是一塊一塊的讀取聂渊;NameNode 只是返回Client請求包含塊的DataNode地址差购,并不是返回請求塊的數(shù)據(jù);
最終讀取來所有的 block 會合并成一個完整的最終文件汉嗽。
從 HDFS 文件讀寫過程中欲逃,可以看出,HDFS 文件寫入時是串行寫入的饼暑,數(shù)據(jù)包先發(fā)送給節(jié)點A稳析,然后節(jié)點A發(fā)送給B,B再給C弓叛;而HDFS文件讀取是并行的彰居, 客戶端 Client 直接并行讀取block所在的節(jié)點。
9. NameNode 工作機制以及元數(shù)據(jù)管理(重要)
9.1 namenode 與 datanode 啟動
- namenode工作機制
第一次啟動namenode格式化后撰筷,創(chuàng)建fsimage和edits文件陈惰。如果不是第一次啟動,直接加載編輯日志和鏡像文件到內(nèi)存毕籽。
客戶端對元數(shù)據(jù)進行增刪改的請求抬闯。
namenode記錄操作日志,更新滾動日志关筒。
namenode在內(nèi)存中對數(shù)據(jù)進行增刪改查溶握。
- secondary namenode
secondary namenode詢問 namenode 是否需要 checkpoint。直接帶回 namenode 是否檢查結果平委。
secondary namenode 請求執(zhí)行 checkpoint奈虾。
namenode 滾動正在寫的edits日志。
將滾動前的編輯日志和鏡像文件拷貝到 secondary namenode廉赔。
secondary namenode 加載編輯日志和鏡像文件到內(nèi)存,并合并匾鸥。
生成新的鏡像文件 fsimage.chkpoint蜡塌。
拷貝 fsimage.chkpoint 到 namenode。
namenode將 fsimage.chkpoint 重新命名成fsimage勿负。
9.2 FSImage與edits詳解
所有的元數(shù)據(jù)信息都保存在了FsImage與Eidts文件當中馏艾,這兩個文件就記錄了所有的數(shù)據(jù)的元數(shù)據(jù)信息劳曹,元數(shù)據(jù)信息的保存目錄配置在了 hdfs-site.xml 當中
<!--fsimage文件存儲的路徑-->
<property>
<name>dfs.namenode.name.dir</name>
<value>file:///opt/hadoop-2.6.0-cdh5.14.0/hadoopDatas/namenodeDatas</value>
</property>
<!-- edits文件存儲的路徑 -->
<property>
<name>dfs.namenode.edits.dir</name>
<value>file:///opt/hadoop-2.6.0-cdh5.14.0/hadoopDatas/dfs/nn/edits</value>
</property>
客戶端對hdfs進行寫文件時會首先被記錄在edits文件中。
edits修改時元數(shù)據(jù)也會更新琅摩。
每次hdfs更新時edits先更新后客戶端才會看到最新信息铁孵。
fsimage:是namenode中關于元數(shù)據(jù)的鏡像,一般稱為檢查點房资。
一般開始時對namenode的操作都放在edits中蜕劝,為什么不放在fsimage中呢?
因為fsimage是namenode的完整的鏡像轰异,內(nèi)容很大岖沛,如果每次都加載到內(nèi)存的話生成樹狀拓撲結構,這是非常耗內(nèi)存和CPU搭独。
fsimage內(nèi)容包含了namenode管理下的所有datanode中文件及文件block及block所在的datanode的元數(shù)據(jù)信息婴削。隨著edits內(nèi)容增大,就需要在一定時間點和fsimage合并牙肝。
9.3 FSimage文件當中的文件信息查看
- 使用命令 hdfs oiv
cd /opt/hadoop-2.6.0-cdh5.14.0/hadoopDatas/namenodeDatas/current
hdfs oiv -i fsimage_0000000000000000112 -p XML -o hello.xml
9.4 edits當中的文件信息查看
- 查看命令 hdfs oev
cd /opt/hadoop-2.6.0-cdh5.14.0/hadoopDatas/dfs/nn/edits
hdfs oev -i edits_0000000000000000112-0000000000000000113 -o myedit.xml -p XML
9.5 secondarynameNode如何輔助管理FSImage與Edits文件
secnonaryNN通知NameNode切換editlog唉俗。
secondaryNN從NameNode中獲得FSImage和editlog(通過http方式)。
secondaryNN將FSImage載入內(nèi)存配椭,然后開始合并editlog虫溜,合并之后成為新的fsimage。
secondaryNN將新的fsimage發(fā)回給NameNode颂郎。
NameNode用新的fsimage替換舊的fsimage吼渡。
完成合并的是 secondarynamenode,會請求namenode停止使用edits乓序,暫時將新寫操作放入一個新的文件中(edits.new)寺酪。
secondarynamenode從namenode中通過http get獲得edits,因為要和fsimage合并替劈,所以也是通過http get 的方式把fsimage加載到內(nèi)存寄雀,然后逐一執(zhí)行具體對文件系統(tǒng)的操作,與fsimage合并陨献,生成新的fsimage盒犹,然后把fsimage發(fā)送給namenode,通過http post的方式眨业。
namenode從secondarynamenode獲得了fsimage后會把原有的fsimage替換為新的fsimage急膀,把edits.new變成edits。同時會更新fsimage龄捡。
hadoop進入安全模式時需要管理員使用dfsadmin的save namespace來創(chuàng)建新的檢查點卓嫂。
secondarynamenode在合并edits和fsimage時需要消耗的內(nèi)存和namenode差不多,所以一般把namenode和secondarynamenode放在不同的機器上聘殖。
fsimage與edits的合并時機取決于兩個參數(shù)晨雳,第一個參數(shù)是默認1小時fsimage與edits合并一次行瑞。
- 第一個參數(shù):時間達到一個小時fsimage與edits就會進行合并
dfs.namenode.checkpoint.period 3600
- 第二個參數(shù):hdfs操作達到1000000次也會進行合并
dfs.namenode.checkpoint.txns 1000000
- 第三個參數(shù):每隔多長時間檢查一次hdfs的操作次數(shù)
dfs.namenode.checkpoint.check.period 60
9.6 namenode元數(shù)據(jù)信息多目錄配置
為了保證元數(shù)據(jù)的安全性,我們一般都是先確定好我們的磁盤掛載目錄餐禁,將元數(shù)據(jù)的磁盤做RAID1
namenode的本地目錄可以配置成多個血久,且每個目錄存放內(nèi)容相同,增加了可靠性帮非。
-
具體配置方案:
hdfs-site.xml
<property>
<name>dfs.namenode.name.dir</name>
<value>file:///export/servers/hadoop-2.6.0-cdh5.14.0/hadoopDatas/namenodeDatas</value>
</property>
9.7 namenode故障恢復
在我們的secondaryNamenode對namenode當中的fsimage和edits進行合并的時候氧吐,每次都會先將namenode的fsimage與edits文件拷貝一份過來,所以fsimage與edits文件在secondarNamendoe當中也會保存有一份喜鼓,如果namenode的fsimage與edits文件損壞郭毕,那么我們可以將secondaryNamenode當中的fsimage與edits拷貝過去給namenode繼續(xù)使用披粟,只不過有可能會丟失一部分數(shù)據(jù)久信。這里涉及到幾個配置選項
- namenode保存fsimage的配置路徑
<!-- namenode元數(shù)據(jù)存儲路徑罪塔,實際工作當中一般使用SSD固態(tài)硬盤,并使用多個固態(tài)硬盤隔開隅忿,冗余元數(shù)據(jù) -->
<property>
<name>dfs.namenode.name.dir</name>
<value>file:///export/servers/hadoop-2.6.0-cdh5.14.0/hadoopDatas/namenodeDatas</value>
</property>
- namenode保存edits文件的配置路徑
<property>
<name>dfs.namenode.edits.dir</name>
<value>file:///export/servers/hadoop-2.6.0-cdh5.14.0/hadoopDatas/dfs/nn/edits</value>
</property>
- secondaryNamenode保存fsimage文件的配置路徑
<property>
<name>dfs.namenode.checkpoint.dir</name>
<value>file:///export/servers/hadoop-2.6.0-cdh5.14.0/hadoopDatas/dfs/snn/name</value>
</property>
- secondaryNamenode保存edits文件的配置路徑
<property>
<name>dfs.namenode.checkpoint.edits.dir</name>
<value>file:///export/servers/hadoop-2.6.0-cdh5.14.0/hadoopDatas/dfs/nn/snn/edits</value>
</property>
接下來我們來模擬namenode的故障恢復功能
殺死namenode進程: 使用jps查看namenode的進程號 , kill -9 直接殺死心剥。
刪除namenode的fsimage文件和edits文件。
根據(jù)上述配置, 找到namenode放置fsimage和edits路徑. 直接全部rm -rf 刪除背桐。
- 拷貝secondaryNamenode的fsimage與edits文件到namenode的fsimage與edits文件夾下面去优烧。
根據(jù)上述配置, 找到secondaryNamenode的fsimage和edits路徑, 將內(nèi)容 使用cp -r 全部復制到namenode對應的目錄下即可。
- 重新啟動namenode, 觀察數(shù)據(jù)是否存在链峭。
10 datanode工作機制以及數(shù)據(jù)存儲
- datanode工作機制
一個數(shù)據(jù)塊在datanode上以文件形式存儲在磁盤上畦娄,包括兩個文件,一個是數(shù)據(jù)本身弊仪,一個是元數(shù)據(jù)包括數(shù)據(jù)塊的長度熙卡,塊數(shù)據(jù)的校驗和,以及時間戳励饵。
DataNode啟動后向namenode注冊驳癌,通過后,周期性(1小時)的向namenode上報所有的塊信息役听。(dfs.blockreport.intervalMsec)颓鲜。
心跳是每3秒一次,心跳返回結果帶有namenode給該datanode的命令如復制塊數(shù)據(jù)到另一臺機器典予,或刪除某個數(shù)據(jù)塊甜滨。如果超過10分鐘沒有收到某個datanode的心跳,則認為該節(jié)點不可用瘤袖。
集群運行中可以安全加入和退出一些機器艳吠。
- 數(shù)據(jù)完整性
當DataNode讀取block的時候,它會計算checksum孽椰。
如果計算后的checksum昭娩,與block創(chuàng)建時值不一樣,說明block已經(jīng)損壞黍匾。
client讀取其他DataNode上的block栏渺。
datanode在其文件創(chuàng)建后周期驗證checksum。
- 掉線時限參數(shù)設置
datanode進程死亡或者網(wǎng)絡故障造成datanode無法與namenode通信锐涯,namenode不會立即把該節(jié)點判定為死亡磕诊,要經(jīng)過一段時間,這段時間暫稱作超時時長纹腌。HDFS默認的超時時長為10分鐘+30秒霎终。如果定義超時時間為timeout,則超時時長的計算公式為:
timeout = 2 * dfs.namenode.heartbeat.recheck-interval + 10 * dfs.heartbeat.interval升薯。
而默認的dfs.namenode.heartbeat.recheck-interval 大小為5分鐘莱褒,dfs.heartbeat.interval默認為3秒。
需要注意的是hdfs-site.xml 配置文件中的heartbeat.recheck.interval的單位為毫秒涎劈,dfs.heartbeat.interval的單位為秒广凸。
<property>
<name>dfs.namenode.heartbeat.recheck-interval</name>
<value>300000</value>
</property>
<property>
<name>dfs.heartbeat.interval </name>
<value>3</value>
</property>
-
DataNode的目錄結構
和namenode不同的是,datanode的存儲目錄是初始階段自動創(chuàng)建的蛛枚,不需要額外格式化谅海。
在/opt/hadoop-2.6.0-cdh5.14.0/hadoopDatas/datanodeDatas/current這個目錄下查看版本號
cat VERSION
#Thu Mar 14 07:58:46 CST 2019
storageID=DS-47bcc6d5-c9b7-4c88-9cc8-6154b8a2bf39
clusterID=CID-dac2e9fa-65d2-4963-a7b5-bb4d0280d3f4
cTime=0
datanodeUuid=c44514a0-9ed6-4642-b3a8-5af79f03d7a4
storageType=DATA_NODE
layoutVersion=-56
具體解釋:
storageID:存儲id號。
clusterID集群id蹦浦,全局唯一扭吁。
cTime屬性標記了datanode存儲系統(tǒng)的創(chuàng)建時間,對于剛剛格式化的存儲系統(tǒng)盲镶,這個屬性為0侥袜;但是在文件系統(tǒng)升級之后,該值會更新到新的時間戳徒河。
datanodeUuid:datanode的唯一識別碼系馆。
storageType:存儲類型。
layoutVersion是一個負整數(shù)顽照。通常只有HDFS增加新特性時才會更新這個版本號由蘑。
- datanode多目錄配置
datanode也可以配置成多個目錄,每個目錄存儲的數(shù)據(jù)不一樣代兵。即:數(shù)據(jù)不是副本尼酿。具體配置如下:
- 只需要在value中使用逗號分隔出多個存儲目錄即可
cd /opt/hadoop-2.6.0-cdh5.14.0/etc/hadoop
<!-- 定義dataNode數(shù)據(jù)存儲的節(jié)點位置,實際工作中植影,一般先確定磁盤的掛載目錄裳擎,然后多個目錄用,進行分割 -->
<property>
<name>dfs.datanode.data.dir</name>
<value>file:///opt/hadoop-2.6.0-cdh5.14.0/hadoopDatas/datanodeDatas</value>
</property>
10.1 服役新數(shù)據(jù)節(jié)點
需求說明:
隨著公司業(yè)務的增長思币,數(shù)據(jù)量越來越大鹿响,原有的數(shù)據(jù)節(jié)點的容量已經(jīng)不能滿足存儲數(shù)據(jù)的需求羡微,需要在原有集群基礎上動態(tài)添加新的數(shù)據(jù)節(jié)點。
10.1.1 環(huán)境準備
- 復制一臺新的虛擬機出來
將我們純凈的虛擬機復制一臺出來惶我,作為我們新的節(jié)點
- 修改mac地址以及IP地址
修改mac地址命令
vim /etc/udev/rules.d/70-persistent-net.rules
修改ip地址命令
vim /etc/sysconfig/network-scripts/ifcfg-eth0
- 關閉防火墻妈倔,關閉selinux
關閉防火墻
service iptables stop
關閉selinux
vim /etc/selinux/config
- 更改主機名
更改主機名命令,將node04主機名更改為node04.hadoop.com
vim /etc/sysconfig/network
- 四臺機器更改主機名與IP地址映射
四臺機器都要添加hosts文件
vim /etc/hosts
192.168.52.100 node01.hadoop.com node01
192.168.52.110 node02.hadoop.com node02
192.168.52.120 node03.hadoop.com node03
192.168.52.130 node04.hadoop.com node04
- node04服務器關機重啟
node04執(zhí)行以下命令關機重啟
reboot -h now
- node04安裝jdk
node04統(tǒng)一兩個路徑
mkdir -p /export/softwares/
mkdir -p /export/servers/
然后解壓jdk安裝包绸贡,配置環(huán)境變量
- 解壓hadoop安裝包
在node04服務器上面解壓hadoop安裝包到/export/servers , node01執(zhí)行以下命令將hadoop安裝包拷貝到node04服務器
cd /export/softwares/
scp hadoop-2.6.0-cdh5.14.0-自己編譯后的版本.tar.gz node04:$PWD
node04解壓安裝包
tar -zxf hadoop-2.6.0-cdh5.14.0-自己編譯后的版本.tar.gz -C /export/servers/
- 將node01關于hadoop的配置文件全部拷貝到node04
node01執(zhí)行以下命令盯蝴,將hadoop的配置文件全部拷貝到node04服務器上面
cd /export/servers/hadoop-2.6.0-cdh5.14.0/etc/hadoop/
scp ./* node04:$PWD
10.1.2 服役新節(jié)點具體步驟
- 創(chuàng)建dfs.hosts文件
在node01也就是namenode所在的機器的/export/servers/hadoop-2.6.0-cdh5.14.0/etc/hadoop目錄下創(chuàng)建dfs.hosts文件
[root@node01 hadoop]# cd /export/servers/hadoop-2.6.0-cdh5.14.0/etc/hadoop
[root@node01 hadoop]# touch dfs.hosts
[root@node01 hadoop]# vim dfs.hosts
添加如下主機名稱(包含新服役的節(jié)點)
node01
node02
node03
node04
- node01編輯hdfs-site.xml添加以下配置
在namenode的hdfs-site.xml配置文件中增加dfs.hosts屬性
node01執(zhí)行以下命令 :
cd /export/servers/hadoop-2.6.0-cdh5.14.0/etc/hadoop
vim hdfs-site.xml
# 添加一下內(nèi)容
<property>
<name>dfs.hosts</name>
<value>/export/servers/hadoop-2.6.0-cdh5.14.0/etc/hadoop/dfs.hosts</value>
</property>
<!--動態(tài)上下線配置: 如果配置文件中有, 就不需要配置-->
<property>
<name>dfs.hosts</name>
<value>/export/servers/hadoop-2.6.0-cdh5.14.0/etc/hadoop/accept_host</value>
</property>
<property>
<name>dfs.hosts.exclude</name>
<value>/export/servers/hadoop-2.6.0-cdh5.14.0/etc/hadoop/deny_host</value>
</property>
- 刷新namenode
- node01執(zhí)行以下命令刷新namenode
[root@node01 hadoop]# hdfs dfsadmin -refreshNodes
Refresh nodes successful
- 更新resourceManager節(jié)點
- node01執(zhí)行以下命令刷新resourceManager
[root@node01 hadoop]# yarn rmadmin -refreshNodes
19/03/16 11:19:47 INFO client.RMProxy: Connecting to ResourceManager at node01/192.168.52.100:8033
- namenode的slaves文件增加新服務節(jié)點主機名稱
node01編輯slaves文件,并添加新增節(jié)點的主機听怕,更改完后捧挺,slaves文件不需要分發(fā)到其他機器上面去
node01執(zhí)行以下命令編輯slaves文件 :
cd /export/servers/hadoop-2.6.0-cdh5.14.0/etc/hadoop
vim slaves
添加一下內(nèi)容:
node01
node02
node03
node04
- 單獨啟動新增節(jié)點
node04服務器執(zhí)行以下命令,啟動datanode和nodemanager :
cd /export/servers/hadoop-2.6.0-cdh5.14.0/
sbin/hadoop-daemon.sh start datanode
sbin/yarn-daemon.sh start nodemanager
- 使用負載均衡命令尿瞭,讓數(shù)據(jù)均勻負載所有機器
node01執(zhí)行以下命令 :
cd /export/servers/hadoop-2.6.0-cdh5.14.0/
sbin/start-balancer.sh
10.2 退役舊數(shù)據(jù)
- 創(chuàng)建dfs.hosts.exclude配置文件
在namenod所在服務器的/export/servers/hadoop-2.6.0-cdh5.14.0/etc/hadoop目錄下創(chuàng)建dfs.hosts.exclude文件闽烙,并添加需要退役的主機名稱
node01執(zhí)行以下命令 :
cd /export/servers/hadoop-2.6.0-cdh5.14.0/etc/hadoop
touch dfs.hosts.exclude
vim dfs.hosts.exclude
添加以下內(nèi)容:
node04.hadoop.com
特別注意:該文件當中一定要寫真正的主機名或者ip地址都行,不能寫node04
- 編輯namenode所在機器的hdfs-site.xml
編輯namenode所在的機器的hdfs-site.xml配置文件筷厘,添加以下配置
cd /export/servers/hadoop-2.6.0-cdh5.14.0/etc/hadoop
vim hdfs-site.xml
#添加一下內(nèi)容:
<property>
<name>dfs.hosts.exclude</name>
<value>/export/servers/hadoop-2.6.0-cdh5.14.0/etc/hadoop/dfs.hosts.exclude</value>
</property>
- 刷新namenode鸣峭,刷新resourceManager
在namenode所在的機器執(zhí)行以下命令,刷新namenode酥艳,刷新resourceManager :
hdfs dfsadmin -refreshNodes
yarn rmadmin -refreshNodes
- 節(jié)點退役完成摊溶,停止該節(jié)點進程
等待退役節(jié)點狀態(tài)為decommissioned(所有塊已經(jīng)復制完成),停止該節(jié)點及節(jié)點資源管理器充石。注意:如果副本數(shù)是3莫换,服役的節(jié)點小于等于3,是不能退役成功的骤铃,需要修改副本數(shù)后才能退役拉岁。
node04執(zhí)行以下命令,停止該節(jié)點進程 :
cd /export/servers/hadoop-2.6.0-cdh5.14.0
sbin/hadoop-daemon.sh stop datanode
sbin/yarn-daemon.sh stop nodemanager
- 從include文件中刪除退役節(jié)點
namenode所在節(jié)點也就是node01執(zhí)行以下命令刪除退役節(jié)點 :
cd /export/servers/hadoop-2.6.0-cdh5.14.0/etc/hadoop
vim dfs.hosts
刪除后的內(nèi)容: 刪除了node04
node01
node02
node03
- node01執(zhí)行一下命令刷新namenode惰爬,刷新resourceManager
hdfs dfsadmin -refreshNodes
yarn rmadmin -refreshNodes
- 從namenode的slave文件中刪除退役節(jié)點
namenode所在機器也就是node01執(zhí)行以下命令從slaves文件中刪除退役節(jié)點 :
cd /export/servers/hadoop-2.6.0-cdh5.14.0/etc/hadoop
vim slaves
刪除后的內(nèi)容: 刪除了 node04
node01
node02
node03
- 如果數(shù)據(jù)負載不均衡喊暖,執(zhí)行以下命令進行均衡負載
node01執(zhí)行以下命令進行均衡負載
cd /export/servers/hadoop-2.6.0-cdh5.14.0/
sbin/start-balancer.sh
11 block塊手動拼接成為完整數(shù)據(jù)
所有的數(shù)據(jù)都是以一個個的block塊存儲的,只要我們能夠將文件的所有block塊全部找出來撕瞧,拼接到一起陵叽,又會成為一個完整的文件,接下來我們就來通過命令將文件進行拼接:
- 上傳一個大于128M的文件到hdfs上面去
我們選擇一個大于128M的文件上傳到hdfs上面去丛版,只有一個大于128M的文件才會有多個block塊巩掺。
這里我們選擇將我們的jdk安裝包上傳到hdfs上面去。
node01執(zhí)行以下命令上傳jdk安裝包
cd /export/softwares/
hdfs dfs -put jdk-8u141-linux-x64.tar.gz /
- web瀏覽器界面查看jdk的兩個block塊id
這里我們看到兩個block塊id分別為
1073742699和1073742700
那么我們就可以通過blockid將我們兩個block塊進行手動拼接了页畦。
- 根據(jù)我們的配置文件找到block塊所在的路徑
根據(jù)我們hdfs-site.xml的配置胖替,找到datanode所在的路徑
<!-- 定義dataNode數(shù)據(jù)存儲的節(jié)點位置,實際工作中,一般先確定磁盤的掛載目錄独令,然后多個目錄用端朵,進行分割 -->
<property>
<name>dfs.datanode.data.dir</name>
<value>file:///export/servers/hadoop-2.6.0-cdh5.14.0/hadoopDatas/datanodeDatas</value>
</property>
進入到以下路徑 : 此基礎路徑為 上述配置中value的路徑
cd /export/servers/hadoop-2.6.0-cdh5.14.0/hadoopDatas/datanodeDatas/current/BP-557466926-192.168.52.100-1549868683602/current/finalized/subdir0/subdir3
- 4. 執(zhí)行block塊的拼接
將不同的各個block塊按照順序進行拼接起來,成為一個完整的文件
cat blk_1073742699 >> jdk8u141.tar.gz
cat blk_1073742700 >> jdk8u141.tar.gz
移動我們的jdk到/export路徑记焊,然后進行解壓
mv jdk8u141.tar.gz /export/
cd /export/
tar -zxf jdk8u141.tar.gz
正常解壓逸月,沒有問題,說明我們的程序按照block塊存儲沒有問題