现在的位置: 首页 > 综合 > 正文

HBase源码分析_Master启动过程

2018年01月11日 ⁄ 综合 ⁄ 共 4990字 ⁄ 字号 评论关闭

构造函数:

1.       创建RPC服务:

i.             创建Listener,主要负责为处理线程创建job,该Listener会创建读取线程(Reader),线程个数为ipc.server.read.threadpool.size,Reader判断Selector中是否有数据,如果有,则把数据读出,然后加入到call队列或者优先队列中。

ii.             创建HbaseRpcMetric,负责统计数据收集

iii.             创建Responder,responder负责将服务端的reponser数据异步写给客户端

2.       启动处理线程组(分为一般的处理线程组和优先的处理线程组,代码上没看到区别),每一个线程组从call队列中读取数据,并调用对应的call方法(具体由客户端设定),处理完以后把每一个call的处理结果加入到responder会处理的responseQueue队列中
3.       创建ZooKeeperWatcher,观察hbase节点,以及hbase下面的master节点,unassigned节点,rs节点,table节点
4.       创建MasterMetric对象

Thread.run():

1.       基于ZooKeeperWatcher创建一个ActiveMasterManager,加入到zookeeper的listener队列中,用于监视zookeeper节点状态
2.       如果是备份节点

i.             通过zookeeper监控节点状态,去写master的地址到zookeeper节点:

ii.             如果写失败,则说明当前有别的master,则一直等,直到zookeeper通知master节点状态发生变化;

iii.             如果写成功,则备份节点成为主节点

3.       如果不是备份节点,如果自己作为master不active,则循环等待,直到自己active为止,如果自己active,那么进入2.b.i
4.       在成为主master之前,初始化master的剩余几个类,以及启动一些服务,这是master启动逻辑最复杂的那部分,finishInitialization:

1)      fileSystemManager:

i.             判断HBASE_ROOT有效性,等待HDFS退出safemode

ii.             如果HBASE_ROOT不存在,则创建他,并写入version,如果存在,则判断version是否和本master启动一致

iii.             如果HBASE_ROOT下不存在root region,那么创建root和meta两个region

iv.             创建rootregion是创建regionId为0的region,这个region只负责root表的数据,他的列只有info

v.             初始化region,1)首先判断region对应的.Regioninfo文件是否存在,如果大小非0,那么就认为已经写过regioninfo,否则写regioninfo数据,接着清除临时目录,2)接着对每一个ColumnFamily初始化Store(Store我们到介绍region的时候详细介绍,这里可以简单地理解为是一个映射表),3)根据初始化Store时读到的maxSeqId,来进行日志回放,每一个RegionServer对应一个日志文件,这里我们也不进行深入展开,4)把上次遗留的split文件清理掉,以及compaction时的merger目录也删除掉

vi.             创建meta region,第一个meta region id为1,初始化过程和5一样

vii.             meta信息加入到root表中

viii.             关闭root region和meta region

2)      Hconnection:

i.             从一个LRU的conf hashcode=>TableServer的HashMap中获取Hconnection,如果HashMap中没有,则创建并加入到map中,创建过程如下:

ii.             从conf中读取一些客户端参数

iii.             设置zooKeeperTrackers         ,包括一个zookeeperWatcher,master节点的地址监控tracker,rootregion的地址监控tracker

3)      ExecutorService:

i.             执行器服务,概括为一个线程池,一个Event队列,以及处理这个队列的处理器

4)      ServerManger:

i.             管理region server的信息,HserverInfo,负载,以及死的server。

ii.             维护在线和离线的server,处理region server的启动和关闭

5)      CatalogServer:

i.             创建root region 的地址监控tracker,meta region的地址监控tracker,并启动他俩

6)      AssignmentManager:

i.             用于管理region的分配

7)      RegionServerTracker:

i.             启动通过zookeerper跟踪在线的region server

8)      ClusterStatusTracker:

i.             跟踪集群状态,并设置集群状态为up,在这之前如果有regionserver启动,则regionserver会一直处于等待状态

