首先是加载配置文件,创建了Configuration对象,通过addHbaseResources加载了hbase-site.xml
/**
之后通过HMasterCommandLine对象开始加载HMaster(HMasterCommandLine中会对启动参数做一些处理,目前的启动参数之后start),所以会进入到startMaster方法中
private
因为是采用单机启动的方式,所以HMaster和HResionServer都会运行到同一个jvm中,会分别启动两个线程启动HMaster和HResionServer。并且if(LocalHBaseCluster.isLocal(conf))判断为true,进入到该分支中。
![94f256c814c874070042effc4f096565.png](https://img-blog.csdnimg.cn/img_convert/94f256c814c874070042effc4f096565.png)
hbase依赖于zookeeper,所以单机版需要先启动内置zookeeper,内置zookeeper如何启动不详细说明。
![5dfa8381cde9b1bf64927319d113b094.png](https://img-blog.csdnimg.cn/img_convert/5dfa8381cde9b1bf64927319d113b094.png)
查看日志输出,可以看到zookeeper的环境信息以及启动成功日志输出
![eca835121fd31ffb65e65f7419c56a44.png](https://img-blog.csdnimg.cn/img_convert/eca835121fd31ffb65e65f7419c56a44.png)
启动zookeeper成功后,会更新一些配置,然后初始化LocalHBaseCluster,在LocalHBaseCluster对象的构造函数中,会生成HMaster和HRegionServer这两个重量级对象,接下来看看这两个对象是如何生成的。
public
通过注释可以得知,是通过addMaster方法来构造HMaster对象的,进入addMaster方法
public
这里通过createMasterThread创建了MasterThread 线程,并添加到masterThreads list中,看看createMasterThread中做了哪些操作。
public
终于找到了构造HMaster对象的代码(HRegionServer同理),获取HMaster.class,并通过反射的方式构造HMaster对象,传入conf配置。接下来看看HMaster的构造方法
/**
通过注释大概了解到了先初始化了RPC 服务,然后连接zookeeper,之后的初始化是在run方法中进行的。以便可以运行在HMaster自己的线程中。接下来查看HMaster的初始化过程。
this
获取配置,取消master的主缓存块(为啥?block cache的作用?)设置短路读取?作用未知?
/**
接下来要初始化RPC服务了,hostname为本机名字,端口是0(?为啥是0),设置与其他服务端的通信重试次数setServerSideHConnectionRetries。之后开始初始化RpcServer对象,通过该对象进行RPC服务。通过上述代码可以得出,先初始化FifoRpcScheduler对象。
看看FifoRpcScheduler对象的初始化过程和作用
/**
通过注释猜测该对象是将请求按顺序进行调度,该构造函数初始了两个属性,到时候是线程池的属性handlerCount = 30以及maxQueueLength = 300。之后就是构造RpcServer对象
先看看RpcServer的注释,看看该类的具体作用
/**
从上述注释可以看到,这个是PRC服务端,并使用protobuf 协议进行通信。该服务端有一个Listener 对象接收请求,并负载调用reader线程(默认10个线程)进行读处理,reader 线程注册到java nio 的Selector服务(目前新版hbase采用netty,不直接使用java原生nio接口),读取数据并通过Call进行解析,最终通过scheduler 处理。具体请求过程后面再看看。
接下来看看RpcServer对象的构造过程
/**
一开始都是初始化一些配置化信息,重点是 listener = new Listener(name),生成Listener对象,主要是构造了一个java nio的服务端。
public
查看Listener的代码,就是一些java nio的代码,其中关键的是生成了一个长度为10的readers 数组,并通过线程池readPool 进行管理。
Reader
Reader构造函数中打开了一个选择器,run函数中调用了doRunLoop()
private
从selector中获取就绪的通道,进行读处理。但是,目前还没有通过注册到reader的选择器中。所以我们接下来继续看RPCServer的代码。接下来另外一行关键的代码是responder = new Responder(),该方法生成Responder对象处理将客户端的RPC请求的回应
Responder
构造函数同样也是打开了一个Selector选择器
private
主方法中将response写回给channel。目前来看,reader处理读请求,Responder将请求的处理结果写回给客户端。最后,是初始化FifoRpcScheduler调度器。
@Override
但是该方法体为空,没有任务操作。到这里,最终完成RpcServer对象的初始化。之后便开始往zookeeper注册信息了。
/**
连接zookeeper,然后创建node,zookeeper各个node如下所示:
baseZNode
跟zookeeper连接完并创建节点后,要开启启动rpcServer, 通过this.rpcServer.startThreads()来让rpcServer开启服务。
/**
其实就是启动responder、listener以及scheduler,但目前还不允许响应请求。
this
之后便是生成MetricsMaster对象维护HMaster各种统计信息和JvmPauseMonitor对jvm的停止进行监控。
至此,HMaster初始化完毕。