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/18 19:50:32 UTC
svn commit: r1340187 - 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: Fri May 18 17:50:32 2012
New Revision: 1340187
URL: http://svn.apache.org/viewvc?rev=1340187&view=rev
Log:
HBASE-5546 Master assigns region in the original region server when opening region failed (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=1340187&r1=1340186&r2=1340187&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 Fri May 18 17:50:32 2012
@@ -857,6 +857,9 @@ public class AssignmentManager extends Z
}
// Handle this the same as if it were opened and then closed.
regionState.update(RegionState.State.CLOSED, createTime, sn);
+ // When there are more than one region server a new RS is selected as the
+ // destination and the same is updated in the regionplan. (HBASE-5546)
+ getRegionPlan(regionState, sn, true);
this.executorService.submit(new ClosedRegionHandler(master,
this, regionState.getRegion()));
break;
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=1340187&r1=1340186&r2=1340187&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 Fri May 18 17:50:32 2012
@@ -50,6 +50,8 @@ import org.apache.hadoop.hbase.client.Re
import org.apache.hadoop.hbase.executor.EventHandler.EventType;
import org.apache.hadoop.hbase.executor.ExecutorService;
import org.apache.hadoop.hbase.executor.ExecutorService.ExecutorType;
+import org.apache.hadoop.hbase.master.AssignmentManager.RegionState;
+import org.apache.hadoop.hbase.master.AssignmentManager.RegionState.State;
import org.apache.hadoop.hbase.master.handler.ServerShutdownHandler;
import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.GetRequest;
@@ -98,6 +100,7 @@ public class TestAssignmentManager {
private Server server;
private ServerManager serverManager;
private ZooKeeperWatcher watcher;
+ private LoadBalancer balancer;
@BeforeClass
public static void beforeClass() throws Exception {
@@ -604,6 +607,74 @@ public class TestAssignmentManager {
assertEquals("Aborted", e.getLocalizedMessage());
}
}
+ /**
+ * TestCase verifies that the regionPlan is updated whenever a region fails to open
+ * and the master tries to process RS_ZK_FAILED_OPEN state.(HBASE-5546).
+ */
+ @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());
+ }
+ // 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())));
+ }
+
+ /**
+ * Mocked load balancer class used in the testcase to make sure that the testcase waits until
+ * random assignment is called and the gate variable is set to true.
+ */
+ public static class MockedLoadBalancer extends DefaultLoadBalancer {
+ private AtomicBoolean gate;
+
+ public void setGateVariable(AtomicBoolean gate) {
+ this.gate = gate;
+ }
+
+ @Override
+ public ServerName randomAssignment(HRegionInfo regionInfo, List<ServerName> servers) {
+ ServerName randomServerName = super.randomAssignment(regionInfo, servers);
+ this.gate.set(true);
+ return randomServerName;
+ }
+ }
/**
* Creates a new ephemeral node in the SPLITTING state for the specified region.
@@ -696,10 +767,9 @@ public class TestAssignmentManager {
Mockito.when(ct.getConnection()).thenReturn(connection);
// Create and startup an executor. Used by AM handling zk callbacks.
ExecutorService executor = startupMasterExecutor("mockedAMExecutor");
- LoadBalancer balancer = LoadBalancerFactory.getLoadBalancer(server
- .getConfiguration());
+ this.balancer = LoadBalancerFactory.getLoadBalancer(server.getConfiguration());
AssignmentManagerWithExtrasForTesting am = new AssignmentManagerWithExtrasForTesting(
- server, manager, ct, balancer, executor);
+ server, manager, ct, this.balancer, executor);
return am;
}