HDFS 初始namenode

HDFS 体系结构
前面我们掌握了 HDFS 的基本使用,下面我们来详细分析一下 HDFS 深层次的内容
HDFS 支 持 主 从 结 构 , 主 节 点 称 为 NameNode , 是 因 为 主 节 点 上 运 行 的 有 NameNode 进 程 ,
NameNode 支持多个,目前我们的集群中只配置了一个
从节点称为 DataNode ,是因为从节点上面运行的有 DataNode 进程, DataNode 支持多个,目前我们的
集群中有两个
HDFS 中还包含一个 SecondaryNameNode 进程,这个进程从字面意思上看像是第二个 NameNode 的意
思,其实不是,一会我们会详细分析。
在这大家可以这样理解:
公司 BOSS NameNode
秘书: SecondaryNameNode
员工: DataNode
接着看一下这张图,这就是 HDFS 的体系结构,这里面的 TCP RPC HTTP 表示是不同的网络通信方式,
通 过 这 张 图 是 想 加 深 大 家 对 HDFS 体 系 结 构 的 理 解 , 我 们 前 面 配 置 的 集 群 NameNode
SecondaryNameNode 进程在同一台机器上面,在这个图里面是把它们分开到多台机器中了。
NameNode 介绍
首先是 NameNode NameNode 是整个文件系统的管理节点
它主要维护着整个文件系统的文件目录树,文件 / 目录的信息 和 每个文件对应的数据块列表,并且还负责
接收用户的操作请求
(namenode所包含信息)
*文件 / 目录的信息:表示文件 / 目录的的一些基本信息,所有者 属组 修改时间 文件大小等信息
*每个文件对应的数据块列表:如果一个文件太大,那么在集群中存储的时候会对文件进行切割,这个 时候就类似于会给文件分成一块一块的,存储到不同机器上面。所以HDFS 还要记录一下一个文件到 底被分了多少块,每一块都在什么地方存储着

上传hdfs显示文件块信息,文件小的时候只有一块,默认切块是128Mb。

*接收用户的操作请求:其实我们在命令行使用 hdfs 操作的时候,是需要先和 namenode 通信 才能开 始去操作数据的。
Namenode包含哪些主要文件

