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 

     

    启动完成

  • 相关阅读:
    自己感受,如何解读别人的好的PHP代码
    34. RunAs Authentication Replacement运行身份验证替换
    32.3.3 Authenticating to a Stateless Service with CAS(使用CAS向无状态服务进行身份验证)
    33.2 Adding X.509 Authentication to Your Web Application
    35.2 Encryptors加密器
    32.3.2 Single Logout(单点退出)
    33. X.509 Authentication
    34.2 Configuration
    32.3.4 Proxy Ticket Authentication代理票证认证
    35.3 Key Generators密钥生成器
  • 原文地址:https://www.cnblogs.com/cl1024cl/p/6205204.html
Copyright © 2011-2022 走看看