NameNode启动分析


概述

本次分析的源码版本为hadoop-2.6.0。HDFS源码分析思路:HDFS服务的每个角色都存在一个进程,即有一个主类存在一个man方法,这就是角色的入口。这里以NameNode分析方法举例:分析NameNode源码时切忌深入到每一个类、每一个方法,应该先对NameNode源码主干进行分析,对该源码有一个宏观认识,然后再进行详细分析。这里我们应该理清楚NamoNode启动的大体步骤,对NameNode 所做的工作,每一个角色提供什么样的服务,可以通过分析该角色的每一个线程。然后分析线程的run()方法来了解该角色实现的具体业务。这样分析源码的思路就比较清晰了。本文主要分析NameNode启动,NameNode的入口:org.apache.hadoop.hdfs.server.namenode.NameNode.main()。

NameNode启动步骤

NameNode启动的大多数步骤都在initialize()方法中完成。

NameNode启动分析_第1张图片

1、初始化度量器系统,会启动Timer for ’NameNode‘ metrics system线程。

2、pauseMonitor.start():启动Jvm暂停监控,此功能由JvmPauseMonitor 线程完成。

3、startHttpServer():判断是否为NameNode角色,如果为NameNode则启动HttpServer服务器.接收外部发过来的请求,默认监听50070。

4、loadNamesystem():载入FSNamesystem,从磁盘加载fsimage和edits进行内存合并。

5、createRpcServer():创建RpcServer 包括ClientRpcServer和ServerRpcServer。ClientRpcServer用于接收客户端请求,ServerRpcServer用于接收DataNode、SecondaryNameNode等内部节点之间的通信请求。

6、startCommonServices():启动公共服务,包含FSNamesystem服务启动、检查磁盘是否有100m来写入edits log、检查是否进入安全模式、BlockManager激活、RpcServer启动。

7、NameNode.join():等待rcp server停止。

到此NameNode启动工作已经完成。接下来NameNode的各项服务个工作就由已经启动的线程承担。下文讲剖析NameNode启动后的各个具体的线程、每个线程主要的作用是做什么。

NameNode启动步骤详细分析

初始化度量器系统

调用流程:DefaultMetricsSystem.initialize()

                        --->MetricsSystemImpl.init()

                                    --->MetricsSystemImpl.start()

                                            --->MetricsSystemImpl.startTimer()

                                                --->MetricsSystemImpl.onTimerEvent()

DefaultMetricsSystem通过枚举实现单例模式,startTimer()方法启动一个定时器,每隔10秒执行一次onTimerEvent()方法。onTimeEvent方法通过sampleMetrics()方法获取指标信息,并通过publishMetrics()方法发送至每个sink。


Jvm暂停监控

调用流程:pauseMonitor.start()

                        --->monitorThread.start()

                            --->Monitor.run()


NameNode启动分析_第2张图片

HttpServer启动

载入FSNamesystem

RpcServer创建

公共服务启动



NameNode启动后的线程概览

1、main:程序主线程。

2、Finalizer:在main线程之后创建的,其优先级为10,主要用于在垃圾收集前,调用对象的finalize()方法。详细解释可以参考 JVM运行基本线程解析。

3、Reference Handler:它主要用于处理引用对象本身(软引用、弱引用、虚引用)的垃圾回收问题。

4、Signal Dispatcher:接收外部参数然后分发到各个不同的模块处理命令,并且返回处理结果。signal dispather线程是在第一次接收外部jvm命令时,进行初始化工作。

5、Timer for ’NameNode‘ metrics system:NameNode度量器系统线程。执行DefaultMetricsSystem.initialize("NameNode") 时启动。

6、JvmPauseMonitor$Monitor:Jvm暂停监控线程,执行pauseMonitor.start()时启动。

7、pool-1-thread-1: jetty内部线程,启动http server时创建 。执行startHttpServer(final Configuration conf) 代码时创建,最终在httpServer = builder.build();时创建并启动。

8、时间戳@qtp-932257672-0@2406: jetty内部线程,启动http server时创建 jetty内部线程 执行startHttpServer(final Configuration conf) 代码创建。

9、时间戳@qtp-932257672-1 - Acceptor0 HttpServer2$SelectChannelConnectorWithSafeStartup@account.jetbrains.com:50070@2407: jetty内部线程,启动http server时创建 执行startHttpServer(final Configuration conf) 代码创建。

10、Time-0:Jetty内部线程,启动Http Server时创建。执行startHttpServer(final Configuration conf) 代码时创建 最终在httpServer.start()时创建。

11、IPC Server idle connection scanner for port 9000@3804:RPC线程,会监听9000端口,执行createRpcServer时启动。

12、Socket Reader #1 for port 9000@3802:执行createRpcServer时启动。

13、BlockManager$ReplicationMonitor@70a36a66@4009:startCommonServices()---->blockManager.activate()时启动。

14、HeartbeatManager$Monitor@42f8285e@4008:执行startCommonServices()---->blockManager.activate()启动。

15、PendingReplicationBlocks$PendingReplicationMonitor@3bc735b3@4004:执行startCommonServices()---->blockManager.activate()启动。

16、DecommissionManager$Monitor@757529a4@4007:执行startCommonServices()---->blockManager.activate()启动。

17、process reaper@3930:执行startCommonServices()---->blockManager.activate()启动(后面会消失)

18、StorageInfoMonitor@4010:执行startCommonServices()---->blockManager.activate()启动。

19~28、IPC Server handler (0-9) on 9000:RPC 处理任务线程,执行startCommonServices()--->rpcServer.start();时启动。

29、IPC Server listener on 9000:RPC监听线程,执行startCommonServices()--->rpcServer.start();时启动。

30、IPC Server Responder:RPC请求响应线程,执行startCommonServices()--->rpcServer.start();时启动。

31、FSNamesystem$NameNodeEditLogRoller@14bae047@4174:在NameNode()--->state.enterState(haContext);启动。

32、FSNamesystem$NameNodeResourceMonitor@5c089b2f@4172:在NameNode()--->state.enterState(haContext);启动。

33、FSNamesystem$LazyPersistFileScrubber@66908383@4176:在NameNode()--->state.enterState(haContext);启动。

34、LeaseManager$Monitor@6ef7623@4170:在NameNode()--->state.enterState(haContext);启动。

35、CacheReplicationMonitor(221551064)@4178:在NameNode()--->state.enterState(haContext);启动。

到此NameNode 所有线程已经启动完成,接下来分析每个线程的具体业务逻辑

NameNode启动完成后线程代码解析

你可能感兴趣的:(NameNode启动分析)