• HBase Region Assign流程详解


    Hbase是kv存储,但是逻辑上我们可以把存储在hbase上的kv数据当成表,rowkey可以认为是表的主键。为了便于分布式操作,hbase会把表横向切分成一块一块的数据,而每块就是一个Region。为了提供在线服务,我们必须把Region加载到集群中的某台机器上,这个加载的过程正是region assign要做的。顺便说一句,hbase中把表切分region和HDFS中文件切分成block,Spark中RDD切分成partitions的思想都是一样的。

    region assgin的流程

     region assgin涉及到client,master,regionserver以及zk之间的交互。主要步骤如下:

    1,client向master发送AssignRegion的RPC请求后(如当在hbase shell中运行assign命令),master响应该服务的入口函数为:

     1 public AssignRegionResponse assignRegion(RpcController controller,
     2       AssignRegionRequest req) throws ServiceException {
     3       ...
     4       //检查master端服务是否启动以及已经初始化
     5       master.checkInitialized();
     6       //协处理器preAssign
     7       ...
     8       
     9       //核心,使用AssignmentManager做region assignment
    10       master.assignmentManager.assign(regionInfo, true, true);
    11       //协处理器postAssign
    12       ...   
    13 }

    入口函数调用的assgin函数主要实现如下:

     1 public void assign(HRegionInfo region,
     2     boolean setOfflineInZK, boolean forceNewPlan) {
     3     //检查该table是否处于disable或者disabling状态
     4     //如果是,则忽略此次assign操作,并且如果该region处于RS_ZK_REGION_CLOSED,
     5     //M_ZK_REGION_OFFLINE状态,则删除RIT下该节点
     6     //另外,还会将master中该region相关的数据结构(RegionStates)的状态做相应设置
     7     if (isDisabledorDisablingRegionInRIT(region)) {
     8       return;
     9     }
    10     String encodedName = region.getEncodedName();
    11     //貌似主要是锁住该region对应的状态
    12     Lock lock = locker.acquireLock(encodedName);
    13     try {
    14       //根据该region当前的状态,进行相关预操作和过滤,
    15       //比如,如果region处于FAILED_CLOSE和FAILD_OPEN状态会先进行unassign操作
    16       //最终使得region处于offline状态
    17       forceRegionStateToOffline(region, forceNewPlan);
    18       
    19       //尝试maximumAttempts(默认10次),首先获取RegionPlan,
    20       //然后设置zk下RIT对应region的状态为M_ZK_REGION_OFFLINE
    21       //一切准备就绪后,master会设置regionStates为PENDING_OPEN状态,并且
    22       //向RegionServer发送OpenRegion请求
    23       assign(state, ...);
    24       }
    25     } finally {
    26       lock.unlock();
    27     }
    28   }

    2,ReionServer响应OpenRegion的请求函数如下:

    public OpenRegionResponse openRegion(final RpcController controller,
          final OpenRegionRequest request) throws ServiceException {
       ...  
        //正常情况下,会交由OpenRegionHanlder来处理
        regionServer.service.submit(new OpenRegionHandler(
                  regionServer, regionServer, region, htd,     masterSystemTime, coordination, ord));
       ...
       //打开后设置状态返回
       builder.addOpeningState(RegionOpeningState.OPENED);          
    }

    而OpenRegionHandler中open region的核心代码process函数中:

     1 public void process() throws IOException {
     2     ...
     3     //transitionFromOfflineToOpening会将zk中该region的状态从M_ZK_REGION_OFFLINE状态设置成RS_ZK_REGION_OPENING状态
     4     if (useZKForAssignment
     5           && !coordination.transitionFromOfflineToOpening(reg...)
     6           
     7    //打开open region,细节暂时忽略
     8    openRegion()
     9    
    10    //transitionToOpened将zk中该region的状态从RS_ZK_REGION_OPENING设置成
    11    //RS_ZK_REGION_OPENED
    12    if (!isRegionStillOpening() ||
    13           (useZKForAssignment && !coordination.transitionToOpened(region, ord))) {      
    14 }

    3,接下来,再看看Master监控到zk中region状态变化的相应情况:

     1 void handleRegion(final RegionTransition rt, OpenRegionCoordination coordination,
     2                 OpenRegionCoordination.OpenRegionDetails ord) {
     3     //当zk的状态变成RS_ZK_REGION_OPENING,设置regionStates的状态为OPENING               
     4     case RS_ZK_REGION_OPENING:
     5          regionStates.updateRegionState(rt, State.OPENING);
     6      
     7      //正如注释所言,剔除中间状态,删除zk RIT结点,RegionStates设置为OPEN
     8      case RS_ZK_REGION_OPENED:
     9      // Handle OPENED by removing from transition and deleted zk node
    10     regionStates.transitionOpenFromPendingOpenOrOpeningOnServer(...);
    11                    
    12 }

    小结

    通过上面的分析,Region Assgin过程中主要的状态和步骤,大概可以用下图来概括。

    未来

    从上面的分析可知,当前region assgin的流程还是非常复杂的,所有很容易就造成Meta表和master,zk中的状态不一致,从而使Region处于RIT状态。社区正在做这方面的优化,主要思想就是去掉zk依赖,从而只依赖master和regionserver。具体详情可参看: https://blogs.apache.org/hbase/entry/hbase_zk_less_region_assignment 。 预计在hbase 2.0中将包含该功能。

  • 相关阅读:
    Java垃圾收集器概述
    redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
    Serialize a Long as a String
    数据库遇到的问题
    解决Safari页面缓存的问题
    idea -> Error during artifact deployment. See server log for details.
    正则表达式
    commons-lang
    Template和Style
    WPF资源
  • 原文地址:https://www.cnblogs.com/superhedantou/p/6648601.html
Copyright © 2020-2023  润新知