HDFS的集群信息

2023-02-28 14:57:16 浏览数 (2)

【概述】


我们都知道整个hdfs由nn zkfc,dn,jn组成,这些可能运行在不同节点上的组件能组成一个集群,其中包含了共同的集群信息,并且各自将集群信息持久化存储到了本地,这个文件就是VERSION文件。本文就来聊聊VERSION文件的相关内容。

【各组件中的VERSION文件】


1. nn中的version文件

version文件的存储位置及具体内容如下:

代码语言:javascript复制
# /home/hncscwc/data/hadoop/dfs/nn 为配置项 "dfs.namenode.name.dir" 指定的值

cat /home/hncscwc/data/hadoop/dfs/nn/current/VERSION

#Fri Mar 11 08:52:21 CST 2022
namespaceID=161164106
clusterID=CID-78f2e32d-93e0-4aeb-84ef-c84fa92520e0
cTime=1646959941280
storageType=NAME_NODE
blockpoolID=BP-1219799146-172.168.3.21-16446959941279
layoutVersion=-63

文件仅在首次格式化时写入,其中namespaceID,clusterID,blockpoolID,cTime均在这个时候生成。

2. jn中的version文件

文件存储位置与内容:

代码语言:javascript复制
# /home/hncscwc/data/hadoop/dfs/journal 为配置项 "dfs.journalnode.edits.dir" 指定的值
# hdfsHACluster 为配置项 "dfs.nameservices" 指定的值

cat /home/hncscwc/data/hadoop/dfs/journal/hdfsHACluster/current/VERSION

#Fri Mar 11 08:52:21 CST 2022

namespaceID=161164106
clusterID=CID-78f2e32d-93e0-4aeb-84ef-c84fa92520e0
cTime=1646959941280
storageType=JOURNAL_NODE
layoutVersion=-63

同样,文件仅在NN格式化命令执行时创建并写入。其中namespaceID,clusterID,cTime在NN格式化命令中传递,即具体值来自于NN,并且保持一致。

格式化之后,nn会通过rpc请求进行editlog的相关操作,每次rpc请求中都会携带namespaceID,clusterID。如果与jn本地保存的不一致,jn会返回错误。

3. dn中的version文件

dn中会有两个位置分别存放不同的version文件。

一个是数据存储目录下的version,一个是数据存储目录BP(BlockPool)目录下的version文件。

数据存储目录下的version文件,具体存储位置与内容为:

代码语言:javascript复制
# /home/hncscwc/data/hadoop/dfs/dn 为配置项 "dfs.datanode.data.dir" 指定的值
# 如果指定多个目录,则在每个目录下均会创建VERSION文件

cat /home/hncscwc/data/hadoop/dfs/dn/current/VERSION

#Fri Mar 11 08:54:51 CST 2022
storageID=DS-2d782d28-48fe-4808-9648-a20992700e34
clusterID=CID-78f2e32d-93e0-4aeb-84ef-c84fa92520e0
cTime=0
datanodeUuid=78434f35-7229-49d2-b225-db2e11b6eb6b
storageType=DATA_NODE
layoutVersion=-57

其中clusterID从NN获取得到;storageID为存储目录的唯一ID,即每个存储目录都有一个唯一ID。datanodeUudi为dn的唯一uuid,在每个这样的version文件中,其值都是一样的。

数据存储目录中BP目录下的version文件,具体存储位置与内容为:

代码语言:javascript复制
# BP-1219799146-172.168.3.21-1646959941279 为nn的BlockPoolID

cat /home/hncscwc/data/hadoop/dfs/dn/current/BP-1219799146-172.168.3.21-1646959941279/current/VERSION

#Fri Mar 11 08:54:51 CST 2022
namespaceID=161164106
cTime=1646959941280
blockpoolID=BP-1219799146-172.168.3.21-1646959941279
layoutVersion=-57

其中namespaceID,cTime,blockpoolID均从nn获取得到。

从上面可以知道,nn格式化后生成了namespaceID,cTime,clusterID,blockpoolID然后同步给了jn,dn。

那dn中的uuid,storageID又是怎么来的,如果新添加一个目录,是否会具有同样的信息,如果不同卷目录中的uuid不一致,又会怎样?我们继续来看看dn启动流程。

【dn启动流程】


dn启动与之相关的流程包括:

1. 向nn建立连接,并请求命名空间信息

2. nn响应dn的请求,并回复dn,在响应内容中包括namespaceID,clusterID,blockpoolID,cTime以及自身状态(Active或Standby)

3. dn收到响应后,进行存储的初始化,具体步骤包括:

