大数据开发工程师-第四周 第一章 初识NameNode


NameNode介绍

1
2
3
4
5
6
7
  首先是NameNode,NameNode是整个文件系统的管理节点
它主要维护着整个文件系统的文件目录树,文件/目录的信息和每个文件对应的数据块列表,并且还负责接收用户的操作请求

目录树:表示目录之间的层级关系,就是我们在hdfs上执行ls命令可以看到的那个目录结构信息。
文件/目录的信息:表示文件/目录的的一些基本信息,所有者 属组 修改时间 文件大小等信息
每个文件对应的数据块列表:如果一个文件太大,那么在集群中存储的时候会对文件进行切割,这个时候就类似于会给文件分成一块一块的,存储到不同机器上面。所以HDFS还要记录一下一个文件到底被分了多少块,每一块都在什么地方存储着
接收用户的操作请求:其实我们在命令行使用hdfs操作的时候,是需要先和namenode通信 才能开始去操作数据的。

HQPVwn.md.png

1
2
3
4
这些文件所在的路径是由hdfs-default.xml的dfs.namenode.name.dir属性控制的
hdfs-default.xml文件在哪呢?

它在hadoop-3.2.0\share\hadoop\hdfs\hadoop-hdfs-3.2.0.jar中,这个文件中包含了HDFS相关的所有默认参数,咱们在配置集群的时候会修改一个hdfs-site.xml文件,hdfs-site.xml文件属于hdfs-default.xml的一个扩展,它可以覆盖掉hdfs-default.xml中同名的参数。
1
2
3
4
5
6
7
8
9
10
11
12
13
那我们来看一下这个文件中的dfs.namenode.name.dir属性

<property>
<name>dfs.namenode.name.dir</name>
<value>file://${hadoop.tmp.dir}/dfs/name</value>
<description>Determines where on the local filesystem the DFS name node
should store the name table(fsimage). If this is a comma-delimited list
of directories then the name table is replicated in all of the
directories, for redundancy. </description>
</property>
这个属性的值是由hadoop.tmp.dir属性控制的,这个属性的值默认在core-default.xml文件中。大家还有没有印象,我们在修改core-site.xml的时候设置的有hadoop.tmp.dir属性的值,值是/data/hadoop_repo,所以说core-site.xml中的hadoop.tmp.dir属性会覆盖掉core-default.xml中的值

最终dfs.namenode.name.dir属性的值就是:/data/hadoop_repo/dfs/name
1
2
3
4
5
进入到/data/hadoop_repo/dfs/name目录下

发现这个下面会有一个current目录,表示当前的意思,还有一个in_use.lock 这个只是一个普通文件,但是它其实有特殊的含义,你看他的文件名后缀值lock 表示是锁的意思,文件名是in_use 表示这个文件现在正在使用,不允许你再启动namenode。

当我们启动namonde的时候 会判断这个目录下是否有in_use.lock 这个相当于一把锁,如果没有的话,才可以启动成功,启动成功之后就会加一把锁,停止的时候会把这个锁去掉

HQZeu8.md.png

1
2
3
4
5
6
7
8
9
current里面有edits文件和fsimage文件

fsimage文件有两个文件名相同的,有一个后缀是md5 md5是一种加密算法,这个其实主要是为了做md5校验的,为了保证文件传输的过程中不出问题,相同内容的md5是一样的,所以后期如果我把这个fsimage和对应的fsimage.md5发给你 然后你根据md5对fsimage的内容进行加密,获取一个值 和fsimage.md5中的内容进行比较,如果一样,说明你接收到的文件就是完整的。

我们在网站下载一些软件的时候 也会有一些md5文件,方便验证下载的文件是否完整。

在这里可以把fsimage 拆开 fs 是文件系统 filesystem image是镜像
说明是文件系统镜像,就是给文件照了一个像,把文件的当前信息记录下来
我们可以看一下这个文件,这个文件需要使用特殊的命令进行查看
fsimage文件
1
2
3
-i 输入文件 -o 输出文件

