您好,登錄后才能下訂單哦!
[TOC]
txid:
namenode對每個操作事件(增刪改操作)都給了一個唯一的id標識,稱為txid,一般是從0開始自增,每多一個操作,txid就自增1。
fsimage:
是namenode在內存中的元數據在本地磁盤的一個鏡像文件,但是通常情況fsimage并沒有包含自新的操作事件,所以本質上和內存中元數據還是有差距的。這里記錄的不是操作日志,其中包含HDFS文件系統的所有目錄和文件idnode的序列化信息。一般命名方式是fsimage_txid 的形式,后面的txid表示該fsimage記錄的最新的操作事件的txid。
edits:
是記錄對namenode進行增刪改操作的操作日志文件,如果有知道mysql的話,這和mysql 的二進制日志有點相似。
[root@bigdata121 tmp]# tree dfs/name
dfs/name
├── current
│?? ├── edits_0000000000000000001-0000000000000000002
│?? ├── edits_0000000000000000003-0000000000000000004
│?? ├── edits_0000000000000000005-0000000000000000006
│?? ├── edits_0000000000000000007-0000000000000000008
│?? ├── edits_0000000000000000009-0000000000000000009
│?? ├── edits_0000000000000000010-0000000000000000011
│?? ├── edits_0000000000000000012-0000000000000000013
│?? ├── edits_0000000000000000014-0000000000000000015
│?? ├── edits_0000000000000000016-0000000000000000017
│?? ├── edits_0000000000000000018-0000000000000000019
│?? ├── edits_0000000000000000020-0000000000000000021
│?? ├── edits_0000000000000000022-0000000000000000024
│?? ├── edits_0000000000000000025-0000000000000000026
│?? ├── edits_inprogress_0000000000000000027
│?? ├── fsimage_0000000000000000024
│?? ├── fsimage_0000000000000000024.md5
│?? ├── fsimage_0000000000000000026
│?? ├── fsimage_0000000000000000026.md5
│?? ├── seen_txid
│?? └── VERSION
└── in_use.lock
總結來說,其實簡化成以下結構:
dfs/name
├── current
│?? ├── edits_txid1-txid2 可能有多個,是已經滾動生成的舊的edits文件
│?? ├── edits_inprogress_txid3 是目前正在使用的edits
│?? ├── fsimage_0000000000000000024 fsimage文件
│?? ├── fsimage_0000000000000000024.md5 fsimage文件的md5校驗值
│?? ├── seen_txid 記錄最新的txid
│?? └── VERSION 記錄hdfs集群的一些簡單信息
└── in_use.lock 鎖文件,避免該目錄用于啟動多個namenode
(1)VERSION文件的內容
# 在hdfs中會有多個namenode,不同的namenode的namenodeID是不同的,分別管理一組blockpoolID
namespaceID=983105879
# 集群ID,全局唯一
clusterID=CID-c12b7022-0c51-49c5-942f-edc889d37fee
# 標記該namenode的存儲目錄創建的時間。對于剛剛創建的存儲系統,這個屬性為0.但在文件系統升級之后,該值會更新到新的時間戳
cTime=1558262787574
# 標記該存儲目錄是namenode還是datanode
storageType=NAME_NODE
# 一個block pool id標識一個block pool,并且是跨集群的全局唯一。當一個新的Namespace被創建的時候(format過程的一部分)會創建并持久化一個唯一ID。在創建過程構建全局唯一的BlockPoolID比人為的配置更可靠一些。NN將BlockPoolID持久化到磁盤中,在后續的啟動過程中,會再次load并使用。
blockpoolID=BP-473222668-192.168.50.121-1558262787574
# 這個沒什么用
layoutVersion=-63
(2)seen_txid
這個文件中記錄了目前最新的一個txid
(3)SNN的目錄結構和namenode是一樣的,只是缺少了部分最新的edits文件。
我們可以看到上面fsimage和edits文件的文件名都跟著很長一串數字,那是什么呢,其實是txid,從兩者命名方式上,我們可以看出一些規律來。
edits文件:
我們可以看到edits文件都是 edits_00000xxx-000000xxx的方式命名的,其實意思就是表示該edits文件中記錄了txid操作事件的范圍。而 edit_inprogess_00000xxx 則表示當前所記錄到的最新的txid事件,以及該文件是目前正在使用的edits文件。
fsimage文件:
以fsimage_000000xxx 的方式命名,表示的是該fsimage 文件記錄到的最新的txid事件,請注意,因為fsimage是有條件觸發之后,edits文件才會合并到fsimage的,否則不會合并。所以一般情況下,edits文件后面的txid會比fsimage 大的。
//格式 : hdfs oiv -p 輸出格式 -i 輸入文件 -o 輸出文件
[root@bigdata121 current]# hdfs oiv -p XML -i fsimage_0000000000000000037 -o /tmp/fsimage37.xml
前面已經說到,fsimage記錄的主要是元數據信息,它描述了hdfs 中存儲的目錄結構以及目錄下的文件,還有對應的目錄和文件的元信息。我們截取部分信息來看看:
<fsimage>
<version>
<layoutVersion>-63</layoutVersion>
<onDiskVersion>1</onDiskVersion>
<oivRevision>17e75c2a11685af3e043aa5e604dc831e5b14674</oivRevision>
</version>
<NameSection>
<namespaceId>983105879</namespaceId>
<genstampV1>1000</genstampV1>
<genstampV2>1014</genstampV2>
<genstampV1Limit>0</genstampV1Limit>
<lastAllocatedBlockId>1073741837</lastAllocatedBlockId>
<txid>334</txid>
</NameSection>
<INodeSection>
<lastInodeId>16407</lastInodeId>
<numInodes>16</numInodes>
這里開始是重點,記錄的就是目錄結構以及元信息
<inode>
<id>16386</id>
<type>DIRECTORY</type> 這個是目錄,名字是test
<name>test</name>
<mtime>1558263065070</mtime> 修改時間
<permission>root:supergroup:0755</permission> 權限
<nsquota>-1</nsquota>
<dsquota>-1</dsquota>
</inode>
<inode>
<id>16387</id> 這是個文件,名為edit_new.xml
<type>FILE</type>
<name>edit_new.xml</name>
<replication>2</replication>
<mtime>1558263065045</mtime>
<atime>1558269494520</atime>
<preferredBlockSize>134217728</preferredBlockSize>
<permission>root:supergroup:0644</permission> 權限
<blocks> 這里是block信息,包含了哪些block
<block>
<id>1073741825</id>
<genstamp>1001</genstamp>
<numBytes>580</numBytes>
</block>
</blocks>
<storagePolicyId>0</storagePolicyId>
</inode>
<INodeSection>
<fsimage>
由以上這部分fsimage信息可知,它記錄當前文件系統的目錄結構以及對應的元信息。和edits的差別是,edits記錄的是對該文件系統的操作。
//格式:hdfs oev -p 輸出格式(默認XML) -i 輸入文件 -o 輸出文件
[root@bigdata121 current]# hdfs oev -i edits_inprogress_0000000000000000038 -o /tmp/edits_inprogess.xml
同樣截取部分信息查看:
<?xml version="1.0" encoding="UTF-8"?>
<EDITS>
<EDITS_VERSION>-63</EDITS_VERSION>
<RECORD>
<OPCODE>OP_START_LOG_SEGMENT</OPCODE> 表示操作的類別,這里是表示日志開始記錄
<DATA>
<TXID>38</TXID> 類似于操的ID,是唯一的
</DATA>
</RECORD>
</EDITS>
每個RECORD記錄的就是一次操作
<RECORD>
<OPCODE>OP_ADD_BLOCK</OPCODE> //像這個就表示上傳文件的操作
<DATA>
<TXID>34</TXID>
<PATH>/jdk-8u144-linux-x64.tar.gz._COPYING_</PATH>
<BLOCK>
<BLOCK_ID>1073741825</BLOCK_ID>
<NUM_BYTES>134217728</NUM_BYTES>
<GENSTAMP>1001</GENSTAMP>
</BLOCK>
<BLOCK>
<BLOCK_ID>1073741826</BLOCK_ID>
<NUM_BYTES>0</NUM_BYTES>
<GENSTAMP>1002</GENSTAMP>
</BLOCK>
<RPC_CLIENTID></RPC_CLIENTID>
<RPC_CALLID>-2</RPC_CALLID>
</DATA>
</RECORD>
每個RECORD記錄了一次操作,比如圖中的
OP_ADD代表添加文件操作。一般來說里面還記錄了
文件路徑(PATH)
修改時間(MTIME)
添加時間(ATIME)
客戶端名稱(CLIENT_NAME)
客戶端地址(CLIENT_MACHINE)
權限(PERMISSION_STATUS)等非常有用的信息
格式:hdfs dfsadmin -rollEdits
在core-site.xml中配置了hadoop.tmp.dir的話,各自的數據目錄如下:
NN:{hadoop.tmp.dir}/dfs/name fsimage和edits文件都會存儲在這一個目錄下
SNN:${hadoop.tmp.dir}/dfs/namesecondary SNN的數據目錄
DN:${hadoop.tmp.dir}/dfs/data datanode的數據目錄
如果不設置hadoop.tmp.dir 這個值,那么NN,SNN,DN都需要手動設置各自的數據目錄,否則數據文件都會生成到 /tmp/hadoop-root/dfs/ 下,各自的設置參數如下:
/*都在hdfs-site.xml中設置*/
//如果這兩個只設置了其中一個,那么fsimage和edits文件都會存儲到指定的一個目錄下
NN:dfs.namenode.name.dir 設置fsimage存儲的路徑
dfs.namenode.edits.dir 設置edits存儲路徑
DN: dfs.datanode.data.dir 這是datanode存儲目錄
SNN:dfs.namenode.checkpoint.dir 這是SNN存儲目錄
在單獨設置namenode的工作目錄時,我們可以給dfs.namenode.name.dir 設置多個值,以逗號分隔開,那么hdfs namenode -format格式化的時候,也會格式化出兩個namenode目錄,并且兩個目錄在運行過程中內容也保持一致,可以使用這種方式作為給namenode備份數據的補充。如:
<property>
<name>dfs.namenode.name.dir</name>
<value>file:///${hadoop.tmp.dir}/dfs/name1,file:///${hadoop.tmp.dir}/dfs/name2</value>
</property>
(1)第一次啟動namenode時(即第一次格式化namenode之后),會自動創建fsimage和edits文件。如果不是第一次啟動,則namenode會加載最新的fsimage以及從fsimage開始到最新的操作事件(以seen_txid文件記錄的txid為準)的所包含的edits文件到內存中,最終在內存中存儲的是最新的元信息。并創建一個新的edits文件,用于記錄的操作,名字是 edit_inprogress_xxxx。
(2)client 對namenode發起增刪改請求
(3)namenode響應請求
(4)namenode記錄增刪改操作時,會先將操作寫入到edits文件中,當成功寫入之后,才會修改內存中存儲的元數據。這種方式是為了保證最新的操作一定持續化存儲在磁盤這種永久性存儲中,避免意外導致操作記錄丟失。
(1)SNN根據設置的檢查checkpoint的時間間隔,詢問namenode是否需要執行checkpoint。namenode響應SNN結果。
(2)如果結果為是,則SNN請求namenode執行checkpoint操作
(3)namenode開始執行checkpoint操作,首先滾動目前正使用的edits文件,將滾動后的edits文件命名為 edits_txid1-txid2的形式,并創建新的edits文件,名字為 edits_inprogess_txid2+1。滾動edits目的主要是為了防止合并操作影響namenode對外提供服務,滾動之后,操作記錄可以正常寫入到新的edits文件中。
(4)將最新的fsimage(看文件后面的txid,最大的就是最新的),以及由此到最新的txid的edits文件拷貝到SNN。注意看fsimage文件名的txid以及edits文件名后面的txid,小于fsimage后面的txid的edits文件不需要拷貝。
(5)SNN讀取拷貝過來的fsiamge和edits文件到內存中進行合并
(6)合并后生成新的fsimage文件,名字為 fsimage.chkpoint
(7)拷貝fsimage.chkpoint到namenode
(8)namenode收到fsimage.chkpoint之后,重名為 fsimage_txid 的形式,后面txid表示此fsimage文件記錄的最新的操作的txid。
hdfs-default.xml
---------------checkpoint實際間隔------------------------
<!--checkpoint的時間間隔,默認一小時,單位是秒-->
<property>
<name>dfs.namenode.checkpoint.period</name>
<value>3600</value>
</property>
---------------操作次數------------------------
<!--觸發checkpoint操作條件之一,edits記錄的操作次數,達到這里指定的次數就會觸發checkpoint-->
<property>
<name>dfs.namenode.checkpoint.txns</name>
<value>1000000</value>
<description>操作動作次數</description>
</property>
<!--檢查操作次數的實際間隔,默認60秒-->
<property>
<name>dfs.namenode.checkpoint.check.period</name>
<value>60</value>
</property>
(1)edis文件的大小超過64M
(2)當前edits文件存在時間超過一定時間,默認3600秒
(3)edit文件中記錄的操作次數達到指定的次數,默認1000000次。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。