紧接着上一节HMaster的构建完成。接下来会调用HMaster调用master.start(),master.join()。
  由HMaster的继承关系,很明显,他是Runnable的子类。也就是说,在调用其start方法时,run方法被调用。


 让我们来到super.run的调用。来到这里一看,内容很多,各位同学不需要慌,让我们再进入preRegistrationInitialization一探究竟。

  来到preRegistrationInitialization,各位同学可能有所迷惑,为什么比较关键的方法有三个,而我在这里之框选了一个呢。原因很简单,在HMaster启动期间,他还运行不到下面去。

  接着,让我们一探究竟。看了两个block方法,各位同学可能以为是在这里阻塞的,然而并不是,真正的等待是在下图框选的waitForMasterActive。

  来到waitForMasterActive(由于在这里我们研究的是HMaster,因此,这里的方法应该是HMaster.waitForMasterActive)。这个方法虽然比较短,确实困扰了我很久的一个地方。下图框选的地方获得的默认值为false,而isStopped与isAborted的获得的初始值都是false。因此,HMaster在启动时,包括启动后,都一直在这里轮询等待。因为启动后只是将activeMaster置位false。在tablesOnMaster默认值为false的情况下,并没有任何作用。也就是说只有后面的两个值发生变动后,这种等待才会被打破。分析到这里,各位同学应该可以安心的分析那个守护线程了。

  让我们来到HMaster.startActiveMasterManager方法中,首先通过调用activeMasterManager.blockUntilBecomingActiveMaster确定当前Master为ActiveMaster,然后再调用finishActiveMasterInitialization方法。这里我们只分析ActiveMaster的流程,并不介绍StandyMaster。在blockUntilBecomingActiveMaster方法中的调用并不是很难,感兴趣的同学可以简单。在activeMasterManager.blockUntilBecomingActiveMaster。这里我们把重点放在finishActiveMasterInitialization。

  接下来让我们来到finishActiveMasterInitialization方法。
  这个方法是出奇的长,在这里,我们还是按照一张张的来介绍,以避免大家到后面会忘记前面的。 首先我们分析第一个方法initializeMemStoreChunkCreator,其实这里只是初始化了
  首先我们分析第一个方法initializeMemStoreChunkCreator,其实这里只是初始化了

 首先我们分析第一个方法initializeMemStoreChunkCreator,其实这里只是初始化了
  首先我们分析第一个方法initializeMemStoreChunkCreator,其实这里只是初始化了

  来到ChunkCreator的构造方法,我们可以看到其主要调用了initializePools方法

  在initializePool方法中,主要构建了MemStoreChunkPool,并且将其加入heapMemoryManager的管理之中。而在构建MemStoreChunkPool的过程中,创建了Chunk,并将其放入reclaimedChunks中,初始化并开始周期调用统计线程StatisticsThread,将其内存数据打印出来。这里设计到HBase的内存管理,我将在后续的章节中专门拿出一讲来为大家讲解。这里就介绍到这。

  接着来到MasterFileSystem的构造方法中,这里主要获得了fs与walFs。

  接下来,让我们来到createServerManager方法中,在这里首先构建了clusterConnection对象,其中主要构建了ShortCircuitingClusterConnection与MetaTableLocator。这里简单略过,详细内容请看我的另外一篇博文《HBase之setupClusterConnection流程》。然后构造了ServerManager,他就是HMaster用于管理region servers信息的类。

  再接下来,来到createProcedureExecutor,这是一个重量级的方法。

  让我们首先来到MasterProcedureEnv的构造方法,这个构造方法看似简单,却同时构造了两个重要的对象。RSProcedureDispatcher、MasterProcedureScheduler。其中的RSProcedureDispatcher负责HMaster向RegionServer的Procedure调用,而MasterProcedureScheduler负责的是Master自身的Procedure的调用。

  需要注意的是,在MasterProcedureScheduler中有几个队列的成员变量,他们的作用就是保存将要调用procedure,然后由具体线程调用。

  接下来是WALProcedureStore,这里主要传入了一个LeaseRecovery对象,而他的实际类型是MasterProcedureEnv.WALStoreLeaseRecovery,他的主要作用是对hdfs的文件恢复租约。

  在ProcedureExecutor的构造方法中只是对其成员变量的赋值,并没有什么比较重要的方法。不过,在这里我们需要记住,在这里传入的store类型为WALProcedureStore,scheduler类型为MasterProcedureScheduler。

  接下来来到WALProcedureStore.start方法。在这里,根据传入的线程数初始化了Slot数量,并且启动WALProcedureStoreSyncThread线程用于调用syncLoop方法。这里就简单略过,我们先继续后面的流程。

  下面,来到ProcedureExecutor.init方法。这里将WorkerThread,添加到workerThread成员变量中。接着调用store.recoverLease,恢复相关文件的租约。然后调用scheduler.start,将scheduler中的running置位true。 这里简单看一下WorkThread中的run方法。这里的流程在我的博文《hbase之InitMetaProcedure流程》中有相关介绍,感兴趣的大家可以去看一下。
  这里简单看一下WorkThread中的run方法。这里的流程在我的博文《hbase之InitMetaProcedure流程》中有相关介绍,感兴趣的大家可以去看一下。
 这里简单看一下WorkThread中的run方法。这里的流程在我的博文《hbase之InitMetaProcedure流程》中有相关介绍,感兴趣的大家可以去看一下。
  这里简单看一下WorkThread中的run方法。这里的流程在我的博文《hbase之InitMetaProcedure流程》中有相关介绍,感兴趣的大家可以去看一下。
  接下来来到finishActiveMasterInitialization的第二张图。
  首先创建了AssignmentManager,AssignmentManager的作用就是用来操作assign/unassign。然后调用了AssignmentManager.start方法。关于AssignmentManager的相关调用我在博文《HBase之AssignmentManager相关调用》中有介绍,感兴趣的同学可以去看一下。接下来构造并调用了RegionServerTracker,用于通过ZK跟踪在线RegionServers。

  然后调用了initializeZKBasedSystemTrackers方法,在这里初始化了所有基于ZK的系统跟踪器。尽管如此,还是有些方法值得我们探究。首先介绍各种Tracker,这些都是直接或间接继承自ZKListener,或者将传入的ZK保存到自己的成员变量中用来实现对自己所在ZK目录中状态的监听。

  然后来到LoadBalancerFactory.getLoadBalancer方法,这里调用ReflectionUtils.newInstance通过反射创建了StochasticLoadBalancer,同时由于StochasticLoadBalancer实现了Configurable接口。因此在通过反射创建了StochasticLoadBalancer,紧接着变调用了setConf方法。在StochasticLoadBalancer.setConf中调用了构造了各种CostFunction。在这里我们简单略过 。
。

  接下来来到方法的后面,这里构建了SnapshotManager、MasterFlushTableProcedureManager(二者都继承自抽象类ProcedureManagerHost)并且注册到创建的MasterProcedureManagerHost对象中。接着调用了MasterProcedureManagerHost.initialize,调用了刚刚注册进来的两个对象initialize方法。

  接下来来到finishActiveMasterInitialization的下一张图。如果已经不是第一次调用,那么就不会调用框二中所选的内容,不过,感兴趣的同学可以去看我的博客《hbase之InitMetaProcedure流程》。这里我们只介绍框一与框三中的内容。

