概念
Namespace
目录、文件、块合在一起,起了个名称Namespace(命名空间)
拥有单独的目录(blockpool)
BlockMap
除Namespace外,NameNode还管理非常重要的元数据BlocksMap,描述数据块Block与DataNode节点之间的对应关系。NameNode并没有对这部分元数据同样操作持久化,原因是每个DataNode已经持有属于自己管理的Block集合,将所有DataNode的Block集合汇总后即可构造出完整BlocksMap。
BlockMap由三元组构成。每个文件块block有几个副本,就有几个三元组:(DataNodeID, PreBlock, NextBlock)
NameNode硬盘文件信息
目录结构
- current
- VERSION
- edits_${start_txid}-${end_txid}
- editsinprogress${start_txid}
- fsimage_${end_txid}
- fsimage_${end_txid}.md5
- in_user.lock
edit logs、fsimage、seen_txid、VERSION、in_use.lock
主要文件
edit logs编辑日志文件
edit logs - 它是在NameNode启动后,对文件系统的改动序列
每条记录都是一个事务。有事务ID作为编号。
分段
Editlog被切割成多段(Segment)。
正在写入的Segment叫inprogess状态。其文件名形如 editsinprogress${starttxid},其中${start_txid} 表示这个 segment 的起始事务 id。
已经写入完成的 EditLog Segment 处于 finalized 状态,其文件名形如 edits${start_txid}-${end_txid}
editlog和fsimage存在磁盘目录${dfs.namenode.name.dir}/current
操作
OP_START_LOG_SEGMENT
OP_ADD
OP_ALLOCATE_BLOCK_ID
OP_SET_GENSTAMP_V2
OP_ADD_BLOCK
OP_CLOSE
OP_RENAME_OLD
<?xml version="1.0" encoding="UTF-8"?>
<EDITS>
<EDITS_VERSION>-63</EDITS_VERSION>
<RECORD>
<OPCODE>OP_START_LOG_SEGMENT</OPCODE>
<DATA>
<TXID>6</TXID>
</DATA>
</RECORD>
<RECORD>
<OPCODE>OP_ADD</OPCODE>
<DATA>
<TXID>7</TXID>
<LENGTH>0</LENGTH>
<INODEID>16386</INODEID>
<PATH>/wc.txt._COPYING_</PATH>
<REPLICATION>3</REPLICATION>
<MTIME>1574260053772</MTIME>
<ATIME>1574260053772</ATIME>
<BLOCKSIZE>134217728</BLOCKSIZE>
<CLIENT_NAME>DFSClient_NONMAPREDUCE_-929106461_1</CLIENT_NAME>
<CLIENT_MACHINE>192.168.153.101</CLIENT_MACHINE>
<OVERWRITE>true</OVERWRITE>
<PERMISSION_STATUS>
<USERNAME>root</USERNAME>
<GROUPNAME>supergroup</GROUPNAME>
<MODE>420</MODE>
</PERMISSION_STATUS>
<RPC_CLIENTID>48f6f0ee-0e35-4b0f-86b1-b2df41b2c4cd</RPC_CLIENTID>
<RPC_CALLID>3</RPC_CALLID>
</DATA>
</RECORD>
<RECORD>
<OPCODE>OP_ALLOCATE_BLOCK_ID</OPCODE>
<DATA>
<TXID>8</TXID>
<BLOCK_ID>1073741825</BLOCK_ID>
</DATA>
</RECORD>
<RECORD>
<OPCODE>OP_SET_GENSTAMP_V2</OPCODE>
<DATA>
<TXID>9</TXID>
<GENSTAMPV2>1001</GENSTAMPV2>
</DATA>
</RECORD>
<RECORD>
<OPCODE>OP_ADD_BLOCK</OPCODE>
<DATA>
<TXID>10</TXID>
<PATH>/wc.txt._COPYING_</PATH>
<BLOCK>
<BLOCK_ID>1073741825</BLOCK_ID>
<NUM_BYTES>0</NUM_BYTES>
<GENSTAMP>1001</GENSTAMP>
</BLOCK>
<RPC_CLIENTID></RPC_CLIENTID>
<RPC_CALLID>-2</RPC_CALLID>
</DATA>
</RECORD>
<RECORD>
<OPCODE>OP_CLOSE</OPCODE>
<DATA>
<TXID>11</TXID>
<LENGTH>0</LENGTH>
<INODEID>0</INODEID>
<PATH>/wc.txt._COPYING_</PATH>
<REPLICATION>3</REPLICATION>
<MTIME>1574260055275</MTIME>
<ATIME>1574260053772</ATIME>
<BLOCKSIZE>134217728</BLOCKSIZE>
<CLIENT_NAME></CLIENT_NAME>
<CLIENT_MACHINE></CLIENT_MACHINE>
<OVERWRITE>false</OVERWRITE>
<BLOCK>
<BLOCK_ID>1073741825</BLOCK_ID>
<NUM_BYTES>75</NUM_BYTES>
<GENSTAMP>1001</GENSTAMP>
</BLOCK>
<PERMISSION_STATUS>
<USERNAME>root</USERNAME>
<GROUPNAME>supergroup</GROUPNAME>
<MODE>420</MODE>
</PERMISSION_STATUS>
</DATA>
</RECORD>
<RECORD>
<OPCODE>OP_RENAME_OLD</OPCODE>
<DATA>
<TXID>12</TXID>
<LENGTH>0</LENGTH>
<SRC>/wc.txt._COPYING_</SRC>
<DST>/wc.txt</DST>
<TIMESTAMP>1574260055288</TIMESTAMP>
<RPC_CLIENTID>48f6f0ee-0e35-4b0f-86b1-b2df41b2c4cd</RPC_CLIENTID>
<RPC_CALLID>9</RPC_CALLID>
</DATA>
</RECORD>
<RECORD>
<OPCODE>OP_END_LOG_SEGMENT</OPCODE>
<DATA>
<TXID>13</TXID>
</DATA>
</RECORD>
</EDITS>
fsimage命名空间镜像文件
它是在NameNode启动时对整个文件系统的快照。定期对内存中文件系统镜像checkpoint生成,格式fsimage_${end_txid}。
fsimage 2.4版本之后,采用protobuffer描述。
源码链接如下
https://github.com/apache/hadoop/blob/branch-2.10.0/hadoop-hdfs-project/hadoop-hdfs/src/main/proto/fsimage.proto
seen_txid
存当前transaction_id,格式化会变成0。
in_use.lock
元数据恢复
fsimage和editlog合并到一起恢复元数据。fsimage加载到内存,再把fsimage结束事务后的事务从Editlog中读取。
块所在DataNode信息不再本地磁盘,每次启动根据DataNode上报。
NameNode元数据存在内存中,故受JVM heap size限制。每个Block占150Byte元数据。
NodeNode的block管理
与yarn不同,hdfs并没有直接用状态机来管理block,而是将不同状态的block存储在不同的缓冲区中,状态迁移则对应数据块在不同缓冲区中的移动。包括BlockManager#blocksMap,namenode上的数据块状态共涉及以下几种缓冲区:
正在写入
的数据块:通过LeaseManager扫描INodeFile,BlockInfo#isComplete()返回false即为正在写入的数据块(不常用)- 存储数据块的元信息,可以认为存储
已完成
等所有状态的数据块:BlockManager#blocksMap,BlockInfo#isComplete()返回true 需要复制
的数据块:BlockManager#neededReplications正在复制
的数据块:BlockManager#pendingReplications复制超时
的数据块:BlockManager#pendingReplications#timedOutItems- 多余的数据块:BlockManager#excessReplicateMap(即
需要删除
的数据块) 无效数据块缓冲区BlockManager#invalidateBlocks(即
正在删除
的数据块)CheckPoint
非HA
如果HDFS没有做HA的话,checkpoint由SecondNameNode进程(一般SecondNameNode单独起在另一台机器上)来进行。在HA模式下,checkpoint则由StandBy状态的NameNode来进行。
什么时候进行checkpoint由两个参数dfs.namenode.checkpoint.preiod(默认值是3600,即1小时)
- dfs.namenode.checkpoint.txns(默认值是1000000)来决定。
period参数表示,经过1小时就进行一次checkpoint,txns参数表示,hdfs经过100万次操作后就要进行checkpoint了。这两个参数任意一个得到满足,都会触发checkpoint过程。
进行checkpoint的节点每隔dfs.namenode.checkpoint.check.period(默认值是60)秒就会去统计一次hdfs的操作次数。
HA
开启HA的HDFS,元数据已经在standby内存中。
- 当前的状态保存成一个新的文件fsimage.ckpt_${end_txid}。
- 然后为该fsimage文件创建一个MD5文件,并将fsimage文件重命名为fsimage_txid。
- SbNN向ANN发送一条HTTP GET请求。请求中包含了SbNN的主机名,端口以及新fsimage的txid。
- ANN收到请求后,用获取到的信息反过来向SbNN再发送一条HTTP GET请求,获取新的fsimage文件。这个新的fsimage文件传输到ANN上后,也是先命名为fsimage.ckpt_txid,并为它创建一个MD5文件。然后再改名为fsimage_txid。fsimage过程完成。
secondarynamenode
缺点:元数据滞后于NameNode(上次Checkpoint的结果),所以NameNode失效时会丢数据。Quorum Journal Manager(QJM群体日志管理器)
同一时间QJM只允许一个NameNode向EditLog写日志。Failover Controller(故障转移控制器)
有多种,默认使用Zookeeper。
组件
Block Management