You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by ra...@apache.org on 2012/05/21 19:07:33 UTC

svn commit: r1341110 - in /hbase/trunk/src: main/java/org/apache/hadoop/hbase/master/AssignmentManager.java test/java/org/apache/hadoop/hbase/master/TestAssignmentManager.java

Author: ramkrishna
Date: Mon May 21 17:07:33 2012
New Revision: 1341110

URL: http://svn.apache.org/viewvc?rev=1341110&view=rev
Log:
HBASE-5882 Prcoess RIT on master restart can try assigning the region if the region is found on a dead server instead of waiting for Timeout Monitor (Ashutosh)

Modified:
    hbase/trunk/src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java
    hbase/trunk/src/test/java/org/apache/hadoop/hbase/master/TestAssignmentManager.java

Modified: hbase/trunk/src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java
URL: http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java?rev=1341110&r1=1341109&r2=1341110&view=diff
==============================================================================
--- hbase/trunk/src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java (original)
+++ hbase/trunk/src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java Mon May 21 17:07:33 2012
@@ -582,8 +582,12 @@ public class AssignmentManager extends Z
           // So we will assign the ROOT and .META. region immediately.
           processOpeningState(regionInfo);
           break;
-
-        }
+        } else if (deadServers.keySet().contains(sn)) {
+          // if the region is found on a dead server, we can assign
+          // it to a new RS. (HBASE-5882)
+          processOpeningState(regionInfo);
+          break;
+        } 
         regionsInTransition.put(encodedRegionName,
           getRegionState(regionInfo, RegionState.State.OPENING, rt));
         failoverProcessedRegions.put(encodedRegionName, regionInfo);
@@ -621,7 +625,6 @@ public class AssignmentManager extends Z
     }
   }
   
