Fsimage和Edits解析
相關(guān)概念
namenode被格式化之后撤逢,將在/opt/module/hadoop-2.8.3/data/tmp/dfs/name/current目錄中產(chǎn)生如下文件
- Fsimage文件:HDFS文件系統(tǒng)元數(shù)據(jù)的一個(gè)永久性的檢查點(diǎn)颜屠,其中包含HDFS文件系統(tǒng)的所有目錄和文件idnode的序列化信息晴氨。
- Edits文件:存放HDFS文件系統(tǒng)的所有更新操作的路徑,文件系統(tǒng)客戶端執(zhí)行的所有寫操作首先會(huì)被記錄到edits文件中。
- seen_txid文件保存的是一個(gè)數(shù)字巩割,就是最后一個(gè)edits_的數(shù)字
每次NameNode啟動(dòng)的時(shí)候都會(huì)將最新的fsimage文件讀入內(nèi)存裙顽,并合并edits里面的更新操作,保證內(nèi)存中的元數(shù)據(jù)信息是最新的宣谈、同步的愈犹,可以看成NameNode啟動(dòng)的時(shí)候就將fsimage和edits文件進(jìn)行了合并。
NameNode會(huì)把最新的fsimage后綴和seen_txid 之間的edits合并蒲祈。
使用OIV查看fsimage文件
hdfs oiv -p 文件類型 -i鏡像文件 -o 轉(zhuǎn)換后文件輸出路徑
hdfs oiv -p XML -i fsimage_0000000000000000294 -o fsimage.xml
文件內(nèi)容如下
<?xml version="1.0"?>
<fsimage>
<version>
<layoutVersion>-63</layoutVersion>
<onDiskVersion>1</onDiskVersion>
<oivRevision>b3fe56402d908019d99af1f1f4fc65cb1d1436a2</oivRevision>
</version>
<NameSection>
<namespaceId>1560614512</namespaceId>
<genstampV1>1000</genstampV1>
<genstampV2>1040</genstampV2>
<genstampV1Limit>0</genstampV1Limit>
<lastAllocatedBlockId>1073741862</lastAllocatedBlockId>
<txid>294</txid>
</NameSection>
<INodeSection>
<lastInodeId>16407</lastInodeId>
<numInodes>6</numInodes>
<inode>
<id>16385</id>
<type>DIRECTORY</type>
<name></name>
<mtime>1536189784686</mtime>
<permission>hadoop:supergroup:0755</permission>
<nsquota>9223372036854775807</nsquota>
<dsquota>-1</dsquota>
</inode>
<inode>
<id>16403</id>
<type>DIRECTORY</type>
<name>user</name>
<mtime>1536189784687</mtime>
<permission>hadoop:supergroup:0755</permission>
<nsquota>-1</nsquota>
<dsquota>-1</dsquota>
</inode>
<inode>
<id>16404</id>
<type>DIRECTORY</type>
<name>hadoop</name>
<mtime>1536190852299</mtime>
<permission>hadoop:supergroup:0755</permission>
<nsquota>-1</nsquota>
<dsquota>-1</dsquota>
</inode>
<inode>
<id>16405</id>
<type>FILE</type>
<name>client</name>
<replication>3</replication>
<mtime>1536189786438</mtime>
<atime>1536320623173</atime>
<preferredBlockSize>134217728</preferredBlockSize>
<permission>hadoop:supergroup:0644</permission>
<blocks>
<block>
<id>1073741858</id>
<genstamp>1036</genstamp>
<numBytes>36667596</numBytes>
</block>
</blocks>
<storagePolicyId>0</storagePolicyId>
</inode>
</INodeSection>
<INodeReferenceSection></INodeReferenceSection>
<SnapshotSection>
<snapshotCounter>0</snapshotCounter>
<numSnapshots>0</numSnapshots>
</SnapshotSection>
<INodeDirectorySection>
<directory>
<parent>16385</parent>
<child>16403</child>
</directory>
<directory>
<parent>16403</parent>
<child>16404</child>
</directory>
<directory>
<parent>16404</parent>
<child>16405</child>
<child>16406</child>
</directory>
<directory>
<parent>16406</parent>
<child>16407</child>
</directory>
</INodeDirectorySection>
<FileUnderConstructionSection></FileUnderConstructionSection>
<SecretManagerSection>
<currentId>0</currentId>
<tokenSequenceNumber>0</tokenSequenceNumber>
<numDelegationKeys>0</numDelegationKeys>
<numTokens>0</numTokens>
</SecretManagerSection>
<CacheManagerSection>
<nextDirectiveId>1</nextDirectiveId>
<numDirectives>0</numDirectives>
<numPools>0</numPools>
</CacheManagerSection>
</fsimage>
從上面的文件中可以看出甘萧,fsimage中并沒有記錄塊所對(duì)應(yīng)的datenode,這是因?yàn)闆]有必要在fsimage文件中記錄梆掸,在內(nèi)存中維護(hù)就可以了扬卷,datenode像namenode匯報(bào)。
oev查看edits文件
hdfs oev -p 文件類型 -i編輯日志 -o 轉(zhuǎn)換后文件輸出路徑
hdfs oev -p XML -i edits_inprogress_0000000000000000336 -o edits_inprogress_0000000000000000336.xml
內(nèi)容如下
<?xml version="1.0" encoding="UTF-8"?>
<EDITS>
<EDITS_VERSION>-63</EDITS_VERSION>
<RECORD>
<OPCODE>OP_START_LOG_SEGMENT</OPCODE>
<DATA>
<TXID>303</TXID>
</DATA>
</RECORD>
<RECORD>
<OPCODE>OP_MKDIR</OPCODE>
<DATA>
<TXID>304</TXID>
<LENGTH>0</LENGTH>
<INODEID>16408</INODEID>
<PATH>/user/hadoop/test</PATH>
<TIMESTAMP>1536562302682</TIMESTAMP>
<PERMISSION_STATUS>
<USERNAME>hadoop</USERNAME>
<GROUPNAME>supergroup</GROUPNAME>
<MODE>493</MODE>
</PERMISSION_STATUS>
</DATA>
</RECORD>
<RECORD>
<OPCODE>OP_ADD</OPCODE>
<DATA>
<TXID>305</TXID>
<LENGTH>0</LENGTH>
<INODEID>16409</INODEID>
<PATH>/user/hadoop/test/cpHello.txt._COPYING_</PATH>
<REPLICATION>3</REPLICATION>
<MTIME>1536562302831</MTIME>
<ATIME>1536562302831</ATIME>
<BLOCKSIZE>134217728</BLOCKSIZE>
<CLIENT_NAME>DFSClient_NONMAPREDUCE_1326850463_1</CLIENT_NAME>
<CLIENT_MACHINE>192.168.114.102</CLIENT_MACHINE>
<OVERWRITE>true</OVERWRITE>
<PERMISSION_STATUS>
<USERNAME>hadoop</USERNAME>
<GROUPNAME>supergroup</GROUPNAME>
<MODE>420</MODE>
</PERMISSION_STATUS>
<RPC_CLIENTID>424e8401-aa20-4dd2-83ae-cedd762158f0</RPC_CLIENTID>
<RPC_CALLID>7</RPC_CALLID>
</DATA>
</RECORD>
<RECORD>
<OPCODE>OP_ALLOCATE_BLOCK_ID</OPCODE>
<DATA>
<TXID>306</TXID>
<BLOCK_ID>1073741863</BLOCK_ID>
</DATA>
</RECORD>
<RECORD>
<OPCODE>OP_SET_GENSTAMP_V2</OPCODE>
<DATA>
<TXID>307</TXID>
<GENSTAMPV2>1041</GENSTAMPV2>
</DATA>
</RECORD>
<RECORD>
<OPCODE>OP_ADD_BLOCK</OPCODE>
<DATA>
<TXID>308</TXID>
<PATH>/user/hadoop/test/cpHello.txt._COPYING_</PATH>
<BLOCK>
<BLOCK_ID>1073741863</BLOCK_ID>
<NUM_BYTES>0</NUM_BYTES>
<GENSTAMP>1041</GENSTAMP>
</BLOCK>
<RPC_CLIENTID></RPC_CLIENTID>
<RPC_CALLID>-2</RPC_CALLID>
</DATA>
</RECORD>
<RECORD>
<OPCODE>OP_CLOSE</OPCODE>
<DATA>
<TXID>309</TXID>
<LENGTH>0</LENGTH>
<INODEID>0</INODEID>
<PATH>/user/hadoop/test/cpHello.txt._COPYING_</PATH>
<REPLICATION>3</REPLICATION>
<MTIME>1536562304777</MTIME>
<ATIME>1536562302831</ATIME>
<BLOCKSIZE>134217728</BLOCKSIZE>
<CLIENT_NAME></CLIENT_NAME>
<CLIENT_MACHINE></CLIENT_MACHINE>
<OVERWRITE>false</OVERWRITE>
<BLOCK>
<BLOCK_ID>1073741863</BLOCK_ID>
<NUM_BYTES>1116</NUM_BYTES>
<GENSTAMP>1041</GENSTAMP>
</BLOCK>
<PERMISSION_STATUS>
<USERNAME>hadoop</USERNAME>
<GROUPNAME>supergroup</GROUPNAME>
<MODE>420</MODE>
</PERMISSION_STATUS>
</DATA>
</RECORD>
<RECORD>
<OPCODE>OP_RENAME_OLD</OPCODE>
<DATA>
<TXID>310</TXID>
<LENGTH>0</LENGTH>
<SRC>/user/hadoop/test/cpHello.txt._COPYING_</SRC>
<DST>/user/hadoop/test/cpHello.txt</DST>
<TIMESTAMP>1536562304822</TIMESTAMP>
<RPC_CLIENTID>424e8401-aa20-4dd2-83ae-cedd762158f0</RPC_CLIENTID>
<RPC_CALLID>12</RPC_CALLID>
</DATA>
</RECORD>
</EDITS>
上述是往hdfs上傳文件的一個(gè)完成過(guò)程
首先創(chuàng)建文件夾酸钦,添加文件(不是真正的添加怪得,只是占個(gè)位置),分配塊ID卑硫,生成時(shí)間戳徒恋,真正上傳文件,關(guān)閉流欢伏,重命名文件入挣。
NameNode和SecondaryNameNode工作機(jī)制
該圖可以分成兩個(gè)階段看
第一階段:NameNode啟動(dòng)
1). 第一次啟動(dòng)NameNode格式化后,創(chuàng)建fsimage和edits文件硝拧。如果不是第一次啟動(dòng)径筏,直接加載編輯日志和鏡像文件到內(nèi)存。
2). 客戶端對(duì)元數(shù)據(jù)進(jìn)行增刪改的請(qǐng)求障陶。
3). NameNode記錄操作日志滋恬,更新滾動(dòng)日志。
4). NameNode在內(nèi)存中對(duì)數(shù)據(jù)進(jìn)行增刪改查抱究。第二階段:Secondary NameNode工作
1). Secondary NameNode詢問(wèn)NameNode是否需要checkpoint恢氯。直接帶回NameNode是否檢查結(jié)果。
2). Secondary NameNode請(qǐng)求執(zhí)行checkpoint鼓寺。
3). NameNode滾動(dòng)正在寫的edits日志勋拟。
4). 將滾動(dòng)前的編輯日志和鏡像文件拷貝到Secondary NameNode。
5). Secondary NameNode加載編輯日志和鏡像文件到內(nèi)存妈候,并合并敢靡。
6). 生成新的鏡像文件fsimage.ckpt。
7). 拷貝fsimage.chkpoint到NameNode州丹。
8). NameNode將fsimage.chkpoint重新命名成fsimage醋安。
checkpoint時(shí)間設(shè)置
- 通常情況下,SecondaryNameNode每隔一小時(shí)執(zhí)行一次墓毒。如果修改在hdfs-site中
在hdfs-default.xml中值如下
<property>
<name>dfs.namenode.checkpoint.period</name>
<value>3600</value>
<description>The number of seconds between two periodic checkpoints.
</description>
</property>
- 一分鐘檢查一次操作次數(shù)吓揪,當(dāng)操作次數(shù)達(dá)到1百萬(wàn)時(shí),SecondaryNameNode執(zhí)行一次所计。
在hdfs-default.xml配置如下
<property>
<name>dfs.namenode.checkpoint.txns</name>
<value>1000000</value>
<description>The Secondary NameNode or CheckpointNode will create a checkpoint
of the namespace every 'dfs.namenode.checkpoint.txns' transactions, regardless
of whether 'dfs.namenode.checkpoint.period' has expired.
</description>
</property>
<property>
<name>dfs.namenode.checkpoint.check.period</name>
<value>60</value>
<description>The SecondaryNameNode and CheckpointNode will poll the NameNode
every 'dfs.namenode.checkpoint.check.period' seconds to query the number
of uncheckpointed transactions.
</description>
</property>
NameNode故障處理
方法一
將SecondaryNameNode中數(shù)據(jù)拷貝到NameNode存儲(chǔ)數(shù)據(jù)的目錄
- kill -9 NameNode對(duì)應(yīng)的進(jìn)程
- 刪除NameNode存儲(chǔ)數(shù)據(jù)
rm -rf /opt/module/hadoop-2.8.3/data/tmp/dfs/name/ - 拷貝SecondaryNameNode中數(shù)據(jù)到原NameNode存儲(chǔ)數(shù)據(jù)目錄
scp -r hadoop@hadoop-102:/opt/module/hadoop-2.8.3/data/tmp/dfs/namesecondary/* ./name - 重新啟動(dòng)NameNode
方法二
使用-importCheckpoint選項(xiàng)啟動(dòng)NameNode守護(hù)進(jìn)程柠辞,從而將SecondaryNameNode中數(shù)據(jù)拷貝到NameNode目錄中
- 修改hdfs-site.xml
<property>
<name>dfs.namenode.checkpoint.period</name>
<value>120</value>
</property>
<property>
<name>dfs.namenode.name.dir</name>
<value>/opt/module/hadoop-2.7.2/data/tmp/dfs/name</value>
</property>
- kill -9 namenode進(jìn)程
- 刪除NameNode存儲(chǔ)的數(shù)據(jù)
rm -rf /opt/module/hadoop-2.8.3/data/tmp/dfs/name/ - 如果SecondaryNameNode不和NameNode在一個(gè)主機(jī)節(jié)點(diǎn)上,需要將SecondaryNameNode存儲(chǔ)數(shù)據(jù)的目錄拷貝到NameNode存儲(chǔ)數(shù)據(jù)的平級(jí)目錄主胧,并刪除in_use.lock文件
在dfs目錄下執(zhí)行
scp -r hadoop@hadoop-102:/opt/module/hadoop-2.8.3/data/tmp/dfs/namesecondary ./
進(jìn)入namesecondary目錄叭首,刪除in_use.lock文件
cd namesecondary
rm -rf in_use.lock - 導(dǎo)入檢查點(diǎn)數(shù)據(jù)(等待一會(huì)ctrl+c結(jié)束掉)
hdfs namenode -importCheckpoint - 啟動(dòng)namenode
hadoop-daemon.sh start namenode
集群安全模式
概述
NameNode啟動(dòng)時(shí),首先將映像文件(fsimage)載入內(nèi)存踪栋,并執(zhí)行編輯日志(edits)中的各項(xiàng)操作焙格。一旦在內(nèi)存中成功建立文件系統(tǒng)元數(shù)據(jù)的映像,則創(chuàng)建一個(gè)新的fsimage文件和一個(gè)空的編輯日志夷都。此時(shí)眷唉,NameNode開始監(jiān)聽DataNode請(qǐng)求。但是此刻囤官,NameNode運(yùn)行在安全模式冬阳,即NameNode的文件系統(tǒng)對(duì)于客戶端來(lái)說(shuō)是只讀的。
系統(tǒng)中的數(shù)據(jù)塊的位置并不是由NameNode維護(hù)的党饮,而是以塊列表的形式存儲(chǔ)在DataNode中肝陪。在系統(tǒng)的正常操作期間,NameNode會(huì)在內(nèi)存中保留所有塊位置的映射信息刑顺。在安全模式下氯窍,各個(gè)DataNode會(huì)向NameNode發(fā)送最新的塊列表信息,NameNode了解到足夠多的塊位置信息之后捏检,即可高效運(yùn)行文件系統(tǒng)荞驴。
如果滿足“最小副本條件”,NameNode會(huì)在30秒鐘之后就退出安全模式贯城。所謂的最小副本條件指的是在整個(gè)文件系統(tǒng)中99.9%的塊滿足最小副本級(jí)別(默認(rèn)值:dfs.replication.min=1)熊楼。在啟動(dòng)一個(gè)剛剛格式化的HDFS集群時(shí),因?yàn)橄到y(tǒng)中還沒有任何塊能犯,所以NameNode不會(huì)進(jìn)入安全模式鲫骗。
基本語(yǔ)法
集群處于安全模式,不能執(zhí)行重要操作(寫操作)踩晶。集群?jiǎn)?dòng)完成后执泰,自動(dòng)退出安全模式。
- bin/hdfs dfsadmin -safemode get (功能描述:查看安全模式狀態(tài))
- bin/hdfs dfsadmin -safemode enter (功能描述:進(jìn)入安全模式狀態(tài))
- bin/hdfs dfsadmin -safemode leave (功能描述:離開安全模式狀態(tài))
- bin/hdfs dfsadmin -safemode wait (功能描述:等待安全模式狀態(tài)渡蜻,監(jiān)控安全模式)
模擬等待安全模式
- 先進(jìn)入安全模式
hdfs dfsadmin -safemode enter - 編寫并執(zhí)行下面腳本
vim testWait.sh
輸入如下內(nèi)容
#!/bin/bash
hdfs dfsadmin -safemode wait
hdfs dfs -put test.txt /
給執(zhí)行權(quán)限
chmod +x testWait.sh
執(zhí)行
./testWait.sh
- 新打開一個(gè)窗口术吝,離開安全模式
hdfs dfsadmin -safemode leave
觀察結(jié)果计济,是否上傳成功
NameNode多目錄配置
NameNode的本地目錄可以配置成多個(gè),且每個(gè)目錄存放內(nèi)容相同排苍,增加了可靠性
具體步驟如下
- 在hdfs-site.xml文件中增加如下內(nèi)容
<property>
<name>dfs.namenode.name.dir</name>
<value>file:///${hadoop.tmp.dir}/dfs/name1,file:///${hadoop.tmp.dir}/dfs/name2</value>
</property>
- 停止集群
stop-dfs.sh - 刪除date和logs中所有數(shù)據(jù)
rm -rf /data /logs - 格式化集群并啟動(dòng)
hdfs namenode -format
start-dfs.sh -
查看結(jié)果