这些文件所在的路径是由 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 中同名的参数。
那我们来看一下这个文件中的 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
进入到 /data/hadoop_repo/dfs/name 目录下
发现这个下面会有一个 current 目录,表示当前的意思,还有一个 in_use.lock 这个只是一个普通文件,
但是它其实有特殊的含义,你看他的文件名后缀值 lock 表示是锁的意思,文件名是 in_use 表示这个文件
现在正在使用,不允许你再启动 namenode
当我们启动 namonde 的时候 会判断这个目录下是否有 in_use.lock 这个相当于一把锁,如果没有的话,
才可以启动成功,启动成功之后就会加一把锁, 停止的时候会把这个锁去掉
[root@bigdata01 name]# cd /data/hadoop_repo/dfs/name
[root@bigdata01 name]# ll
total 8
drwxr-xr-x. 2 root root 4096 Apr 8 21:31 current
-rw-r--r--. 1 root root 14 Apr 8 20:30 in_use.lock
[root@bigdata01 name]# cd current
[root@bigdata01 current]# ll
total 4152
-rw-r--r--. 1 root root 42 Apr 7 22:17 edits_0000000000000000001-000000
-rw-r--r--. 1 root root 1048576 Apr 7 22:17 edits_0000000000000000003-000000
-rw-r--r--. 1 root root 42 Apr 7 22:22 edits_0000000000000000004-000000
-rw-r--r--. 1 root root 1048576 Apr 7 22:22 edits_0000000000000000006-000000
-rw-r--r--. 1 root root 42 Apr 8 14:53 edits_0000000000000000007-000000
-rw-r--r--. 1 root root 1644 Apr 8 15:53 edits_0000000000000000009-000000
-rw-r--r--. 1 root root 1523 Apr 8 16:53 edits_0000000000000000032-000000
-rw-r--r--. 1 root root 42 Apr 8 17:53 edits_0000000000000000052-000000
-rw-r--r--. 1 root root 1048576 Apr 8 17:53 edits_0000000000000000054-000000
-rw-r--r--. 1 root root 42 Apr 8 20:31 edits_0000000000000000055-000000
-rw-r--r--. 1 root root 523 Apr 8 21:31 edits_0000000000000000057-000000
-rw-r--r--. 1 root root 1048576 Apr 8 21:31 edits_inprogress_000000000000000
-rw-r--r--. 1 root root 652 Apr 8 20:31 fsimage_0000000000000000056
-rw-r--r--. 1 root root 62 Apr 8 20:31 fsimage_0000000000000000056.md5
-rw-r--r--. 1 root root 661 Apr 8 21:31 fsimage_0000000000000000065
-rw-r--r--. 1 root root 62 Apr 8 21:31 fsimage_0000000000000000065.md5
-rw-r--r--. 1 root root 3 Apr 8 21:31 seen_txid
-rw-r--r--. 1 root root 219 Apr 8 20:30 VERSION
里面有 edits 文件 和 fsimage 文件
fsimage 文件有两个文件名相同的,有一个后缀是 md5 md5 是一种加密算法,这个其实主要是为了做
md5 校验的,为了保证文件传输的过程中不出问题,相同内容的 md5 是一样的,所以后期如果我把这个
fsimage 和对应的 fsimage.md5 发给你 然后你根据 md5 fsimage 的内容进行加密,获取一个值 和
fsimage.md5 中的内容进行比较,如果一样,说明你接收到的文件就是完整的。
我们在网站下载一些软件的时候 也会有一些 md5 文件,方便验证下载的文件是否完整。
在这里可以把 fsimage 拆开 fs 是文件系统 fifilesystem image 是镜像
说明是文件系统镜像,就是给文件照了一个像,把文件的当前信息记录下来
我们可以看一下这个文件,这个文件需要使用特殊的命令进行查看
-i 输入文件 -o 输出文件
[root@bigdata01 current]# hdfs oiv -p XML -i fsimage_0000000000000000056 -o f
2020-04-08 22:23:32,851 INFO offlineImageViewer.FSImageHandler: Loading 4 str
2020-04-08 22:23:32,916 INFO namenode.FSDirectory: GLOBAL serial map: bits=29
2020-04-08 22:23:32,916 INFO namenode.FSDirectory: USER serial map: bits=24 m
2020-04-08 22:23:32,916 INFO namenode.FSDirectory: GROUP serial map: bits=24
2020-04-08 22:23:32,916 INFO namenode.FSDirectory: XATTR serial map: bits=24
里面最外层是一个 fsimage 标签,看里面的 inode 标签,
这个 inode 表示是 hdfs 中的每一个目录或者文件信息
例如这个:
<inode><id>16393</id><type>FILE</type><name>LICENSE.txt</name><replication>2<
</blocks>
<storagePolicyId>0</storagePolicyId></inode>
id :唯一编号
type :文件类型
replication :文件的副本数量
mtime :修改时间
atime :访问时间
preferredBlockSize :推荐每一个数据块的大小
permission :权限信息
blocks :包含多少数据块【文件被切成数据块】
block :内部的 id 表示是块 id genstamp 是一个唯一编号, numBytes 表示当前数据块的实际大小,
storagePolicyId 表示是数据的存储策略
这个文件中其实就维护了整个文件系统的文件目录树,文件 / 目录的元信息和每个文件对应的数据块列
表,所以说 fsimage 中存放了 hdfs 最核心的数据。
下面我们来看一下 edits 文件,这些文件在这称之为事务文件,为什么呢?
当我们上传一个文件的时候,上传一个 10G 的文件,假设传到 9G 的时候上传失败了,这个时候就需要重
新传,那 hdfs 怎么知道这个文件失败了呢?这个是在 edits 文件中记录的。
当我们上传大文件的时候,一个大文件会分为多个 block ,那么 edits 文件中就会记录这些 block 的上传状
态,只有当全部 block 都上传成功了以后,这个时候 edits 中才会记录这个文件上传成功了,那么我们执行
hdfs dfs -ls 的时候就能查到这个文件了,
所以当我们在 hdfs 中执行 ls 命令的时候,其实会查询 fsimage edits 中的内容
为什么会有这两个文件呢?
首先 , 我们固化的一些文件内容是存储在 fsimage 文件中,当前正在上传的文件信息是存储在 edits 文件
中。
这个时候我们来查看一下这个 edits 文件的内容,挑一个 edits 文件内容多一些的文件
[root@bigdata01 current]# hdfs oev -i edits_0000000000000000057-000000000000
分析生成的 edits.xml 文件,这个地方注意,可能有的 edits 文件生成的 edits.xml 为空,需要多试几个。
这个 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 :关闭上传操作
<RECORD>
<OPCODE>OP_ADD</OPCODE>
<DATA>
<TXID>58</TXID>
<LENGTH>0</LENGTH>
<INODEID>16396</INODEID>
<PATH>/user.txt</PATH>
<REPLICATION>3</REPLICATION>
<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>
<MODE>420</MODE>
</PERMISSION_STATUS>
</DATA>
</RECORD>
这里面的每一个 record 都有一个事务 id txid ,事务 id 是连续的,其实一个 put 操作会在 edits 文件中产生
很多的 record ,对应的就是很多步骤,这些步骤对我们是屏蔽的。
注意了,根据我们刚才的分析,我们所有对 hdfs 的增删改操作都会在 edits 文件中留下信息,那么 fsimage
文件中的内容是从哪来的?
其实是这样的, edits 文件会定期合并到 fsimage 文件中。
有同学可能有疑问了, edits 文件和 fsimage 文件中的内容是不一样的,这怎么能是合并出来的呢?
注意,这个其实是框架去做的,在合并的时候会对 edits 中的内容进行转换,生成新的内容,其实
edits 中保存的内容是不是太细了,单单一个上传操作就分为了好几步,其实上传成功之后,我们
只需要保存文件具体存储的 block 信息就行了把,所以在合并的时候其实是对 edits 中的内容进行了
精简。
他们具体合并的代码我们不用太过关注,但是我们要知道是那个进程去做的这个事情,
其实就是我们之前提到的 secondarynamenode
这个进程就是负责定期的把 edits 中的内容合并到 fsimage 中。他只做一件事,这是一个单独的进程,在实
际工作中部署的时候,也需要部署到一个单独的节点上面。
current 目录中还有一个 seen_txid 文件, HDFS format 之后是 0 ,它代表的是 namenode 里面的 edits_*
件的尾数 ,namenode 重启的时候,会按照 seen_txid 的数字,顺序从头跑 edits_0000001~ seen_txid
数字。如果根据对应的 seen_txid 无法加载到对应的文件, NameNode 进程将不会完成启动以保护数据一 致性。
[root@bigdata01 current]# cat seen_txid
66
最后这个 current 目录下面还有一个 VERSION 文件
[root@bigdata01 current]# cat VERSION
#Wed Apr 08 20:30:00 CST 2020
namespaceID=498554338
clusterID=CID-cc0792dd-a861-4a3f-9151-b0695e4c7e70
cTime=1586268855170
storageType=NAME_NODE
blockpoolID=BP-1517789416-192.168.182.100-1586268855170
layoutVersion=-65
这里面显示的集群的一些信息、当重新对 hdfs 格式化 之后,这里面的信息会变化。
之前我们说过 在使用 hdfs 的时候只格式化一次,不要格式化多次,为什么呢?
一会在讲 datanode 的时候会详细解释、
最后做一个总结:
fsimage: 元数据镜像文件,存储某一时刻 NameNode 内存中的元数据信息,就类似是定时做了一个快照
操作。【这里的元数据信息是指文件目录树、文件 / 目录的信息、每个文件对应的数据块列表】
edits: 操作日志文件【事务文件】,这里面会实时记录用户的所有操作
seen_txid: 是存放 transactionId 的文件, format 之后是 0 ,它代表的是 namenode 里面的 edits_* 文件的
尾数 ,namenode 重启的时候,会按照 seen_txid 的数字,顺序从头跑 edits_0000001~ seen_txid 的数
字。如果根据对应的 seen_txid 无法加载到对应的文件, NameNode 进程将不会完成启动以保护数据一致
性。
VERSION: 保存了集群的版本信息
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大数据开发工程师-宋权

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值