1. master
    1. 初始化HMaster
      1. 创建RPC服务
        1. 启动一个responder线程
          1. 创建nio selector
          2. 默认超时时间为15 mins
          3. 依次将responseQueue中的内容写回各通道,并关闭连接
          4. 如果该请求的返回没有写完,则放回队列头,推迟再发送
          5. 对于超时未完成的响应,丢弃并关闭相应连接
        2. 启动一个listener线程
          1. 创建Reader和readPool
          2. 判断Selector中是否有数据
          3. 如果有,则把数据读出,然后加入到 callQueue或者priorityCallQueue中
        3. 启动n个handers
          1. 启动处理线程组(分为一般的和优先的)
          2. 每一个线程组从call队列中读取数据,并调用对应的call方法(具体由客户端设定)
          3. 把每一个call的处理结果加入到responder会处理的responseQueue队列中
      2. 创建ZooKeeperWatcher
      3. 创建MasterMetrics对象
    2. 启动线程 run()
      1. 创建activeMasterManager,加入到listener队列
      2. 检查是否backup master
        1. 三分钟循环检查一次,直到系统中master挂掉
        2. 往zk写master地址并watch
          1. 成为active master,然后进入finishInitialization函数
          2. 阻塞并反复通过watcher检查在运行的master是否挂掉或stop状态
    3. finishInitialization
      1. 创建MasterFileSystem对象
        1. 检查hbase版本
        2. 检查root region是否存在
          1. 创建root region
          2. regionId为0,列只有info
          3. 首先判断region对应的. Regioninfo文件是否存在,如果大小非0,那么就认为已经写过regioninfo,否则写regioninfo数据,接着清除临时目录
          4. 对每一个ColumnFamily初始化Store
          5. 根据初始化Store时读到的maxSeqId,来进行日志回放,每一个RegionServer对应一个日志文件
          6. 把上次遗留的split文件清理掉,以及compaction时的merger目录也删除掉
          7. 创建meta region
          8. 第一个meta region id为1
          9. 初始化
          10. 把meta信息加入到root表中
          11. 关闭root region和meta region
      2. 创建HConnectionImplementation对象
      3. 创建ServerManager对象
      4. 创建并启动CatalogTracker线程
        1. 启动rootRegionTracker线程
        2. 启动metaNodeTracker线程
      5. 向zk注册AssignmentManager,用以管理region的分配
      6. 创建并启动RegionServerTracker线程
      7. 创建并启动ClusterStatusTracker线程
      8. 创建线程池ExecutorService
        1. MASTER_OPEN_REGION
        2. MASTER_CLOSE_REGION
        3. MASTER_SERVER_OPERATIONS
        4. MASTER_META_SERVER_OPERATIONS
        5. MASTER_TABLE_OPERATIONS
        6. 以守护方式运行LogCleaner线程
        7. 启动一个http server:InfoServer
        8. RPCServer开始处理请求
      9. serverManager.waitForRegionServers
        1. 每隔1500ms统计region server的数量
          1. 如果数量没变 && 数量>1 && 超过了4500s
          2. 统计region servers的region数量并返回
      10. splitLogAfterStartup
        1. 对.logs下每个hlog目录,查看它所属的region server是否online
          1. 不需要做任何动作(region server自己会恢复数据)
          2. 需要将它分配(split log)给其它 的region server
          3. splitLogLock.lock()
          4. 创建一个HLogSplitter
          5. 先通过lease机制检查文件是否能够append,如果不能则死循环等待
          6. 启动3个写线程
          7. 从内存中读出每一行数据的key和value,然后查询相应的region路径。如果该region路径不存在,说明该region很可能己经被split了,则不处理这部分数 据,因为此时忽略它们是安全的。
          8. 如果上一步能查到相应的路径,则到对应路径下创建"recovered.edits"文件夹(如果该文件夹存在则删除后覆盖之),然后将数据写入该文件夹
          9. 把hlog中的内容全部加载到内存中(内存同时被几个写线程消费)
          10. 把有损坏并且跳过的文件移到/hbase/.corrupt/目录中
          11. 把其余己经处理过的文件移到/hbase/.oldlogs中,然后删除原有的server目录
          12. 等待写线程结束,返回新写的所有路径
          13. 把被处理的日志分别放到指定的corrupt目录和oldLogDir目录下,然后关闭writerThreads线程组
          14. splitLogLock.unlock()
      11. assignRootAndMeta
        1. ROOT region
          1. processRegionInTransitionAndBlockUntilAssigned
          2. verifyRootRegionLocation
          3. Topic
          4. Topic
          5. assignRoot
          6. waitForRoot
        2. meta region
          1. processRegionInTransitionAndBlockUntilAssigned
          2. verifyMetaRegionLocation
          3. Topic
          4. Topic
          5. assignMeta
          6. waitForMeta
          7. waitForAssignment
      12. regionCount==0 ?
        1. fresh start
          1. cleanoutUnassigned
          2. assignAllUserRegions
          3. 扫描meta中的所有表,依次分配
          4. hbase.master.startup.retainassign
          5. 按meta表中原有的信息来分配,即原来在哪里就还分到哪里,如果哪个region在原有的 server info中找不到所属的region server则从online region server中随机挑选
          6. 随机循环添加region,会保证balance
          7. 分配方案设计好后,开始执行分配的线程,默认超时时间10分钟
        2. processFailover
          1. rebuildUserRegions
          2. 处理deadServers
          3. 遍历所有的region,在zk上创建它们的node,把它们加入transition和unassign列表,并置状态为offline
          4. ServerShutdownHandler -> processDeadRegion
          5. 跳过所有disabled的table对应的region
          6. 查看该region是否己经split,如果是,需要fix它的子region
          7. 查看子region的info是否找不到了,如果是的话修补之(即重新将meta表中的region信息添加进来并assign它)
          8. 扫描zk中的transition列表,对不同的事件做不同处理
          9. RS_ZK_REGION_CLOSING
          10. 添加到regionsInTransition队列中
          11. RS_ZK_REGION_CLOSED
          12. 添加到regionsInTransition队列中并且创建一个ClosedRegionHandler线程去处理它
          13. 按root/meta/user region分优先级
          14. 如果这个region对应的table己经disabled或disabling,那么下线它并返回
          15. 下线这个region,然后再将它分配给一个serve
          16. M_ZK_REGION_OFFLINE
          17. 同上
          18. RS_ZK_REGION_OPENING
          19. 添加到regionsInTransition队列
          20. RS_ZK_REGION_OPENED
          21. 添加到regionsInTransition队列中
          22. 对应的原来的RS是否存在
          23. 创建一个OpenedRegionHandler线程来处理
          24. 按root/meta/user region分优先级
          25. 先删除zk中己经打开的对应的node
          26. 上线这个region
          27. 如果这个region对应的table己经disabled或disabling,那么unassign它
          28. 不处理,等待meta扫描时去分配它
      13. getAndStartBalancerChore
        1. balanceSwitch
          1. isRegionsInTransition
          2. areDeadServersInProgress
          3. 制定出balance计划
          4. 执行balance计划
          5. 将执行计划放入assignment的执行计划列表
          6. 检查该region是否又进入了transaction状态,如果是则跳过
          7. 将该region置为pending_close状态
          8. 向region server发送close region的信号
          9. 真实执行计划
      14. CatalogJanitor
        1. initialChore() chore()
          1. scan()
          2. fullscan()
          3. isSplitParent()
          4. Map<HRegionInfo, Result> splitParents
          5. 遍历splitParents
          6. cleanParent(...)
          7. HConstants.SPLITA_QUALIFIER HConstants.SPLITB_QUALIFIER
          8. checkDaughter()
          9. getAssignmentManager().regionOffline
          10. regionsInTransition.remove
          11. clearRegionPlan
          12. setOffline
          13. HRegion.deleteRegion
          14. MetaEditor.deleteRegion
    4. loop
      1. stop?
        1. stopChores()
          1. balancerChore.interrupt()
          2. catalogJanitorChore.interrupt()
        2. serverManager.letRegionServersShutdown()
        3. stopServiceThreads()
          1. rpcServer.stop()
          2. logCleaner.interrupt()
          3. infoServer.stop()
        4. activeMasterManager.stop()
        5. catalogTracker.stop()
        6. serverManager.stop()
        7. assignmentManager.stop()
        8. HConnectionManager.deleteConnection
        9. zooKeeper.close()
  2. region server
  3. client