9)      启动ExecutorService的不同服务,用于接收不同的请求类型:

i.             MASTER_OPEN_REGION

ii.             MASTER_CLOSE_REGION

iii.             MASTER_SERVER_OPERATIONS

iv.             MASTER_META_SERVER_OPERATIONS

v.             MASTER_TABLE_OPERATIONS

vi.             LogCleaner

vii.             InfoServer:一个httpSever

viii.             RPCServer

10)  等待regionserver汇报,ServerManager统计

i.             Server数

ii.             每个server 的Region数

11)  恢复日志,主要是针对还没有起来的regionserver的日志

i.             对于.logs目录下,如果对应的文件名(其实就是主机名)没有对应的regionserver,那么就需要将这部分的日志分摊(split log)到别的region server上

ii.             Splitlog简单地来说就是将属于一个region的日志重新从regionserver的日志中提取出来,写到一个新的文件中,以供加载region的时候使用,

iii.             具体地说,

a)       先创建一个HlogSplitter,HlogSplitter把regionserver的日志按记录读取出来,存放到一个EntryBuffers结构中,然后由一组写线程writerThreads读取这个结构,写入到/HBASE_ROOT/TABLE_NAME/REGION_ENCODE_NAME/RECOVERED_EDITS_DIR/LOG_SEQ_NUM文件中,如:hbase/some_table/2323432434/recovered.edits/2332

b)       在split的过程中,会遇到EOFException、FileNotFoundException、IOException等异常,EOFException异常通常是由于文件截断造成的,比如regionserver异常crash了,FileNotFoundException这种情况往往是由于regionserver在关闭之前把日志写完了,这时候这些日志实际上已经被持久化了,IOException是剩余的情况,这种情况下,我们认为日志被损坏了

c)       把被处理的日志分别放到指定的corrupt目录和oldLogDir目录下,然后关闭writerThreads线程组

12)  再次确认root和第一个meta表已经分配:

i.             如果root region起来了,但是还在迁移,那么等待他迁移完成,此时master是被阻塞的

ii.             如果meta region起来了,但是还在迁移,那么等待他迁移完成,此时master也是被阻塞的

13)  如果一个regionserver一个都没有,那么AssignmentManager重新分配所有的region,否则,处理failover状况

i.             重新分配所有region包括:

a)       清除目前的region分配状况

b)       重新分配所有非disable的表的region,分配region有两种balance方法,一种是按照上次的分配方式,一种是roundrobin方式,可以通过hbase.master.startup.retainassign配置,如果配置成true,则为上次的分配方式。分配方式由一个叫做BulkAssigner的对象负责。

ii.             处理failover状况

a)       首先获取未被分配的region对应的server列表,然后对每台server机器上的region进行处理,其实只是从zookeeper上面设置region的信息为offline

b)       如果是因为分裂导致的offlineregion,那么确认新split出来的region信息已经加入到meta表中

iii.             获取那些正在迁移的region,将这些region信息更改加入到当前的zookeerper迁移列表中,交给zookeeperWatcher负责更新

14)  启动balancer线程,balancer是一个后台定时启动的chore

i.             如果balancer已经关闭,那么直接退出这次balance

ii.             如果有region在迁移,也直接退出这次balance

iii.             如果有死的节点,那么也直接退出这次balance

iv.             获取目前的分配状况,然后为每一个分配生成一个balance计划,分别执行,balance在讲balancer的时候再细讲

15)  启动一个meta表的Janitor(看门人,catalogJanitorChore),然后扫描meta表,去收集那些未使用的region,用于垃圾回收,细节这里也不再展开

16)  设置master状态为已经初始化

5.       然后就是循环sleep,直到遇到stop命令

a)停掉balancerChore

b) 停掉catalogJanitorChore

c)等待所有regionserver停掉

d)关掉rpc服务

e)停止logCleaner,infoServer,activeMasterManager,catalogTracker,serverManager,assignmentManager

f)删除HConnection连接,关闭和zookeeper的连接

抱歉!评论已关闭.