機架和刀片機
塊 副本數
塊的理解
- 存儲處理數據的最小單元,其中在hadoop1.x中默認大小爲64M,hadoop2.0默認大小爲128M,塊的大小是由hdfs-site.xml文件中的dfs.blocksize 屬性控制
key | value |
---|---|
dfs.blocksize | 134217728 |
- 塊大小爲什麼要設置成128M?(參考其他人的博客)
是爲了最小化尋址時間,目前磁盤的傳輸速率普遍是在100M/S左右,所以設計成128M每塊
副本數的理解
副本數的設置使hdfs具有高可靠,數據不會丟失,一個dn只能存儲一個塊的一份副本,僞分佈式部署只能爲1個副本,因爲只有一個dn;集羣部署一般情況下設置3個副本即可,配置在hdfs-site.xml文件中
key | value |
---|---|
dfs.replication | 3 |
-
面試題
一個文件160M,塊大小128M ,副本數2份,請問:實際存儲多少塊,實際多少存儲空間?
回答之前有兩個概念需要搞清楚:
a.數據上傳到hdfs上,大小不會憑空增加
b.未滿一個block塊的大小,也會佔用一個block文件160/128=1...32 因爲副本數爲2,所以存儲4塊,空間佔160*2=320M
HDFS架構
Namenode
概念和作用
namenode是hdfs的主節點,也是元數據節點,1.整個文件系統的文件目錄樹,2.文件/目錄的元信息和每個文件對應的數據塊列表;這些信息以兩個文件永久存儲在磁盤上,一個是鏡像文件fsimage,另一個是 編輯日誌文件editlog
文件系統的命名空間構成
a.文件的名稱
b.文件的屬性 權限 創建時間 副本數
c.文件的目錄結構
d.文件對應切割爲那些的block塊和副本數==》數據分佈在那些dn節點,當然nn不會持久化存儲着寫映射關係,是通過集羣啓動和運行時,dn定期向nn發送blockreport,nn在內存中維護這種關係
nn數據存儲路徑和內容
[root@JD current]# pwd
/tmp/hadoop-hadoop/dfs/name/current
[root@JD current]# ll
-rw-rw-r-- 1 hadoop hadoop 42 Dec 2 17:39 edits_0000000000000000328-0000000000000000329
-rw-rw-r-- 1 hadoop hadoop 1048576 Dec 2 17:39 edits_inprogress_0000000000000000330
-rw-rw-r-- 1 hadoop hadoop 1744 Dec 2 16:39 fsimage_0000000000000000327
-rw-rw-r-- 1 hadoop hadoop 62 Dec 2 16:39 fsimage_0000000000000000327.md5
-rw-rw-r-- 1 hadoop hadoop 1744 Dec 2 17:39 fsimage_0000000000000000329
-rw-rw-r-- 1 hadoop hadoop 62 Dec 2 17:39 fsimage_0000000000000000329.md5
-rw-rw-r-- 1 hadoop hadoop 4 Dec 2 17:39 seen_txid
-rw-rw-r-- 1 hadoop hadoop 202 Nov 28 17:55 VERSION
NN的fsimage的個數默認是保留2個
是在hdfs-site文件進行配置,屬性爲
key | value |
---|---|
dfs.namenode.num.checkpoints.retained | 2 |
NN的editlog文件不會保留所有的,如生產上的文件第一個edit文件就沒了
edits文件(編輯日誌)
文件名前綴:edits
文件名後綴:該文件存儲的事務ID
文件系統客戶端執行寫操作時,這些事務首先會記錄到edits日誌中
fsimage(鏡像文件)
每個fsimage文件存儲的都是文件系統元數據信息(文件及目錄結構 組成文件的塊的信息 副本數量信息),如果namenode發生故障,最近的fsimage文件會被載入到內存中,用來重構元數據的最近狀態,再從相關點開始向前執行edits日誌文件中記錄的每個事務
數據塊Block存儲在datanode中,但是fsimage文件中並不描述block和datanode的映射關係,取而代之的是,namenode將這種映射關係存儲在內存中,這種映射關係通過datanode向namenode發送最新的塊列表信息,使namenode在內存中生成這種映射關係。
安全模式
NameNode啓動過的時候,會先將fsimage文件中的元數據加載到內存中,並執行編輯日誌中的各項操作。一旦在內存中建立文件系統元數據的映像,則創建一個新的fsimage文件和一個空的edits文件,在這個過程中namenode運行在安全模式下。
系統中數據塊的位置並不是由namenode維護的,而是以塊列表的形勢存儲在datanode中,在安全模式中,datanode會向namenode發送最新的塊列表信息,namenode在內存中建立一塊和datanode的映射關係, namenode瞭解到足夠多的塊位置信息之後,namenode會對外提供服務。
fsimage和edits合併實現原理 爲什麼要合併?
在NameNode運行期間,客戶端對HDFS的寫操作都保存到edits文件中,久而久之edits文件會變得很大,雖然這對NameNode運行的時候是沒有影響的,但是在NameNode重啓的時候,NameNode先將fsimage中的內容映射到內存中,然後再一條一條執行edits編輯日誌中的操作當edits文件非常大的時候會導致namenode啓動的時間非常漫長,而在這段時間中HDFS處於安全模式,所以需要在Namenode運行的時候將edits和fsimage定時進行合併,減小edits文件的大小。
NN收到DN發送來的block report之後,是如何進行處理的
除了heartbeat,block report應該說是HDFS中另一個最重要的RPC。DataNode通過block report告訴NameNode,它都有哪些block,然後NameNode根據block report來確定一個DataNode上哪些block是無效的,哪些應該被刪除,以及哪個block應該被replicate到其他的機器上,以及如何進行replicate。我們會介紹NameNode收到DataNode發送來的block report之後,是如何進行處理的,這一個過程。
- DataNode報告的block在NameNode中找不到,那麼,這個block自然就是無效的。可能是DataNode中的這個block已經被更新的block給替代掉了。因爲一個有效的block無論何時,在NameNode中都應該能找到。
- NameNode中存在DataNode中不存在的block。直接在NameNode的元數據中刪除就好了
- DataNode報告的block的元數據,和NameNode中的不符,比如,block的長度不同,或者時間戳不對,就要先告訴DataNode把舊的block刪除掉,然後告訴其他的DataNode把最新的block replicate到對應的DataNode上
- DataNode報告的block處於UNDER CONSTRUCTION狀態,那麼就把它加到NameNode中維護的關於block的under construction的replicas的列表中
- 如果DataNode報告的block能在NameNode中找到並且這個block是處於FINALIZED狀態,那麼就把它添加到NameNode維護的關於block的已經完成的replicas的列表中
總結
NameNode維護着2張表:
1.文件系統的目錄結構,以及元數據信息
2.文件與數據塊(block)列表的對應關係
元數據存放在fsimage中,在運行的時候加載到內存中的(讀寫比較快)。
操作日誌寫到edits中。(類似於LSM樹中的log)
Datanode
-
概念和作用
datanode是hdfs的從節點,也稱爲數據節點,主要存儲數據塊和數據塊校驗和(.meta文件,主要是校驗文件是否損壞) -
dn文件存儲路徑
[root@JD subdir0]# pwd /tmp/hadoop-hadoop/dfs/data/current/BP-497769727-192.168.0.3-1574934933514/current/finalized/subdir0/subdir0 [root@JD subdir0]# ll -rw-rw-r-- 1 hadoop hadoop 33K Dec 1 17:24 blk_1073741838 #數據塊 -rw-rw-r-- 1 hadoop hadoop 271 Dec 1 17:24 blk_1073741838_1014.meta #數據塊校驗和 -rw-rw-r-- 1 hadoop hadoop 138K Dec 1 17:24 blk_1073741839 -rw-rw-r-- 1 hadoop hadoop 1.1K Dec 1 17:24 blk_1073741839_1015.meta
-
dn的心跳和報告
a. dn每隔3s向nn發送心跳,告訴nn我還健康,是在配置文件hdfs-site.xml文件中匹配值,屬性和值爲
key | value |
---|---|
dfs.heartbeat.interval | 3 |
b. dn每隔6h掃描塊,並向nn發送blockreport,生產上根據數據量大小,建議配置3小時即可,在配置文件hdfs-site.xml文件中匹配值,其中dfs.datanode.directoryscan.interval表示掃描塊的屬性 21600s=6h,dfs.blockreport.intervalMsec表示blockreport的屬性 21600000ms=6h屬性和值爲
key | value |
---|---|
dfs.blockreport.intervalMsec | 21600000 |
dfs.datanode.directoryscan.interval | 21600 |
SecondaryNamenode
- 概念
snn也稱爲元數據節點,是hdfs中的備用節點,主要作用是合併fsimage和editlog作爲一個新的fsimage,並推送到nn,該過程也稱爲checkpoint - 配置合併的參數
在hdfs-site.xml中,有兩個參數可以控制文件合併是由時間還是次數決定,其中這兩個參數的默認值爲1小時或者Editlog操作日誌記錄滿 1000000條,兩者滿足一條就會合並文件
key | value |
---|---|
dfs.namenode.checkpoint.period | 3600 |
dfs.namenode.checkpoint.txns | 1000000 |
- snn的缺點
雖然snn能解決單點故障,但是還是會有風險的,因爲如圖所示,還有40分鐘的數據是恢復不了的
nn和snn交互的流程
NN
edits_0000000000000000306-0000000000000000307
edits_0000000000000000308-0000000000000000324
edits_inprogress_0000000000000000325
fsimage_0000000000000000307
fsimage_0000000000000000307.md5
fsimage_0000000000000000324
fsimage_0000000000000000324.md5
SNN
edits_0000000000000000302-0000000000000000303
edits_0000000000000000304-0000000000000000305
edits_0000000000000000306-0000000000000000307
edits_0000000000000000308-0000000000000000324
fsimage_0000000000000000307
fsimage_0000000000000000307.md5
fsimage_0000000000000000324
fsimage_0000000000000000324.md5
fsimage_0000000000000000307 + edits_0000000000000000308-0000000000000000324
==>fsimage_0000000000000000324
a. fsimage和edits文件合併時,在nn生成一份新的edit.new文件
b. 複製fsimage和edits文件到snn,在snn進行合併,生成fsimage.ckpt
c.snn將fsimage.ckpt文件推送到nn,然後將fsimage.ckpt替換爲fsimage文件,同時將edits.new文件替換爲edits文件
手動自動修復損壞的文件
-
hadoop中有個命令是可以手動修復損壞的塊,前提是多副本的情況下
[hadoop@JD hadoop]$ hdfs debug Usage: hdfs debug <command> [arguments] These commands are for advanced users only. Incorrect usages may result in data loss. Use at your own risk. verifyMeta -meta <metadata-file> [-block <block-file>] computeMeta -block <block-file> -out <output-metadata-file> recoverLease -path <path> [-retries <num-retries>] 執行手動修復指定塊命令(xxx指的是有問題的文件在hdfs的路徑) [hadoop@JD hadoop]$ hdfs debug recoverLease -path xxx -retries 10
小文件的理解
定義:明顯小於block size的文件 80%
危害:
1)磁盤IO
2)task啓動銷燬的開銷
3)資源有限
hdfs適合存儲小文件嗎
不適合
假如不適合是爲什麼
因爲hdfs的一個block塊的大小是128M,雖然傳上的文件小,但是也會佔用一個block文件,如果存儲上千萬、上億個小文件,Namenode需要維護的源數據信息越多,nn的壓力會很大,也有可能撐爆nn的大小(生產上配置的4G)
假如上傳文件都是小文件 比如 3m 5m 6m 10m四個文件怎麼辦
有兩種解決方式,第一種是在上傳之前進行文件的合併,第二種是在hdfs中進行文件的合併
假如已經在hdfs上 真的有小文件,該怎麼辦?合併 啓動一個服務 單獨合併目標 是爲了小文件合併大文件,約定的:儘量合併的大文件 <=128M blocksize 比如控制 110M
改變hdfs的存儲目錄
hdfs的存儲目錄是在/tmp目錄下的,但是linux有30天清理不在規則內的未訪問的文件,所以爲了防止文件被誤刪,我們將存儲目錄放到/home/hadoop/tmp目錄下
切換爲hadoop用戶
[root@JD ~]# su - hadoop
Last login: Mon Dec 2 21:11:59 CST 2019 on pts/1
[hadoop@JD ~]$ pwd
/home/hadoop
賦權限
[hadoop@JD ~]$ chmod -R 777 /home/hadoop/tmp
移動之前已生成的文件到新目錄下
[hadoop@JD ~]$ mv /tmp/hadoop-hadoop/dfs/ /home/hadoop/tmp
修改配置文件core-site.xml
[hadoop@JD ~]$ cd app/hadoop/etc/hadoop
[hadoop@JD hadoop]$ vi core-site.xml
<property>
<name>hadoop.tmp.dir</name>
<value>/home/hadoop/tmp</value>
</property>
重啓hdfs
上傳文件測試是否存在於新配置的目錄裏
進入dn目錄
[hadoop@JD subdir0]$ pwd
/home/hadoop/tmp/dfs/data/current/BP-497769727-192.168.0.3-1574934933514/current/finalized/subdir0/subdir0
查看文件
[hadoop@JD subdir0]$ ll
total 216
-rw-rw-r-- 1 hadoop hadoop 7 Nov 28 22:26 blk_1073741826
-rw-rw-r-- 1 hadoop hadoop 11 Nov 28 22:26 blk_1073741826_1002.meta
-rw-rw-r-- 1 hadoop hadoop 29 Dec 1 17:14 blk_1073741827
-rw-rw-r-- 1 hadoop hadoop 11 Dec 1 17:14 blk_1073741827_1003.meta
-rw-rw-r-- 1 hadoop hadoop 30 Dec 1 17:24 blk_1073741836
-rw-rw-r-- 1 hadoop hadoop 11 Dec 1 17:24 blk_1073741836_1012.meta
-rw-rw-r-- 1 hadoop hadoop 349 Dec 1 17:24 blk_1073741837
-rw-rw-r-- 1 hadoop hadoop 11 Dec 1 17:24 blk_1073741837_1013.meta
-rw-rw-r-- 1 hadoop hadoop 33508 Dec 1 17:24 blk_1073741838
-rw-rw-r-- 1 hadoop hadoop 271 Dec 1 17:24 blk_1073741838_1014.meta
-rw-rw-r-- 1 hadoop hadoop 141014 Dec 1 17:24 blk_1073741839
-rw-rw-r-- 1 hadoop hadoop 1111 Dec 1 17:24 blk_1073741839_1015.meta
執行上傳
[hadoop@JD subdir0]$ hadoop fs -put /home/hadoop/bbb.txt /
19/12/02 22:50:44 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
再次查看發現有我們剛纔上傳的文件,成功
[hadoop@JD subdir0]$ ll
total 224
-rw-rw-r-- 1 hadoop hadoop 7 Nov 28 22:26 blk_1073741826
-rw-rw-r-- 1 hadoop hadoop 11 Nov 28 22:26 blk_1073741826_1002.meta
-rw-rw-r-- 1 hadoop hadoop 29 Dec 1 17:14 blk_1073741827
-rw-rw-r-- 1 hadoop hadoop 11 Dec 1 17:14 blk_1073741827_1003.meta
-rw-rw-r-- 1 hadoop hadoop 30 Dec 1 17:24 blk_1073741836
-rw-rw-r-- 1 hadoop hadoop 11 Dec 1 17:24 blk_1073741836_1012.meta
-rw-rw-r-- 1 hadoop hadoop 349 Dec 1 17:24 blk_1073741837
-rw-rw-r-- 1 hadoop hadoop 11 Dec 1 17:24 blk_1073741837_1013.meta
-rw-rw-r-- 1 hadoop hadoop 33508 Dec 1 17:24 blk_1073741838
-rw-rw-r-- 1 hadoop hadoop 271 Dec 1 17:24 blk_1073741838_1014.meta
-rw-rw-r-- 1 hadoop hadoop 141014 Dec 1 17:24 blk_1073741839
-rw-rw-r-- 1 hadoop hadoop 1111 Dec 1 17:24 blk_1073741839_1015.meta
-rw-rw-r-- 1 hadoop hadoop 7 Dec 2 22:50 blk_1073741840
-rw-rw-r-- 1 hadoop hadoop 11 Dec 2 22:50 blk_1073741840_1016.meta