-
   /**
    * Put the region <code>hri</code> into an offline state up in zk.
    * @param hri

Modified: hbase/trunk/src/test/java/org/apache/hadoop/hbase/master/TestAssignmentManager.java
URL: http://svn.apache.org/viewvc/hbase/trunk/src/test/java/org/apache/hadoop/hbase/master/TestAssignmentManager.java?rev=1341110&r1=1341109&r2=1341110&view=diff
==============================================================================
--- hbase/trunk/src/test/java/org/apache/hadoop/hbase/master/TestAssignmentManager.java (original)
+++ hbase/trunk/src/test/java/org/apache/hadoop/hbase/master/TestAssignmentManager.java Mon May 21 17:07:33 2012
@@ -472,6 +472,7 @@ public class TestAssignmentManager {
             am.regionsInTransition.isEmpty());
       }
     } finally {
+      am.setEnabledTable(REGIONINFO.getTableNameAsString());
       executor.shutdown();
       am.shutdown();
       // Clean up all znodes
@@ -614,47 +615,65 @@ public class TestAssignmentManager {
   @Test
   public void testRegionPlanIsUpdatedWhenRegionFailsToOpen() throws IOException, KeeperException,
       ServiceException, InterruptedException {
-    this.server.getConfiguration().setClass(HConstants.HBASE_MASTER_LOADBALANCER_CLASS,
-        MockedLoadBalancer.class, LoadBalancer.class);
-    AssignmentManagerWithExtrasForTesting am = setUpMockedAssignmentManager(this.server,
-        this.serverManager);
-    // Boolean variable used for waiting until randomAssignment is called and new
-    // plan is generated.
-    AtomicBoolean gate = new AtomicBoolean(false);
-    if (balancer instanceof MockedLoadBalancer) {
-      ((MockedLoadBalancer) balancer).setGateVariable(gate);
-    }
-    ZKAssign.createNodeOffline(this.watcher, REGIONINFO, SERVERNAME_A);
-    int v = ZKAssign.getVersion(this.watcher, REGIONINFO);
-    ZKAssign.transitionNode(this.watcher, REGIONINFO, SERVERNAME_A, EventType.M_ZK_REGION_OFFLINE,
-        EventType.RS_ZK_REGION_FAILED_OPEN, v);
-    String path = ZKAssign.getNodeName(this.watcher, REGIONINFO.getEncodedName());
-    RegionState state = new RegionState(REGIONINFO, State.OPENING, System.currentTimeMillis(),
-        SERVERNAME_A);
-    am.regionsInTransition.put(REGIONINFO.getEncodedName(), state);
-    // a dummy plan inserted into the regionPlans. This plan is cleared and new one is formed
-    am.regionPlans.put(REGIONINFO.getEncodedName(), new RegionPlan(REGIONINFO, null, SERVERNAME_A));
-    RegionPlan regionPlan = am.regionPlans.get(REGIONINFO.getEncodedName());
-    List<ServerName> serverList = new ArrayList<ServerName>(2);
-    serverList.add(SERVERNAME_B);
-    Mockito.when(this.serverManager.createDestinationServersList(SERVERNAME_A)).thenReturn(serverList);
-    am.nodeDataChanged(path);
-    // here we are waiting until the random assignment in the load balancer is called.
-    while (!gate.get()) {
-      Thread.sleep(10);
-    }
-    // new region plan may take some time to get updated after random assignment is called and 
-    // gate is set to true.
-    RegionPlan newRegionPlan = am.regionPlans.get(REGIONINFO.getEncodedName());
-    while (newRegionPlan == null) {
-      Thread.sleep(10);
-      newRegionPlan = am.regionPlans.get(REGIONINFO.getEncodedName());
+    try {
+      this.server.getConfiguration().setClass(
+          HConstants.HBASE_MASTER_LOADBALANCER_CLASS, MockedLoadBalancer.class,
+          LoadBalancer.class);
+      AssignmentManagerWithExtrasForTesting am = setUpMockedAssignmentManager(
+          this.server, this.serverManager);
+      // Boolean variable used for waiting until randomAssignment is called and
+      // new
+      // plan is generated.
+      AtomicBoolean gate = new AtomicBoolean(false);
+      if (balancer instanceof MockedLoadBalancer) {
+        ((MockedLoadBalancer) balancer).setGateVariable(gate);
+      }
+      ZKAssign.createNodeOffline(this.watcher, REGIONINFO, SERVERNAME_A);
+      int v = ZKAssign.getVersion(this.watcher, REGIONINFO);
+      ZKAssign.transitionNode(this.watcher, REGIONINFO, SERVERNAME_A,
+          EventType.M_ZK_REGION_OFFLINE, EventType.RS_ZK_REGION_FAILED_OPEN, v);
+      String path = ZKAssign.getNodeName(this.watcher, REGIONINFO
+          .getEncodedName());
+      RegionState state = new RegionState(REGIONINFO, State.OPENING, System
+          .currentTimeMillis(), SERVERNAME_A);
+      am.regionsInTransition.put(REGIONINFO.getEncodedName(), state);
+      // a dummy plan inserted into the regionPlans. This plan is cleared and
+      // new one is formed
+      am.regionPlans.put(REGIONINFO.getEncodedName(), new RegionPlan(
+          REGIONINFO, null, SERVERNAME_A));
+      RegionPlan regionPlan = am.regionPlans.get(REGIONINFO.getEncodedName());
+      List<ServerName> serverList = new ArrayList<ServerName>(2);
+      serverList.add(SERVERNAME_B);
+      Mockito.when(
+          this.serverManager.createDestinationServersList(SERVERNAME_A))
+          .thenReturn(serverList);
+      am.nodeDataChanged(path);
+      // here we are waiting until the random assignment in the load balancer is
+      // called.
+      while (!gate.get()) {
+        Thread.sleep(10);
+      }
+      // new region plan may take some time to get updated after random
+      // assignment is called and
+      // gate is set to true.
+      RegionPlan newRegionPlan = am.regionPlans
+          .get(REGIONINFO.getEncodedName());
+      while (newRegionPlan == null) {
+        Thread.sleep(10);
+        newRegionPlan = am.regionPlans.get(REGIONINFO.getEncodedName());
+      }
+      // the new region plan created may contain the same RS as destination but
+      // it should
+      // be new plan.
+      assertNotSame("Same region plan should not come", regionPlan,
+          newRegionPlan);
+      assertTrue("Destnation servers should be different.", !(regionPlan
+          .getDestination().equals(newRegionPlan.getDestination())));
+    } finally {
+      this.server.getConfiguration().setClass(
+          HConstants.HBASE_MASTER_LOADBALANCER_CLASS, DefaultLoadBalancer.class,
+          LoadBalancer.class);
     }
-    // the new region plan created may contain the same RS as destination but it should
-    // be new plan.
-    assertNotSame("Same region plan should not come", regionPlan, newRegionPlan);
-    assertTrue("Destnation servers should be different.", !(regionPlan.getDestination().equals(
-        newRegionPlan.getDestination())));
   }
   
   /**
@@ -677,6 +696,35 @@ public class TestAssignmentManager {
   }
   
   /**
+   * Test the scenario when the master is in failover and trying to process a
+   * region which is in Opening state on a dead RS. Master should immediately
+   * assign the region and not wait for Timeout Monitor.(Hbase-5882).
+   */
+  @Test
+  public void testRegionInOpeningStateOnDeadRSWhileMasterFailover() throws IOException,
+      KeeperException, ServiceException, InterruptedException {
+    AssignmentManagerWithExtrasForTesting am = setUpMockedAssignmentManager(this.server,
+        this.serverManager);
+    ZKAssign.createNodeOffline(this.watcher, REGIONINFO, SERVERNAME_A);
+    int version = ZKAssign.getVersion(this.watcher, REGIONINFO);
+    ZKAssign.transitionNode(this.watcher, REGIONINFO, SERVERNAME_A, EventType.M_ZK_REGION_OFFLINE,
+        EventType.RS_ZK_REGION_OPENING, version);
+    RegionTransition rt = RegionTransition.createRegionTransition(EventType.RS_ZK_REGION_OPENING,
+        REGIONINFO.getRegionName(), SERVERNAME_A, HConstants.EMPTY_BYTE_ARRAY);
+    Map<ServerName, List<Pair<HRegionInfo, Result>>> deadServers = 
+      new HashMap<ServerName, List<Pair<HRegionInfo, Result>>>();
+    deadServers.put(SERVERNAME_A, null);
+    version = ZKAssign.getVersion(this.watcher, REGIONINFO);
+    am.gate.set(false);
+    am.processRegionsInTransition(rt, REGIONINFO, deadServers, version);
+    // Waiting for the assignment to get completed.
+    while (!am.gate.get()) {
+      Thread.sleep(10);
+    }
+    assertTrue("The region should be assigned immediately.", null != am.regionPlans.get(REGIONINFO
+        .getEncodedName()));
+  }
+  /**
    * Creates a new ephemeral node in the SPLITTING state for the specified region.
    * Create it ephemeral in case regionserver dies mid-split.
    *
@@ -810,7 +858,13 @@ public class TestAssignmentManager {
       while (this.gate.get()) Threads.sleep(1);
       super.processRegionsInTransition(rt, regionInfo, deadServers, expectedVersion);
     }
-    
+
+    @Override
+    public void assign(HRegionInfo region, boolean setOfflineInZK, boolean forceNewPlan,
+        boolean hijack) {
+      super.assign(region, setOfflineInZK, forceNewPlan, hijack);
+      this.gate.set(true);
+    }
     /** reset the watcher */
     void setWatcher(ZooKeeperWatcher watcher) {
       this.watcher = watcher;