[root@bigdata01 current]# hdfs oiv -p XML -i fsimage_0000000000000000056 -o fsimage56.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<inode><id>16393</id><type>FILE</type><name>LICENSE.txt</name><replication>2</replication><mtime>1586332513657</mtime><atime>1586332513485</atime><preferredBlockSize>134217728</preferredBlockSize><permission>root:supergroup:0644</permission><blocks><block><id>1073741827</id><genstamp>1003</genstamp><numBytes>150569</numBytes></block>
</blocks>
<storagePolicyId>0</storagePolicyId></inode>
<inode><id>16394</id><type>FILE</type><name>NOTICE.txt</name><replication>2</replication><mtime>1586332522962</mtime><atime>1586332522814</atime><preferredBlockSize>134217728</preferredBlockSize><permission>root:supergroup:0644</permission><blocks><block><id>1073741828</id><genstamp>1004</genstamp><numBytes>22125</numBytes></block>
</blocks>
<storagePolicyId>0</storagePolicyId></inode>
<inode><id>16395</id><type>FILE</type><name>README.txt</name><replication>2</replication><mtime>1586332531932</mtime><atime>1586332531689</atime><preferredBlockSize>134217728</preferredBlockSize><permission>root:supergroup:0644</permission><blocks><block><id>1073741829</id><genstamp>1005</genstamp><numBytes>1361</numBytes></block>
</blocks>
<storagePolicyId>0</storagePolicyId></inode>
</INodeSection>
<INodeReferenceSection></INodeReferenceSection><SnapshotSection><snapshotCounter>0</snapshotCounter><numSnapshots>0</numSnapshots></SnapshotSection>
<INodeDirectorySection><directory><parent>16385</parent><child>16393</child><child>16394</child><child>16395</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>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
里面最外层是一个fsimage标签,看里面的inode标签,
这个inode表示是hdfs中的每一个目录或者文件信息

id:唯一编号
type:文件类型
name:文件名称
replication:文件的副本数量
mtime:修改时间
atime:访问时间
preferredBlockSize:推荐每一个数据块的大小
permission:权限信息
blocks:包含多少数据块【文件被切成数据块】
block:内部的id表示是块id,genstamp是一个唯一编号,numBytes表示当前数据块的实际大小,storagePolicyId表示是数据的存储策略

这个文件中其实就维护了整个文件系统的文件目录树,文件/目录的元信息和每个文件对应的数据块列表,所以说fsimage中存放了hdfs最核心的数据。
edits文件
1
2
3
4
5
6
7
8
9
下面我们来看一下edits文件,这些文件在这称之为事务文件,为什么呢?

hdfs oev -i edits_0000000000000000057-0000000000000000065 -o edits.xml

当我们上传一个文件的时候,上传一个10G的文件,假设传到9G的时候上传失败了,这个时候就需要重新传,那hdfs怎么知道这个文件失败了呢?这个是在edits文件中记录的。
当我们上传大文件的时候,一个大文件会分为多个block,那么edits文件中就会记录这些block的上传状态,只有当全部block都上传成功了以后,这个时候edits中才会记录这个文件上传成功了,那么我们执行hdfs dfs -ls 的时候就能查到这个文件了,
所以当我们在hdfs中执行ls命令的时候,其实会查询fsimage和edits中的内容
为什么会有这两个文件呢?
首先,我们固化的一些文件内容是存储在fsimage文件中,当前正在上传的文件信息是存储在edits文件中。
1
2
3
4
5
6
7
8
这个edits.xml中可以大致看一下,里面有很多record。每一个record代表不同的操作,

