HDFS集群启动过程详解

时间:2021-04-13 04:33:13

HDFS的启动过程和关闭过程都经过脚本进行了封装,只需要执行start-all.sh和stop-all.sh就可以。操作较简单。下面针对启动阶段的原理和详细过程进行说明,对关闭过程目前还没有调研,所以暂缺。

HDFS的启动分三步骤:

  • l  第一步,启动namenode;
  • l  第二步,启动datanode;
  • l  第三步,启动Secondary namenode。

下面一一描述。


第一步,启动namenode

1.      初始化过程:获取一些必要的参数值,初始化FSImage,FSNameSystem,NameNode等类。这个过程在很多启动描述中都被忽略,不是很重要。需要注意的是,这个过程在recover, format和finalize几种启动时的操作略有不同。

2.      构造Configuration对象:该对象的具体创建过程不是很清楚,只知道其中包含了一些配置信息的加载。所以应该是和配置信息有关的。

3.      构造namenode对象:这是namenode启动最重要的阶段。Namenode对象主要包括两部分,一个是Server类成员对象,第二个是FSNameSystem类成员对象。

a)        Server成员的构造:Server是namenode用于与client和datanode之间进行RPC通信的服务端。Namenode中有一个或两个Server成员,由不同的Hadoop版本决定,两个的时候分别负责和client和Datanode的通信。

b)        FSNameSystem的构造:Server构造完成后,调用namenode的initialize方法,接下来的操作都在这个方法中完成。先是构造FSNameSystem对象,FSNameSystem对象就是namenode上元数据的真正的存放数据结构。它主要包括两部分,第一部分是一些数据结构,包括

  • l  blocksMap:map,保存数据块block相关的映射关系,包括文件与块,块与datanode的映射等。
  • l  curruptReplicasMap:保存所有损坏的块,所有副本都损坏。
  • l  datanodeMap:曾近连接过的所有的datanode,是全集。
  • l  recentInvalidateSets:最近失效的block。
  • l  excessReplicateMap:机器与机器上多余的block的映射,这些block等待被删除。
  • l  Heartbeats:当前发送心跳包的datanode,也就是alive的datanode。

第二部分是FSDirectory对象,这里存放着文件系统的层次结构。

FSNameSystem对象构造的过程,首先初始化blocksMap等数据结构,然后加载fsimage文件到类FSImage中,然后读取edits文件,利用fsimage和edits构造文件系统层次结构。

Q:fsimage文件如何加载?

之所以要记录fsimage的加载过程,是因为fsimage是启动过程中耗时较大的一个步骤,便于后续的研究。

1.      从fsimage逐行读入目录和文件信息;

2.      初始化元数据信息;

3.      构造namespace名字空间镜像;

4.      读取block信息,并填充到BlocksMap中。


c)        启动后台守护进程: 启动一系列的后台守护进程,下面是简单描述。

  • l  PendingReplicaitonBlocks$PendingReplicationMonitor: 监控block的copy过程
  • l  FSNamesystem$HeartbeatMonitor,心跳包的检测
  • l  FSNamesystem$ReplicationMonitor: 监控复本数量,如果不足,就copy。
  • l  LeaseManager$Monitor:控制写请求,文件不能同时多人写。
  • l  DecommissionManager$Monitor:处理数据节点的退役

d)       启动RPC Server服务和web服务:Namenode和datanode以及client之间的通信都是通过RPC方式的,下面是简单描述RPC的通信过程。

Listener获取来自client或者datanode的请求,为该请求创建listener的一个子类reader的对象。并创建connection类,加入到connectionList中。处理connection对象,reader常见call对象,然后加入到callList中。再取出,处理执行,然后将得到的response加入到ResponseQueue中,从RQ中返回给client或者datanode,并关闭连接。

4.      进入安全模式:namenode对象构造完成后,namenode进入安全模式,在这个阶段等待datanode的注册。为什么一定要在第3步以后呢,我觉得是因为只有RPC启动后,datanode才能与namenode进行通信,才能注册。

5.      退出安全模式,启动成功:在等待datanode注册的过程中,namenode有一个timeout设置,等待超时后,namenode就会默认已经没有要注册的datanode了,离开安全模式。

namenode正式启动。


第二步,启动datanode

Datanode的启动包括两个步骤,初始化过程和启动过程

1.       初始化过程:

a)        初始化过程的第一步,是Datanode获取并设置各种配置信息。我认为datanode整理自己的block信息并进行封装,等待发送给namenode就是在这一步进行的。

b)        然后向namenode发送RPC请求,从namenode获取namespaceID, version以及StorageID等待信息,然后再做一系列的初始化操作。

2.       Datanode启动:

a)        首先是datanode向namenode注册。

Datanode通过DatanodeProtocal协议进行注册,向namenode发送注册信息,包括服务地址,信息查询端口,客户端访问端口以及datanodeID等,还包括block_report块数据;

namenode接收到信息后(这时的namenode处在安全模式中,等待注册),先检验datanode的版本,然后把datanode交给FSNameSystem处理;

FSNameSystem先验证该datanode是否被允许挂载(通过dfs.hosts列表验证),然后把datanode数据映射到元数据中,这里主要是获取block_report块与datanode的映射关系,添加到BlocksMap中[hx1] ,然后再把这个datanode添加到heartsbeats中进行监控。最后返回注册信息。

b)        启动datanode线程。Datanode线程实际上是在不断调用offerService,周期性向namenode发送block_Report和heartbeats,同时接受namenode的指令。

Datanode启动完成。


第三步,Secondary namenode的启动

Secondary namenode的过程没有细看。分析一下,觉得其实它的启动应该是有两部分的,首先与namenode建立连接,注册到namenode,并且从namenode同步当前的fsimage,edits等文件信息;第二部分,是启动secondary namenode上用于轮训的进程,定期执行检查点的创建操作。


HDFS启动完成。


HDFS启动耗时

HDFS启动最耗时的步骤,是fsimage加载的过程和datanode注册时block_report载入的过程。具体的情况需要结合源码以及简单的测试来确定。