1)读取各个存储路径中的VERSION文件

如果存储目录中没有这个文件(可能是首次启动,也可能是新添加的存储卷目录),则进行格式化动作。即写VERSION文件(仅写入数据存储目录下的VERSION);如果有则读取该文件中的具体内容,并与请求响应中的字段比较,如果namespaceID,clusterID不一致则返回错误。

2)初始化dn的uuid

在上一步骤中,以读取到的第一个非空的DatanodeUuid作为dn的uuid,如果均为空(首次启动),则生成一个uuid,然后再将uuid重新写入各个存储卷目录下的VERSION中。

也就是说,当DN首次启动时,初始化动作会写两次VERSION文件,第一次没有DatanodeUuid,第二次会包含DatanodeUuid字段。

另外,非首次启动(即再次重启)时,由于会依次读取每个存储卷目录下的VERSION文件,并将第一个非空的DatanodeUuid作为dn的uuid,如果后续存储卷目录VERSION文件中的uuid与之前的不一致,则会抛异常退出。

3)加载blockpool的信息

读取各个BlockPool卷目录下的VERSION文件,如果没有该文件则进行格式化;有则比对namespaceID,BlockPoolID,cTime是否一致(不一致会抛异常退出),如有必要则更新该文件(通常是升级时)。

4. 向nn进行注册

向nn进行注册,注册时会携带datanode的uuid、rpc通信的ip地址,端口、数据传输的ip地址,端口等信息。nn收到请求后以DatanodeUuid作为唯一key,记录dn的信息并进行管理。

读到这里,我们知道了datanode的uuid是如何产生并在多个存储卷目录同步了,以及再次重启时如何沿用之前产生的uuid。

【新增存储卷目录】


考虑这么一种场景,停止dn后,在配置文件中新增了存储卷目录,dn再次启动后,这个新增的存储卷目录中VERSION文件会是怎样的?

这里需要分两种情况来分析:

  • 新增的卷目录放在配置条目的中间或最后(非配置条目的第一个) 结合上面的流程,可以看出,在进行存储的初始化动作时,因为该目录为空,所以会进行格式化动作,又由于之前读取了其他目录中的VERSION文件,并获取到了DatanodeUuid,因此格式化写入的VERSION中会包含DatanodeUuid。
  • 新增的卷目录放在配置条目的第一个 同样会进行格式化动作,但因为该存储卷目录为读取的第一个目录,并且没有VERSION文件,因此此时DatanodeUuid为空。所以格式化写入的VERSION文件中也就没有uuid。在此之后加载其他存储卷目录的VERSION文件,得到了DatanodeUuid,并且非空,因此不会生成新的uuid并再次写入VERSION文件中。 最终新增的这个存储卷目录的VERSION文件中也就没有了DatanodeUuid字段。

例如:首次启动时,仅配置"/home/hncscwc/data/dfs/dn",停止dn后,新增一个存储卷目录"/home/hncscwc/data1/dfs/dn",并放在配置项的最前面,即"/home/hncscwc/data1/dfs/dn,/home/hncscwc/data/dfs/dn"。此后启动dn,会发现 "/home/hncscwc/data1/dfs/dn"下的VERSION文件中没有DatanodeUuid字段。

代码语言:javascript复制
[root@hncscwc dfs]# cat /home/hncscwc/data1/dfs/dn/current/VERSION
#Fri Mar 11 08:54:51 CST 2022
storageID=DS-2d782d28-48fe-4804-9648-a20992700e34
clusterID=CID-78f2e32d-93e0-4aeb-84ef-c84fa92520e0
cTime=0
storageType=DATA_NODE
layoutVersion=-57

[root@hncscwc dfs]# cat /home/hncscwc/data/dfs/dn/current/VERSION
#Fri Mar 11 08:54:51 CST 2022
storageID=DS-2d782d28-48fe-4804-9648-a20992700e34
clusterID=CID-78f2e32d-93e0-4aeb-84ef-c84fa92520e0
cTime=0
datanodeUuid=78434fe5-7229-49d2-b225-db2e11b6eb6b
storageType=DATA_NODE
layoutVersion=-57

在这种情况下,虽然VERSION文件中没有datanodeUuid,但不会影响正常使用。

【总结】


小结一下,本文主要介绍了hdfs各个组件中VERSION文件中存储的集群信息,以及dn的唯一id是如何产生并保持不变的,可以扩展的一些点是:如果不小心对active的nn进行了格式化并进行了重启,如何进行集群的恢复;如果存储卷目录中的id不一致了应当如何恢复等。

0 人点赞