HBase Region在两个RegionServer出现分析

文章转自:http://punishzhou.iteye.com/blog/1264874


HBase的操作一般都是以region为粒度的,如split,compact,move等操作。因此对于每个region在集群的唯一性就需要得到保证。若region在两个regionserver中出现显然会有各种各样的bug出现。

这里我们通过以下的分析来看看region在上吗情况下会出现分配到两个rs中。


对于一个RS1上的Region A将其move到RS2中,调用HBaseAdmin的move操作:

1.创建一个到B的RegionPlan

2.然后unassigned Region A,即将RS1上的Region A的region关闭,主要是关闭region上每个storefile的读数据流,在这个过程中会把memstore内容刷一次磁盘

3.然后在RS2中open Region A,主要操作是对Region A的初始化,将A的rs地址信息更新Meta表中


假设在move的过程中RS1 down掉了,那么master会调用servershutdownhandler来处理该事件。主要处理步骤如下:
Java代码HBase Region在两个RegionServer出现分析
文章图片

  1. public void process() throws IOException {
  2. final String serverName = this.hsi.getServerName();

拆分日志,把regionserver的hlog按照region的不同进行拆分,分别写入各个region目录下
Java代码HBase Region在两个RegionServer出现分析
文章图片
  1. LOG.info(" Splitting logs for " + serverName);
  2. this.services.getMasterFileSystem().splitLog(serverName);

在master的内存中清除rs中的region和server,并返回在master的RIT队列上的该RS的online region

Java代码HBase Region在两个RegionServer出现分析
文章图片
  1. // Clean out anything in regions in transition.Being conservative and
  2. // doing after log splitting.Could do some states before -- OPENING?
  3. // OFFLINE? -- and then others after like CLOSING that depend on log
  4. // splitting.
  5. List regionsInTransition =
  6. this.services.getAssignmentManager().processServerShutdown(this.hsi);
[如该RS包含ROOT或META则需首先分配之
Java代码HBase Region在两个RegionServer出现分析
文章图片
  1. // Assign root and meta if we were carrying them.
  2. if (isCarryingRoot()) { // -ROOT-
  3. try {
  4. this.services.getAssignmentManager().assignRoot();
  5. } catch (KeeperException e) {
  6. this.server.abort(" In server shutdown processing, assigning root" , e);
  7. throw new IOException(" Aborting" , e);
  8. }
  9. }
  10. // Carrying meta?
  11. if (isCarryingMeta())this.services.getAssignmentManager().assignMeta();

从meta表中获得RS1上的的region
Java代码HBase Region在两个RegionServer出现分析
文章图片
  1. // Wait on meta to come online; we need it to progress.
  2. // TODO: Best way to hold strictly here?We should build this retry logic
  3. //into the MetaReader operations themselves.
  4. NavigableMap hris = null;
  5. while (!this.server.isStopped()) {
  6. try {
  7. this.server.getCatalogTracker().waitForMeta();
  8. hris = MetaReader.getServerUserRegions(this.server.getCatalogTracker(),
  9. this.hsi);
  10. break;
  11. } catch (InterruptedException e) {
  12. Thread.currentThread().interrupt();
  13. throw new IOException(" Interrupted" , e);
  14. } catch (IOException ioe) {
  15. LOG.info(" Received exception accessing META during server shutdown of " +
  16. serverName + " , retrying META read" );
  17. }
  18. }

移除RIT中状态为Closing或是PendingClose的region,得到的就是需要重新分配的regions[

Java代码HBase Region在两个RegionServer出现分析
文章图片
  1. // Skip regions that were in transition unless CLOSING or PENDING_CLOSE
  2. for (RegionState rit : regionsInTransition) {
  3. if (!rit.isClosing() & & !rit.isPendingClose()) {
  4. LOG.debug(" Removed " + rit.getRegion().getRegionNameAsString() +
  5. " from list of regions to assign because in RIT" );
  6. hris.remove(rit.getRegion());
  7. }
  8. }

我们可以看到,在move过程中,若region尚未上线,此时master的RIT队列中region的状态是OFFLINE,而该region在master的角度来看是offline的,然而在severshutdown的处理中认为该region是要重新分配的。若在此时region在RS2上线了,那么而master依然要对该region进行分配这就导致了region的两次分配过程[code=" java" ]
Java代码HBase Region在两个RegionServer出现分析
文章图片
  1. LOG.info(" Reassigning " + hris.size() + " region(s) that " + serverName +
  2. " was carrying (skipping " + regionsInTransition.size() +
  3. " regions(s) that are already in transition)" );
  4. // Iterate regions that were on this server and assign them
  5. for (Map.Entry e: hris.entrySet()) {
  6. if (processDeadRegion(e.getKey(), e.getValue(),
  7. this.services.getAssignmentManager(),
  8. this.server.getCatalogTracker())) {
  9. this.services.getAssignmentManager().assign(e.getKey(), true);
  10. }
  11. }
  12. this.deadServers.finish(serverName);
  13. LOG.info(" Finished processing of shutdown of " + serverName);
  14. }

【HBase Region在两个RegionServer出现分析】 整个过程起始是在rs shundown以后master需要对rs上的region重新assign到其他rs中去,但是在需要assign的region的序曲上出现了一些问题,将在master中已经offline的但是依然在RIT队列中的region重新分配,由于这些region可能已经在其他地方正在分配,但是还没有上线。当master开始assign region的时候此时region上线了,master依旧会继续分配重而导致region的两次分配

    推荐阅读