zoukankan      html  css  js  c++  java
  • HBase Master 启动

    –>首先初始化HMaster

    –>创建一个rpcServer,其中并启动

    –>启动一个Listener线程,功能是监听client的请求,将请求放入nio请求队列,逻辑如下:

    –>创建n个selector,和一个n个线程的readpool,n由”ipc.server.read.threadpool.size”决定,默认为10

    –>读取每个请求的头和内容,将内容放入priorityQueue中

    –>启动一个Responder线程,功能是将响应队列里的数据写给各个client的connection通道,逻辑如下:

    –>创建nio selector

    –>默认超时时间为15 mins

    –>依次将responseQueue中的内容写回各通道,并关闭连接

    –>buffer=8k(代码写死)

    –>如果该请求的返回没有写完,则放回队列头,推迟再发送

    –>对于超时未完成的响应,丢弃并关闭相应连接

    –>启动N(n默认为10)个Handler线程,功能是处理请求队列,并将结果写到响应队列

    –>读取priorityQueue中的call,调用对应的call方法获得value,写回out并调用doRespond方法,处理该请求,并唤醒writable selector

    –>启动M(m默认为0)个Handler线程以处理priority

    –>注册zookeeper watcher

     

    –>block直至成为active master 

        –>先检查配置项”hbase.master.backup”,自己是否backup机器,如果是则直接block直至检查到系统中的active master挂掉(默认每3分钟检查一次) 

        –>否则,注册zookeeper watcher,如果注册成功则成为active master,否则阻塞并反复通过watcher检查在运行的master是否挂掉或stop状态 

     

    –>进入finishInitialization()函数并初始化master: 

        –>先检查hbase版本,如果是第一次启动hbase,则将版本信息写入/hbase/hbase.version,如果下次启动时这个文件不存在,则无法启动!如果不小心删掉了必须自己写一个版本 信息上去 

        –> 检查和保证root region的完好,如果root region还不存在,则创建root region以及第一个meta region 

        –>创建HConnectionImplementation实现的连接 

        –>创建server manager,后续绝大部分master工作都是通过server manager完成的 

        –>创建并启动CatalogTracker线程,用以跟踪root和meta两个特殊table的状态,它内部又启动RootRegionTracker和MetaNodeTracker两个线程 

        –>创建并启动RegionServerTracker线程,用以跟踪所有online region的状态,一旦有node delete状态则会通知server manager将其注销 

        –>创建并启动ClusterStatusTracker线程,用以跟踪整个cluster的up和down状态 

        –>向zookeeper注册AssignmentManager,用以管理region的分配 

        –>创建线程池ExecutorService,在其中运行以下线程 

            MASTER_META_SERVER_OPERATIONS 

            MASTER_SERVER_OPERATIONS 

            MASTER_CLOSE_REGION 

            MASTER_OPEN_REGION 

            MASTER_TABLE_OPERATIONS

    –> 以守护方式运行LogCleaner线程,作用是每1分钟清理(.oldlogs)目录

    –> 启动一个http server:InfoServer,作用是在60010端口上提供界面展示

    –> 允许在初始化HMaster类时启动的Handler线程开始提供响应(通过开关标志)

        –>然后master需要等待regionserver的报告,满足以下这些条件后返回当前所有region server上的region数后继续: 

           a 至少等待4.5s(“hbase.master.wait.on.regionservers.timeout”) 

           b 成功启动regionserver节点数>=1(“hbase.master.wait.on.regionservers.mintostart”) 

           c 1.5s内没有regionsever死掉或新启动(“hbase.master.wait.on.regionservers.interval”) 

     

     

        –>然后splitLogAfterStartup,从hlog中恢复数据,这是一个很长的逻辑: 

            –>依次检查每一个hlog目录,查看它所属的region server是否online,如果是则不需要做任何动作,region server自己会恢复数据,如果不是,则需要将它分配给其它 的region server 

            –>split是加锁操作: 

            –> 创建一个新的hlogsplitter,遍历每一个server目录下的所有hlog文件,依次做如下操作。(如果遇到文件损坏等无法跳过的错误,配 置”hbase.hlog.split.skip.errors=true”以忽略之) 

            –>启动”hbase.regionserver.hlog.splitlog.writer.threads”(默认为3)个线程,共使用128MB内存,启动这些写线程 

            –>先通过lease机制检查文件是否能够append,如果不能则死循环等待 

            –>把hlog中的内容全部加载到内存中(内存同时被几个写线程消费) 

                 –>把有损坏并且跳过的文件移到/hbase/.corrupt/目录中 

                 –> 把其余己经处理过的文件移到/hbase/.oldlogs中,然后删除原有的server目录 

                 –> 等待写线程结束,返回新写的所有路径 

           –>解锁

        写线程逻辑: 

            –>从内存中读出每一行数据的key和value,然后查询相应的region路径。如果该region路径不存在,说明该region很可能己经被split了,则不处理这部分数 据,因为此时忽略它们是安全的。 

            –>如果上一步能查到相应的路径,则到对应路径下创建”recovered.edits”文件夹(如果该文件夹存在则删除后覆盖之),然后将数据写入该文件夹 

     

        –>完成split Hlog的操作后,开始分配root和meta表: 

          –>分配root表: 

              –>block住直到root的region server从transaction状态中恢复正常 

              –>检查root的region server在zookeeper中是否己经有值并且正常可访问,如果不正常或没有则删除原有节点再重新分配(随机分配) 

          –> 分配meta表: 

             –>过程同root表的分配 

     

        –>如果启动后online的region servers上的regions总数为0,则表示这是个fresh start,清除掉zookeeper上的所有节点,重新开始watching 

             –> 开始分配user表 

                   –>扫描meta中的所有表,依次分配,分配方案如下: 

                        –>如果”hbase.master.startup.retainassign”为true(默认为true),则分配时按meta表中原有的信息来分配,即原来在哪里就还分到哪里,如果哪个region在原有的 server info中找不到所属的region server则从online region server中随机挑选 

                        –>否则随机循环添加region,会保证balance 

                  –>分配方案设计好后,开始执行分配的线程,默认超时时间10分钟 

       –>如果启动后online的region servers不为0,则表示很可能master挂掉过,可能是重新启动的。此时系统中己有region servers了,需要先处理region server上的regions: 

            –>转入processFailover处理流程

    –>先调用rebuildUserRegions函数,它扫描.META.表,更新所有的server和对应的regionInfo信息,找出offline的server,加入deadServers

    –>处理deadServers

    –>遍历所有的region,在zk上创建它们的node,把它们加入transition和unassign列表,并置状态为offline

    –>调用ServerShutdownHandler的processDeadRegion方法,处理所有dead regions

    –>跳过所有disabled的table对应的region

    –>查看该region是否己经split,如果是,需要fix它的子region

    –>查看子region的info是否找不到了,如果是的话修补之(即重新将meta表中的region信息添加进来并assign它)

    –>然后扫描zk中的transition列表,对不同的事件做不同处理

    –>RS_ZK_REGION_CLOSING:将它简单添加到regionsInTransition队列中

    –>RS_ZK_REGION_CLOSED:将它添加到regionsInTransition队列中并且创建一个ClosedRegionHandler线程去处理它

    –>ClosedRegionHandler流程:

    –>按root/meta/user region分优先级

    –>如果这个region对应的table己经disabled或disabling,那么下线它并返回

    –>下线这个region,然后再将它分配给一个server(不太明白为什么此时需要assign一次)

    –>M_ZK_REGION_OFFLINE:同上

    –>RS_ZK_REGION_OPENING:将它简单添加到regionsInTransition队列中

    –>RS_ZK_REGION_OPENED:将它添加到regionsInTransition队列中,如果它对应的原来的RS还存在,则创建一个OpenedRegionHandler线程来处理,否则不处理,等待meta扫描时去分配它

    –>OpenedRegionHandler流程:

    –>按root/meta/user region分优先级

    –>先删除zk中己经打开的对应的node

    –>上线这个region

    –>如果这个region对应的table己经disabled或disabling,那么unassign它

     

        –> 启动balancer线程并放入守候线程,默认循环时间为300秒 

        –>balancer线程的作用是定期均衡所有region server上的region数量,工作过程如下: 

            –>三种情况不进行balance: 

                 –>balance开关没有打开(硬编码打开了) 

                 –>有至少一个region正处于regionsInTransition状态(split结束但还没有清除) 

                 –>有正在下线处理的region server 

            –> 制定出balance计划: 

                 –>计算总的region数目,以及online server数量,每个server的region数目都会均衡到平均数。 

            –>执行balance计划: 

                 –> 将执行计划放入assignment的执行计划列表 

                 –>检查该region是否又进入了transaction状态,如果是则跳过 

                 –>将该region置为pending_close状态 

                 –> 向region server发送close region的信号 

            –> 真实执行计划在其它时候(下一篇文章介绍)

     

        –>启动meta扫描线程并放入守候线程,默认循环时间为300秒 

             –> meta扫描线程的作用是定期清理己经split的region并将它删除,工作过程如下: 

                  –> 连接meta server,scan表的info信息,扫描所有region,从region info中读出是否split的信息 

                  –>如果己经split,则先获取splitA和splitB的region info 

                  –>如果splitA和splitB的reference都不再指向父region了(从它们的regionPath可以得出),则将父region删除掉,删掉流程如下: 

                  –> 将region的状态置为offline 

                  –>将该region从regionsInTransition中删除掉 

                  –> 将该region从regionPlan中删除掉,避免再进行balance之类的操作 

                  –>将该region的region info从AssignmentManager的regions树中以及AssignmentManager中存放的每个servers中删掉 

                  –>删除meta表里的该region的目录 

                  –>通知meta region server删除该region 

     

    启动完成

  • 相关阅读:
    uva 10369 Arctic Network
    uvalive 5834 Genghis Khan The Conqueror
    uvalive 4848 Tour Belt
    uvalive 4960 Sensor Network
    codeforces 798c Mike And Gcd Problem
    codeforces 796c Bank Hacking
    codeforces 768c Jon Snow And His Favourite Number
    hdu 1114 Piggy-Bank
    poj 1276 Cash Machine
    bzoj 2423 最长公共子序列
  • 原文地址:https://www.cnblogs.com/cl1024cl/p/6205204.html
Copyright © 2011-2022 走看看