hbase region split源码分析

简介: hbase region split :split执行调用流程:1.HbaseAdmin发起split:###2.RSRpcServices实现类执行split(Implements the regionserver RPC services.)###3.CompactSplitThread类与SplitRequest类用来执行region切割:###4.splitRequest执行doSplitting操作###4.1初始化两个子region###4.2执行切割####4.2.1:(创建子region。

hbase region split :

split执行调用流程:

1.HbaseAdmin发起split:###

2.RSRpcServices实现类执行split(Implements the regionserver RPC services.)###

3.CompactSplitThread类与SplitRequest类用来执行region切割:###

4.splitRequest执行doSplitting操作###

4.1初始化两个子region###

4.2执行切割####

4.2.1:(创建子region。stepsBeforePONR函数)#####
4.2.2:子region执行:stepsAfterPONR函数执行(包含openDaughters函数):#####
4.2.3:HRegionServer添加子region到meta表,加入RegionServer#####

4.3等待region切分完成,修改meta表信息,报告master####

1.HbaseAdmin发起split:

    public void split(final TableName tableName) throws IOException {
split(tableName, null);
  }
   public void split(final ServerName sn, final HRegionInfo hri,
  byte[] splitPoint) throws IOException {
if (hri.getStartKey() != null && splitPoint != null &&
 Bytes.compareTo(hri.getStartKey(), splitPoint) == 0) {
   throw new IOException("should not give a splitkey which equals to startkey!");
}
// TODO: There is no timeout on this controller. Set one!
HBaseRpcController controller = rpcControllerFactory.newController();
controller.setPriority(hri.getTable());

// TODO: this does not do retries, it should. Set priority and timeout in controller
AdminService.BlockingInterface admin = this.connection.getAdmin(sn);

//hbase中split调用请求通过protobuf(AdminProtos)实现
ProtobufUtil.split(controller, admin, hri, splitPoint);
    实现代码:
     try {
        admin.splitRegion(controller, request);
        } 

2.RSRpcServices实现类执行split(Implements the regionserver RPC services.)

      代码:
      try {
  checkOpen();
  requestCount.increment();
  Region region = getRegion(request.getRegion());
  region.startRegionOperation(Operation.SPLIT_REGION);
  if (region.getRegionInfo().getReplicaId() != HRegionInfo.DEFAULT_REPLICA_ID) {
throw new IOException("Can't split replicas directly. "
+ "Replicas are auto-split when their primary is split.");
  }
  LOG.info("Splitting " + region.getRegionInfo().getRegionNameAsString());
  region.flush(true);
  byte[] splitPoint = null;
  if (request.hasSplitPoint()) {

  //确定切割点splitpoint
splitPoint = request.getSplitPoint().toByteArray();
  }
  ((HRegion)region).forceSplit(splitPoint);

  //请求region切割
  regionServer.compactSplitThread.requestSplit(region, ((HRegion)region).checkSplit(),
RpcServer.getRequestUser());
  return SplitRegionResponse.newBuilder().build();
}

3.CompactSplitThread类与SplitRequest类用来执行region切割:

    代码:
    try {
  this.splits.execute(new SplitRequest(r, midKey, this.server, user));
  if (LOG.isDebugEnabled()) {
LOG.debug("Split requested for " + r + ".  " + this);
  }
}

try {
  //acquire a shared read lock on the table, so that table schema modifications
  //do not happen concurrently

  //获取table的读锁。。
  tableLock = server.getTableLockManager().readLock(parent.getTableDesc().getTableName()
  , "SPLIT_REGION:" + parent.getRegionInfo().getRegionNameAsString());
  try {
tableLock.acquire();
  }

4.splitRequest执行doSplitting操作

4.1###

       //初始化两个子region信息
this.hri_a = new HRegionInfo(hri.getTable(), startKey, this.splitrow, false, rid);
    this.hri_b = new HRegionInfo(hri.getTable(), this.splitrow, endKey, false, rid);

4.2###

       //执行切割
   st.execute(this.server, this.server, user);

4.2.1:(创建子region。stepsBeforePONR函数)####

            //创建两个子region
        PairOfSameType<Region> regions = createDaughters(server, services, user);

4.2.2:stepsAfterPONR函数执行(openDaughters):####

            // 两个子region DaughterOpener线程 start
        DaughterOpener aOpener = new DaughterOpener(server, (HRegion)a);
        DaughterOpener bOpener = new DaughterOpener(server, (HRegion)b);

        //向hdfs上写入.regionInfo文件以便meta挂掉以便恢复 
        writeRegionInfoOnFilesystem(content, true);

        //初始化所有的hstore
        initializeStores(reporter, status);

        //LoadStoreFiles函数执行:
        if (files == null || files.size() == 0) {
        return new ArrayList<StoreFile>();
        }

             // initialize the thread pool for opening store files in parallel..
            ThreadPoolExecutor storeFileOpenerThreadPool =
            this.region.getStoreFileOpenAndCloseThreadPool("StoreFileOpenerThread-" +
         this.getColumnFamilyName());
             CompletionService<StoreFile> completionService =
            new ExecutorCompletionService<StoreFile>(storeFileOpenerThreadPool);

            int totalValidStoreFile = 0;
            for (final StoreFileInfo storeFileInfo: files) {

            //HDFS上对应的路径和文件
            completionService.submit(new Callable<StoreFile>() {
             @Override
            public StoreFile call() throws IOException {

            //每个文件创建一个StoreFile对象,对每个storefile对象会读取文件上的内容创建一个 
            HalfStoreFileReader读对象来操作该region的父region上的相应的文件,及该 
            region上目前存储的是引用文件,其指向的是其父region上的相应的文件,对该 
            region的所有读或写都将关联到父region上
         StoreFile storeFile = createStoreFileAndReader(storeFileInfo);
         return storeFile;
             }
            });
             totalValidStoreFile++;
             }


             //将子Region添加到rs的online region列表上,并添加到meta表上 
             {
         if (useZKForAssignment) {
          // add 2nd daughter first (see HBASE-4335)
          services.postOpenDeployTasks(b);
         } else if (!services.reportRegionStateTransition(TransitionCode.SPLIT,
           parent.getRegionInfo(), hri_a, hri_b)) {
         throw new IOException("Failed to report split region to master: "
          + parent.getRegionInfo().getShortNameToLog());
         }
         // Should add it to OnlineRegions
         services.addToOnlineRegions(b);
         if (useZKForAssignment) {
           services.postOpenDeployTasks(a);
        }
         services.addToOnlineRegions(a);
         }

参考文章:
http://blog.csdn.net/Pun_C/article/details/47173453

相关实践学习
lindorm多模间数据无缝流转
展现了Lindorm多模融合能力——用kafka API写入,无缝流转在各引擎内进行数据存储和计算的实验。
云数据库HBase版使用教程
&nbsp; 相关的阿里云产品:云数据库 HBase 版 面向大数据领域的一站式NoSQL服务,100%兼容开源HBase并深度扩展,支持海量数据下的实时存储、高并发吞吐、轻SQL分析、全文检索、时序时空查询等能力,是风控、推荐、广告、物联网、车联网、Feeds流、数据大屏等场景首选数据库,是为淘宝、支付宝、菜鸟等众多阿里核心业务提供关键支撑的数据库。 了解产品详情:&nbsp;https://cn.aliyun.com/product/hbase &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
2月前
|
存储 分布式计算 Hadoop
Hadoop-33 HBase 初识简介 项目简介 整体架构 HMaster HRegionServer Region
Hadoop-33 HBase 初识简介 项目简介 整体架构 HMaster HRegionServer Region
65 2
|
存储 分布式计算 监控
分布式数据库HBase的基本概念和架构之基本架构的Region Server
分布式数据库HBase是一个开源的分布式数据库系统,是Apache Hadoop生态系统的重要组成部分。
420 0
|
Arthas 负载均衡 Java
Hbase1.3 生产优化,源码分析
Hbase1.3 生产优化,源码分析
137 0
|
分布式计算 分布式数据库 Hbase
Hbase compact以及split跟踪
为了准确了解HBASE内部工作原理,我们需要做一些测试,在大量数据插入的情况下,HBASE内部到底有什么表现? 比如插入速度, hstore compact,split等相关活动,了解了这些才能更好的维护HBASE系统本身。 此次测试会有几轮,所以测试到哪里就写到哪里,我随便找了一张大概120W来的表,我会写一个mapreduce任务,来读取这张表,再写入另外一个测试表: test2, 没有选择更大的表是因为毕竟整个拷贝是需要时间,通常20分钟-30分钟,太大的表,不太利于跟踪。 拷贝过程,HBASE会针对此表有相关的活动日志,依据日志,我们来看看HBASE到底在干什么。 测试开始,
236 0
|
存储 大数据 Java
深入解读HBase2.0新功能之高可用读Region Replica
基于时间线一致的高可用读(Timeline-consistent High Available Reads),又称Region replica,为HBase带来了高可用读的能力。本文主要介绍region replica这个功能设计的背景,技术细节和使用方法,同时会仔细分析这个功能的优缺点并给出使用建议。
9154 0
|
分布式数据库 Hbase
技术篇-深入解读 HBase2.0 新功能之高可用读 Region Replica
1.前言 基于时间线一致的高可用读(Timeline-consistent High Available Reads),又称 Region replica。其实早在 HBase-1.2 版本的时候,这个功能就已经开发完毕了, 但是还是不太稳定,离生产可用级别还有一段距离,后来社区又陆陆续续修复了 一些 bug,比如说 HBASE-18223。
4671 0
|
存储 Shell 分布式数据库