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;