例如 OP_ADD,OP_CLOSE 等等,具体挑一个实例进行分析。
OP_ADD:执行上传操作
OP_ALLOCATE_BLOCK_ID:申请block块id
OP_SET_GENSTAMP_V2:设置GENSTAMP
OP_ADD_BLOCK:添加block块
OP_CLOSE:关闭上传操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
<RECORD>
<OPCODE>OP_ADD</OPCODE>
<DATA>
<TXID>58</TXID>
<LENGTH>0</LENGTH>
<INODEID>16396</INODEID>
<PATH>/user.txt</PATH>
<REPLICATION>3</REPLICATION>
<MTIME>1586349095694</MTIME>
<ATIME>1586349095694</ATIME>
<BLOCKSIZE>134217728</BLOCKSIZE>
<CLIENT_NAME>DFSClient_NONMAPREDUCE_-1768454371_1</CLIENT_NAME>
<CLIENT_MACHINE>192.168.182.1</CLIENT_MACHINE>
<OVERWRITE>true</OVERWRITE>
<PERMISSION_STATUS>
<USERNAME>yehua</USERNAME>
<GROUPNAME>supergroup</GROUPNAME>
<MODE>420</MODE>
</PERMISSION_STATUS>
<ERASURE_CODING_POLICY_ID>0</ERASURE_CODING_POLICY_ID>
<RPC_CLIENTID>1722b83a-2dc7-4c46-baa9-9fa956b755cd</RPC_CLIENTID>
<RPC_CALLID>0</RPC_CALLID>
</DATA>
</RECORD>
<RECORD>
<OPCODE>OP_ALLOCATE_BLOCK_ID</OPCODE>
<DATA>
<TXID>59</TXID>
<BLOCK_ID>1073741830</BLOCK_ID>
</DATA>
</RECORD>
<RECORD>
<OPCODE>OP_SET_GENSTAMP_V2</OPCODE>
<DATA>
<TXID>60</TXID>
<GENSTAMPV2>1006</GENSTAMPV2>
</DATA>
</RECORD>
<RECORD>
<OPCODE>OP_ADD_BLOCK</OPCODE>
<DATA>
<TXID>61</TXID>
<PATH>/user.txt</PATH>
<BLOCK>
<BLOCK_ID>1073741830</BLOCK_ID>
<NUM_BYTES>0</NUM_BYTES>
<GENSTAMP>1006</GENSTAMP>
</BLOCK>
<RPC_CLIENTID/>
<RPC_CALLID>-2</RPC_CALLID>
</DATA>
</RECORD>
<RECORD>
<OPCODE>OP_CLOSE</OPCODE>
<DATA>
<TXID>62</TXID>
<LENGTH>0</LENGTH>
<INODEID>0</INODEID>
<PATH>/user.txt</PATH>
<REPLICATION>3</REPLICATION>
<MTIME>1586349096480</MTIME>
<ATIME>1586349095694</ATIME>
<BLOCKSIZE>134217728</BLOCKSIZE>
<CLIENT_NAME/>
<CLIENT_MACHINE/>
<OVERWRITE>false</OVERWRITE>
<BLOCK>
<BLOCK_ID>1073741830</BLOCK_ID>
<NUM_BYTES>17</NUM_BYTES>
<GENSTAMP>1006</GENSTAMP>
</BLOCK>
<PERMISSION_STATUS>
<USERNAME>yehua</USERNAME>
<GROUPNAME>supergroup</GROUPNAME>
<MODE>420</MODE>
</PERMISSION_STATUS>
</DATA>
</RECORD>
1
2
3
4
这里面的每一个record都有一个事务id,txid,事务id是连续的,其实一个put操作会在edits文件中产生很多的record,对应的就是很多步骤,这些步骤对我们是屏蔽的。
注意了,根据我们刚才的分析,我们所有对hdfs的增删改操作都会在edits文件中留下信息,那么fsimage文件中的内容是从哪来的?
其实是这样的,edits文件会定期合并到fsimage文件中。
有同学可能有疑问了,edits文件和fsimage文件中的内容是不一样的,这怎么能是合并出来的呢?
1
注意,这个其实是框架去做的,在合并的时候会对edits中的内容进行转换,生成新的内容,其实edits中保存的内容是不是太细了,单单一个上传操作就分为了好几步,其实上传成功之后,我们只需要保存文件具体存储的block信息就行了把,所以在合并的时候其实是对edits中的内容进行了精简。
1
2
3
他们具体合并的代码我们不用太过关注,但是我们要知道是那个进程去做的这个事情,
其实就是我们之前提到的secondarynamenode
这个进程就是负责定期的把edits中的内容合并到fsimage中。他只做一件事,这是一个单独的进程,在实际工作中部署的时候,也需要部署到一个单独的节点上面。
seentxid文件

HQ3eWF.md.png

1
current目录中还有一个seentxid文件,HDFS format之后是0,它代表的是namenode里面的edits*文件的尾数,namenode重启的时候,会按照seen_txid的数字,顺序从头跑edits_0000001~到seen_txid的数字。如果根据对应的seen_txid无法加载到对应的文件,NameNode进程将不会完成启动以保护数据一致性。
VERSION文件

HQ3Ky9.md.png

1
2
3
这里面显示的集群的一些信息、当重新对hdfs格式化 之后,这里面的信息会变化。
之前我们说过 在使用hdfs的时候只格式化一次,不要格式化多次,为什么呢?
一会在讲datanode的时候会详细解释、
总结
1
2
3
4
5
6
7
fsimage: 元数据镜像文件,存储某一时刻NameNode内存中的元数据信息,就类似是定时做了一个快照操作。【这里的元数据信息是指文件目录树、文件/目录的信息、每个文件对应的数据块列表】

edits: 操作日志文件【事务文件】,这里面会实时记录用户的所有操作

seentxid: 是存放transactionId的文件,format之后是0,它代表的是namenode里面的edits*文件的尾数,namenode重启的时候,会按照seen_txid的数字,顺序从头跑edits_0000001~到seen_txid的数字。如果根据对应的seen_txid无法加载到对应的文件,NameNode进程将不会完成启动以保护数据一致性。

VERSION:保存了集群的版本信息

本文标题:大数据开发工程师-第四周 第一章 初识NameNode

文章作者:TTYONG

发布时间:2022年02月08日 - 18:02

最后更新:2023年06月26日 - 16:06

原始链接:http://tianyong.fun/%E5%A4%A7%E6%95%B0%E6%8D%AE%E5%BC%80%E5%8F%91%E5%B7%A5%E7%A8%8B%E5%B8%88-%E7%AC%AC%E5%9B%9B%E5%91%A8%20%E7%AC%AC%E4%B8%80%E7%AB%A0%20%E5%88%9D%E8%AF%86NameNode.html

许可协议: 转载请保留原文链接及作者。

多少都是爱
0%