1. 概述
HDFS集群分為兩大角色:NameNode、DataNode(Secondary NameNode)
NameNode負(fù)責(zé)管理整個(gè)文件系統(tǒng)的元數(shù)據(jù)死陆,記錄存放在哪些datanode中待牵,以及存放路徑
dataNode 負(fù)責(zé)管理用戶的文件數(shù)據(jù)塊
文件會(huì)按照固定大衅淦痢(blocksize)來切分成塊后分布式存儲(chǔ)在若干臺(tái)datanode上
每一個(gè)文件快可以有多個(gè)副本,并存放在不同的datanode上
datanode 會(huì)定期向namenode匯報(bào)自身所保存的文件block信息缨该,而namenode則會(huì)負(fù)責(zé)保持文件的副本數(shù)量(當(dāng)減少datanode的時(shí)候偎行,namenode才知道當(dāng)前副本狀態(tài),從而進(jìn)行副本維持)
HDFS的內(nèi)部工作機(jī)制對(duì)客戶端保持透明贰拿,客戶端請(qǐng)求訪問HDFS都是通過向namenode申請(qǐng)來進(jìn)行
2. 寫數(shù)據(jù)流程
比較簡單蛤袒,看圖即懂
3. 讀數(shù)據(jù)流程
比較簡單,看圖即懂
4. nameNode膨更、secondNameNode管理元數(shù)據(jù)機(jī)制
4.1 機(jī)制
每次更新元數(shù)據(jù)妙真,namenode都需要記錄下來這些更新信息,方便之后查詢更新過的元數(shù)據(jù)询一。
假如每次記錄在磁盤上隐孽,幾千萬上億條元數(shù)據(jù)寫入速度會(huì)非常慢,導(dǎo)致磁盤IO使用率過高健蕊,效率低菱阵;讀數(shù)據(jù)的時(shí)候再上億條數(shù)據(jù)里面搜索,查詢的效率也非常低缩功。
因此需要將更新記錄放在內(nèi)存中(new一個(gè)元數(shù)據(jù)對(duì)象)晴及,如果僅僅使用內(nèi)存,億級(jí)的數(shù)據(jù)又會(huì)使nameNode死機(jī)或者意外斷電嫡锌,那么內(nèi)存中的記錄全部丟失虑稼。
所以需要把內(nèi)存中的億級(jí)元數(shù)據(jù)定時(shí)寫入fsimage中。由于一條元數(shù)據(jù)平均大小為150Bytes势木,定時(shí)時(shí)間太長的話中途斷電就丟失了蛛倦,定時(shí)時(shí)間太短又會(huì)導(dǎo)致磁盤IO占用過高的問題。
這樣啦桌,secondNameNode就引入了溯壶,用于fsimage鏡像同步管理及皂。
1. 用戶更新元數(shù)據(jù)時(shí),將更新記錄寫入namenode內(nèi)存
2. 在第1步的同時(shí)且改,在namenode中验烧,只將內(nèi)存中更新的記錄追加到日志文件(edits文件)中,這樣又跛,即便是斷電了碍拆,nameNode也能根據(jù)edits操作日志就能恢復(fù)元數(shù)據(jù)的記錄信息。
但是這樣又會(huì)引入一個(gè)問題慨蓝,edits文件變得越來越大感混,每次重啟的時(shí)候加載edits日志又會(huì)嚴(yán)重耗時(shí),影響nameNode啟動(dòng)速度菌仁。
這樣我們就需要一個(gè)元數(shù)據(jù)對(duì)象(在內(nèi)存中)的一個(gè)鏡像文件fsimage浩习,那么edits文件就不用記錄每條元數(shù)據(jù)的完整信息,只用記錄對(duì)單條元數(shù)據(jù)的操作記錄济丘,且定時(shí)將edits和fsimage鏡像文件合并。這樣斷電重啟時(shí)洽蛀,只需要將fsimage與edits中未同步的少量操作記錄計(jì)算合并后的元數(shù)據(jù)完整信息加載到內(nèi)存中摹迷。
但是定時(shí)合并edits和fsimage也是一個(gè)很耗費(fèi)資源的操作,且合并的同時(shí)郊供,查詢操作就無法保證效率和正確性峡碉,從而引入了secondNameNode,將耗費(fèi)資源的操作放到另一臺(tái)節(jié)點(diǎn)中驮审。
3. 為了在定時(shí)合并edits和fsimage鏡像時(shí)區(qū)分合并了和未合并的操作記錄鲫寄,這里需要拆分edits文件,未合并過的新操作記錄用edits_inprogress來區(qū)分疯淫,默認(rèn)1分鐘拆分一次地来。
合并在hadoop namenode中專業(yè)術(shù)語是checkpoint,由secondNameNode發(fā)起詢問namenode是否需要checkpoint熙掺,如果達(dá)到限值namenode回給secondNameNode可以checkpoint未斑,secondNameNode才發(fā)起checkpoint請(qǐng)求。
其實(shí)币绩,定時(shí)觸發(fā)合并edits_inprogress記錄和fsimage鏡像的說法并不嚴(yán)格蜡秽,實(shí)際上checkpiont觸發(fā)條件有2個(gè):a。secondNameNode定時(shí)觸發(fā)詢問namenode是否需要出發(fā)checkpoint(默認(rèn)是1小時(shí)一次)缆镣;b芽突。edits的size達(dá)到默認(rèn)值:64MB,namenode才同意觸發(fā)checkpoint董瞻。
當(dāng)secondNameNode請(qǐng)求觸發(fā)checkpoint時(shí)寞蚌,namenode需要將edits_inprogress_idx改名為edits_idx,且新建edits_inprogress_idx+1用來記錄新增的操作。這樣secondNameNode可以沒有顧慮的做edits_idx和fsimage的checkpoint
4. 第一次做checkpoint時(shí):secondNameNode將namenode的edits_idx和fsimage下載過來睬澡;之后再做checkpoint:secondNameNode只需要下載edits_idx+1固额,因?yàn)樯弦淮蔚膄simage.checkpoint就是當(dāng)先namenode的fsimage
5. 將下載過來的edits_idx和fsImage(fsimage.checkpoint)加載到內(nèi)存中進(jìn)行運(yùn)算
6. 將運(yùn)算的結(jié)果dump到文件(覆蓋)fsimage.checkpoint
7. secondNameNode將fsimage.checkpoint上傳到namenode中
8. namenode 將fsimage.checkpoint替換舊的fsimage
默認(rèn)edits文件1分鐘拆分一次,checkpoint詢問30分鐘一次
如果沒有新的edits記錄煞聪,則不會(huì)做checkpoint
當(dāng)達(dá)到億級(jí)數(shù)據(jù)時(shí)斗躏,一定要考慮內(nèi)存的大小,以阿里云目前服務(wù)器最大支持512G來看昔脯,每條元數(shù)據(jù)平均150bytes啄糙,能存儲(chǔ)36億條元數(shù)據(jù)。每個(gè)元數(shù)據(jù)是一個(gè)文件云稚,那么可以自行估算企業(yè)的實(shí)際情況隧饼。另外,元數(shù)據(jù)所指向的上傳的文件肯定是越大越好静陈,且不要頻繁改動(dòng)燕雁,適合存儲(chǔ)大文件(小文件要合并存放,例如每個(gè)小時(shí)的文件合并成一天的文件來存放到HDFS)鲸拥?
namenode如果死機(jī)拐格,secondNameNode不具備能夠替代的功能,因?yàn)閟econdNameNode只是用于做checkpoint的刑赶,所以一旦namenode死機(jī)捏浊,hadoop集群就不能運(yùn)作了。
4.2 集群功能優(yōu)化配置參數(shù)
4.2.1 dfs.namenode.name.dir
如果namenode的硬盤損壞撞叨,元數(shù)據(jù)是可以恢復(fù)絕大部分的(沒有做checkpoint的edits_inprogress數(shù)據(jù)不能恢復(fù))金踪,我們可以做個(gè)實(shí)驗(yàn)來驗(yàn)證:
1. #hadoop fs -ls /testdir
2. 立即刪除namenode的工作目錄 #rm -rf /kluter/hdpTmpDir/dfs/name, 這是,hadoop fs -ls /是可以正常工作的牵敷, 因?yàn)樵獢?shù)據(jù)信息還在namenode進(jìn)程中
3. kill namenode進(jìn)程胡岔,重啟namenode失敗,因?yàn)閱?dòng)時(shí)報(bào)錯(cuò):namenode工作目錄不存在了
4. 將secondNameNode的工作目錄cp到namenode的工作目錄劣领,重啟namenode成功姐军,但是發(fā)現(xiàn)第1步創(chuàng)建的testdir沒有恢復(fù)成功
5. 為了解決第4步的問題,我們?cè)陂_始搭建的時(shí)候就必須規(guī)劃好硬件資源尖淘,在namenode上奕锌,需要掛載至少2塊磁盤:即便一塊磁盤掛了,另一塊磁盤中還是有相同完整數(shù)據(jù)的村生。需要修改hdfs-site.xml配置:
<property>
????<name>dfs.namenode.name.dir</name>
????<value>/kluter/hdpTmpDir/dfs/name,/kluter/hdpTmpDir/dfs/nameBak</value>
</property>
4.2.2?dfs.datanode.data.dir
同理datanode可以通過hdfs-site.xml中的dfs.datanode.data.dir來配置多個(gè)工作目錄到相同主機(jī)的不同硬盤惊暴,但并不是block在相同主機(jī)不同磁盤的復(fù)制(因?yàn)閺?fù)制是在不同主機(jī)namenode之間)。
這個(gè)配置有2個(gè)作用:
? ? 1. 可以應(yīng)對(duì)多個(gè)hadoop客戶端同時(shí)傳文件到HDFS的情況趁桃,不同的客戶端將文件放在不同的磁盤辽话,使用不同磁盤的IO并發(fā)進(jìn)行肄鸽,以減輕一塊磁盤IO的壓力。
? ? 2. 可以達(dá)到不增加namenode的情況下進(jìn)行HDFS空間擴(kuò)容油啤,節(jié)約主機(jī)成本典徘,只有磁盤費(fèi)用的增加
4.2.3?dfs.namenode.secondary.http-address
這個(gè)參數(shù)是設(shè)置secondaryNameNode的節(jié)點(diǎn)IP和端口,默認(rèn)是和namenode在同一臺(tái)主機(jī)
<property>
????<name>dfs.namenode.secondary.http-address</name>
????<value>10.10.77.193:50090</value>
</property>
4.2.4?dfs.namenode.checkpoint.period
checkpoint超時(shí)時(shí)間,默認(rèn)值3600s=1小時(shí)益咬,做實(shí)驗(yàn)可以改成幾分鐘試試效果
4.2.5?dfs.namenode.checkpoint.dir
secondaryNameNode的工作目錄逮诲,當(dāng)snn和nn在同一臺(tái)時(shí)有效,如果不在同一臺(tái)主機(jī)幽告,nn會(huì)根據(jù)這個(gè)參數(shù)建立一個(gè)空的namesecondary目錄
4.3 其他
4.3.1?VERSION 文件
路徑:/kluter/hdpTmpDir/dfs/name/current/梅鹦, namenode、datanode路徑相同
# cat VERSION
#Fri Jun 22 14:10:26 CST 2018
namespaceID=126653939
clusterID=CID-530c66ce-ec4f-4bea-895f-6bdda27c48fa
cTime=1529647826935
storageType=NAME_NODE
blockpoolID=BP-590588951-10.10.77.194-1529647826935
layoutVersion=-63
1. namespaceID:文件系統(tǒng)的唯一標(biāo)識(shí)符冗锁,在文件系統(tǒng)首次格式化之后生成的齐唆;有多個(gè)集群的情況下,不同集群擁有不同的
2. storageType:說明這個(gè)文件系統(tǒng)存儲(chǔ)的是什么進(jìn)程的數(shù)據(jù)結(jié)構(gòu)信息
3. cTime表示nn存儲(chǔ)時(shí)間的創(chuàng)建時(shí)間冻河,如果nn更新升級(jí)箍邮,cTime將會(huì)記錄更新時(shí)間戳
4. layoutVersion表示HDFS永久性數(shù)據(jù)結(jié)構(gòu)的版本信息,只要數(shù)據(jù)結(jié)構(gòu)變更版本號(hào)也改變芋绸,此時(shí)HDFS也需要升級(jí)媒殉,否則磁盤仍舊是舊的版本數(shù)據(jù)結(jié)構(gòu),會(huì)導(dǎo)致新版本的nn無法使用
5. clusterID是系統(tǒng)生成或手動(dòng)指定的集群ID摔敛。當(dāng)有多個(gè)集群時(shí),需要格式化一個(gè)指定集群就需要填寫對(duì)應(yīng)的cluster_id
4.3.2 namenode的seen_txid文件
路徑:/kluter/hdpTmpDir/dfs/name/current全封,只有namenode才有
作用是重啟namenode時(shí)马昙,值會(huì)增加,用于namenode對(duì)edits_inprogress_idx進(jìn)行回滾刹悴,每次重啟namenode時(shí)行楞,nn就知道除了fsimage之外還需要將哪些edits文件進(jìn)行加載該值等于inprogress的index,加載完fsimage和edits_inprogress文件后滾動(dòng)新的edits_inprogress_idxNew
5. DataNode工作機(jī)制
1.
????存儲(chǔ)管理用戶的文件塊數(shù)據(jù)(block datas)
2.?
????定期向namenode匯報(bào)自身所持有的block信息(用于集群中某些block異常時(shí)土匀,namenode知道如何去恢復(fù)初始副本數(shù)量),默認(rèn)值21600000ms = 6hour子房,建議改成1小時(shí)=3600000
<property>
????<name>dfs.blockreport.intervalMsec</name>
????<value>3600000</value>
</property>
3. dataNode掉線timeout參數(shù)
如果dataNode因?yàn)楦鞣N原因死掉造成無法與namenode通信,namenode不會(huì)立即把該dn節(jié)點(diǎn)判定為掉線就轧,要經(jīng)過一段時(shí)限证杭,HDFS默認(rèn)timeout為10分鐘+30秒,超時(shí)公式:timeout=2*heartbeat.recheck.interval + 10*dfs.heartbeat.interval
heartbeat.recheck.interval默認(rèn)為300000ms=5分鐘妒御,heartbeat.interval默認(rèn)為3s?
假如手動(dòng)kill一個(gè)datanode解愤,也許你會(huì)覺得10分鐘+30s后namenode才認(rèn)定datanode掛掉是一個(gè)很長的時(shí)間(實(shí)驗(yàn):kill zookeeper2這臺(tái)datanode,在網(wǎng)頁上發(fā)現(xiàn)datanode2的狀態(tài)依然是active)乎莉,但實(shí)際上有可能datanode只是需要重啟一下送讲,這樣不用頻繁的在網(wǎng)絡(luò)內(nèi)部發(fā)送消息奸笤,也不需要namenode立即去別的節(jié)點(diǎn)上同步數(shù)據(jù)來保證數(shù)據(jù)的copy數(shù)量