HBase的master server具体实现是HMaster。它提供了面向Client的HMasterInterface和面向region server的HMasterRegionInterface的实现。
下面是它的组件介绍:
InfoServer
展示信息的组件。这是一个web server,响应你访问http://MasterHost:60010的http请求,它本质是一个Jetty web server。
ZooKeeperWatcher
zookeeper的观察者。所有需要获知与处理ZNode状态变化的组件都需要在它上面注册ZooKeeperListener。同时它还提供了在zookeeper上操作节点的能力,通过获取其内部的RecoverableZooKeeper对象来进行操作。
ActiveMasterManager
active master的管理对象。它主要做的事就是监听zookeeper上master znode的变化。一旦它发现当前的active master unavailable(也就是 master znode被删除了),那么它会竞争,使当前master成为新的active master。
在master启动的时候会调用其blockUntilBecomingActiveMaster方法,试图成为集群的active master。失败的话,master的启动会阻塞在这个方法上,直到集群停止或者是当前active master unavailable,那么它会被唤醒做新的竞争。
RegionServerTracker
跟踪online region server的状态通过zookeeper,并做相应处理。如果某个RS znode被删除了,那么它会通过ServerManager去终止这个RS,并移出online servers列表。
特别的,在它准备expire这个RS的时候,会先通过ServerManager判断这个RS是否在线,如果不在线则不做exprire,也不移出列表,仅仅是打出一条warn log。我猜这样做的目的是:既然RS不在线,我也无法给它下达关闭命令,说不定过一会这个RS恢复正常又上线了,又重新在zookeeper里建立znode。但这样做我觉得有一个问题,万一这个RS永远也恢复不了呢,那online servers列表里不是会遗留一个offline RS。
DrainingServerTracker
跟踪draining region server状态,draining RS 就是不应该再获得更多region的RS。
RpcServer
提供RPC服务的组件。具体服务由RpcEngine来支持,而引擎的实现是WritableRpcEngine。在0.96版本之后HBase引入了protocol buffer,RPC引擎的实现也被替换了。
MasterFileSystem
抽象了Master对底层文件系统的操作。包括split log,检查文件系统状态等。
ServerManager
管理region server。维护在线和离线的server列表,同时处理RS的startup和shutdown等。RS启动之后会报告给它,它会检测时钟偏差在master和RS之间以及是否已经存在相同的HostPort的RS。同时还会检查这个RS是否在dead list里,防止这个RS因为快速恢复但是已经在expiration流程中的问题。
RS的负载信息也会report给它,关闭和打开region的也是通过它完成。
AssignmentManager
主要工作就是region assign。同时维护region state,比如它通过zookeeper知晓一个split已完成事件,那么它会更新相关region的状态。这是个重量级的组件,Master维护region的分裂,移动都和它有关。
CatalogTracker
-ROOT- 和 .META. 的跟踪器。具体工作由RootRegionTracker和MetaNodeTracker完成。前者跟踪”root-region-server” 这个ZNode的状态 ,后者跟踪.META.对应的ZNode状态(具体这个ZNode是”unassign/HRegionInfo.FIRST_META_REGIONINFO.getEncodedName()”) 可以从这个组件上获取到目录表的location信息。
ClusterStatusTracker
跟踪“shutdown” 这个ZNode的状态,可以通过这个组件控制cluster的down or up。这个ZNode里面放了集群的启动时间。它的setClusterDown 方法就是通过删除”shutdown” ZNode来完成。
MemoryBoundedLogMessageBuffer
存放来自region server的fatal error信息,超过buffer大小后会自动清理。
ExecutorService
事件执行器,各种不同事件会被提交到里面不同的队列里等待执行。不同的事件默认的资源也不同,比如MASTER_OPEN_REGION事件的处理默认有5个线程。
这个不是java.util.concurrent.ExecutorService而是org.apache.hadoop.hbase.executor.ExecutorService
LoadBalancer
平衡region server上region的负载。当且仅当没有region in transition时候才会起作用。balanceCluster定期被调用生成RegionPlan。
它的默认实现是DefaultLoadBalancer,0.96之后默认是StochasticLoadBalancer(HBASE-5959)。后者的思想是随机做几次决策,每次比较cost function计算出的结果与当前最优的结果,保留较小者。最后如果当前最优cost小于原先的cost,那么就生成相应RegionPlan。
BalancerChore
定期执行 master.balance()。
CatalogJanitor
定期清理.meta.里split时候遗留的parent region信息。如果parent region的reference不再被它的daughter hold,那么parent region就会被清理。
还一个额外条件就是parent region的parent如果没被clean,那么这个parent也不该被clean。
LogCleaner
定期清理.oldlogs目录下的log。
它会从hbase.master.logcleaner.plugins配置里加载所有BaseLogCleanerDelegate。某个log可以被删除,只有所有delegate都同意。
HFileCleaner
定期清理.archive目录下的HFile。
它会从hbase.master.hfilecleaner.plugins配置里加载所有BaseHFileCleanerDelegate。
只有所有delegate都同意才能被删除。
MasterCoprocessorHost
提供Master端的coprocessor的执行环境与框架。
这些coprocessor被包装在MasterEnvironment里。当action发生的时候,会遍历MasterCoprocessorHost里所有MasterEnvironment,获取里面MasterObserver,并调用相关方法。
SnapshotManager
管理table快照的组件。
提供了监视快照执行状态的方法以及制作快照,快照恢复,删除快照等方法。
HealthCheckChore
这不是一个必要的组件,只有你配置了hbase.node.health.script.location才能启动它。它会定期执行location设置的Script来检测health,在失败窗口内失败次数达到阈值就会stop master。
然后我们看看HMaster整个启动过程主要都做了什么:
1.先是在HMaster的构造函数里设置各种参数以及启动RpcServer,链接zookeeper(即创建zookeeperWatcher),如果hbase.node.health.script.location配置存在,则构造一个HealthCheckChore。
2.然后HMaster的run方法会被执行,该方法做如下事情:
启动infoServer,调用becomeActiveMaster竞争成为cluster唯一的active master。
becomeActiveMaster里面会先初始化ActiveMasterManager和ClusterStatusTracker最后调用ActiveMasterManager的blockUntilBecomingActiveMaster方法。
如果竞争成功继续往下走,调用finishInitalization,否则一直阻塞在这步。
3. finishInitalization方法里就是整个启动最复杂的过程了
首先初始化 MasterFileSystem,然后将cluster id写入zookeeper的“hbaseid” ZNode
接着初始化ServerManager和ExecutorService。
之后调用initializeZKBasedSystemTrackers来初始化各种基于zookeeper的组件。这里面先是初始化CatalogTracker,然后是LoadBalancer。因为AssignmentManager的初始化需要LoadBalancer,虽然LoadBalancer和zookeeper没什么关系。然后分别初始化AssignmentManager,RegionServerTracker,DrainingServerTracker,clusterStatusTracker,SnapshotManager。
initializeZKBasedSystemTrackers方法结束后,紧接着初始化MasterCoprocessorHost。
接着调用startServiceThreads来启动各种服务。这个方法里先是启动了MASTER_OPEN_REGION,MASTER_CLOSE_REGION,MASTER_SERVER_OPERATIONS,MASTER_META_SERVER_OPERATIONS,MASTER_TABLE_OPERATIONS这5个事件的处理线程池。然后启动了LogCleaner,HFileCleaner, HealthCheckChore这些周期的服务。最后调用RpcServer的openServer,允许响应请求。
startServiceThreads结束后,会调用ServerManager的waitForRegionServers来等待所有region server报告,直到一些条件发生才会终止等待。比如已报告RS数达到hbase.master.wait.on.regionservers.maxtostart之类。
等待结束之后,我们通过RegionServerTracker获得在线的region servers,也就是在zookeeper上注册了的。遍历它们,寻找那些已经在zookeeper上注册了的,但是还没有report的。我们把这些也记录在ServerManager里,只不过它们的HServerLoad信息暂时为空。
接着是启动AssignmentManager的超时监控。它内部有一个TimeoutMonitor,其实就是启动它。
获取上次failed RS,然后做split log。根据配置的不同,可能是做分布式的split log也可能是master自己split log。split log是为了之后回放,用来恢复在失败前未来得及写入File System的数据。
然后是检测root region server之前是否failed,如果是则split log,然后assign Root。同样的检测met region server,之后是assign Meta。
两个目录表都assign成功之后,调用AssignmentManager的joinCluster。这个方法会扫描meta table然后rebuild所有存在的region。
最后初始化和启动BalancerChore和CatalogJanitor。
上述启动过程隐藏了一些细节,目的是为了看清主线。
整个HMaster的架构和启动过程差不多就是这样,更多Master工作细节可以阅读相关组件的源码。
版权声明:本文为博主原创文章,未经博主允许不得转载。