Author: jdcryans
Date: Wed Jun 15 18:21:14 2011
New Revision: 1136140
URL: http://svn.apache.org/viewvc?rev=1136140&view=rev
Log:
HBASE-3789 Cleanup the locking contention in the master
Modified:
hbase/trunk/CHANGES.txt
hbase/trunk/src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java
hbase/trunk/src/main/java/org/apache/hadoop/hbase/regionserver/SplitTransaction.java
hbase/trunk/src/main/java/org/apache/hadoop/hbase/regionserver/handler/CloseRegionHandler.java
hbase/trunk/src/main/java/org/apache/hadoop/hbase/util/HBaseFsck.java
hbase/trunk/src/main/java/org/apache/hadoop/hbase/util/HBaseFsckRepair.java
hbase/trunk/src/main/java/org/apache/hadoop/hbase/zookeeper/RegionServerTracker.java
hbase/trunk/src/main/java/org/apache/hadoop/hbase/zookeeper/ZKAssign.java
hbase/trunk/src/main/java/org/apache/hadoop/hbase/zookeeper/ZKUtil.java
hbase/trunk/src/main/java/org/apache/hadoop/hbase/zookeeper/ZooKeeperWatcher.java
hbase/trunk/src/test/java/org/apache/hadoop/hbase/MiniHBaseCluster.java
hbase/trunk/src/test/java/org/apache/hadoop/hbase/regionserver/TestSplitTransactionOnCluster.java
hbase/trunk/src/test/java/org/apache/hadoop/hbase/util/TestHBaseFsck.java
Modified: hbase/trunk/CHANGES.txt
URL:
http://svn.apache.org/viewvc/hbase/trunk/CHANGES.txt?rev=1136140&r1=1136139&r2=1136140&view=diff
==============================================================================
--- hbase/trunk/CHANGES.txt (original)
+++ hbase/trunk/CHANGES.txt Wed Jun 15 18:21:14 2011
@@ -263,6 +263,7 @@ Release 0.91.0 - Unreleased
HBASE-3982 Improvements to TestHFileSeek
HBASE-3940 HBase daemons should log version info at startup and possibly
periodically (Li Pi)
+ HBASE-3789 Cleanup the locking contention in the master
TASKS
HBASE-3559 Move report of split to master OFF the heartbeat channel
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=1136140&r1=1136139&r2=1136140&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
Wed Jun 15 18:21:14 2011
@@ -38,6 +38,7 @@ import java.util.TreeMap;
import java.util.TreeSet;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -70,7 +71,6 @@ import org.apache.hadoop.hbase.util.Writ
import org.apache.hadoop.hbase.zookeeper.ZKAssign;
import org.apache.hadoop.hbase.zookeeper.ZKTable;
import org.apache.hadoop.hbase.zookeeper.ZKUtil;
-import org.apache.hadoop.hbase.zookeeper.ZKUtil.NodeAndData;
import org.apache.hadoop.hbase.zookeeper.ZooKeeperListener;
import org.apache.hadoop.hbase.zookeeper.ZooKeeperWatcher;
import org.apache.hadoop.io.Writable;
@@ -446,10 +446,17 @@ public class AssignmentManager extends Z
if (!isInStateForSplitting(regionState)) break;
// If null, add SPLITTING state before going to SPLIT
if (regionState == null) {
- LOG.info("Received SPLIT for region " + prettyPrintedRegionName +
- " from server " + sn +
- " but region was not first in SPLITTING state; continuing");
- addSplittingToRIT(sn, encodedName);
+ regionState = addSplittingToRIT(sn, encodedName);
+ String message = "Received SPLIT for region " +
prettyPrintedRegionName +
+ " from server " + sn;
+ // If still null, it means we cannot find it and it was already
processed
+ if (regionState == null) {
+ LOG.warn(message + " but it doesn't exist anymore," +
+ " probably already processed its split");
+ break;
+ }
+ LOG.info(message +
+ " but region was not first in SPLITTING state; continuing");
}
// Check it has daughters.
byte [] payload = data.getPayload();
@@ -589,8 +596,10 @@ public class AssignmentManager extends Z
RegionState regionState = null;
synchronized (this.regions) {
regionState = findHRegionInfoThenAddToRIT(serverName, encodedName);
- regionState.update(RegionState.State.SPLITTING,
+ if (regionState != null) {
+ regionState.update(RegionState.State.SPLITTING,
System.currentTimeMillis(), serverName);
+ }
}
return regionState;
}
@@ -689,16 +698,14 @@ public class AssignmentManager extends Z
@Override
public void nodeCreated(String path) {
if(path.startsWith(watcher.assignmentZNode)) {
- synchronized(regionsInTransition) {
- try {
- RegionTransitionData data = ZKAssign.getData(watcher, path);
- if(data == null) {
- return;
- }
- handleRegion(data);
- } catch (KeeperException e) {
- master.abort("Unexpected ZK exception reading unassigned node data",
e);
+ try {
+ RegionTransitionData data = ZKAssign.getData(watcher, path);
+ if (data == null) {
+ return;
}
+ handleRegion(data);
+ } catch (KeeperException e) {
+ master.abort("Unexpected ZK exception reading unassigned node data",
e);
}
}
}
@@ -718,16 +725,14 @@ public class AssignmentManager extends Z
@Override
public void nodeDataChanged(String path) {
if(path.startsWith(watcher.assignmentZNode)) {
- synchronized(regionsInTransition) {
- try {
- RegionTransitionData data = ZKAssign.getData(watcher, path);
- if (data == null) {
- return;
- }
- handleRegion(data);
- } catch (KeeperException e) {
- master.abort("Unexpected ZK exception reading unassigned node data",
e);
+ try {
+ RegionTransitionData data = ZKAssign.getData(watcher, path);
+ if (data == null) {
+ return;
}
+ handleRegion(data);
+ } catch (KeeperException e) {
+ master.abort("Unexpected ZK exception reading unassigned node data",
e);
}
}
}
@@ -762,23 +767,17 @@ public class AssignmentManager extends Z
* <ol>
* <li>Watch the node for further children changed events</li>
* <li>Watch all new children for changed events</li>
- * <li>Read all children and handle them</li>
* </ol>
*/
@Override
public void nodeChildrenChanged(String path) {
if(path.equals(watcher.assignmentZNode)) {
- synchronized(regionsInTransition) {
- try {
- List<NodeAndData> newNodes = ZKUtil.watchAndGetNewChildren(watcher,
- watcher.assignmentZNode);
- for(NodeAndData newNode : newNodes) {
- LOG.debug("Handling new unassigned node: " + newNode);
- handleRegion(RegionTransitionData.fromBytes(newNode.getData()));
- }
- } catch(KeeperException e) {
- master.abort("Unexpected ZK exception reading unassigned children",
e);
- }
+ try {
+ // Just make sure we see the changes for the new znodes
+ ZKUtil.listChildrenAndWatchThem(watcher,
+ watcher.assignmentZNode);
+ } catch(KeeperException e) {
+ master.abort("Unexpected ZK exception reading unassigned children", e);
}
}
}
@@ -843,9 +842,7 @@ public class AssignmentManager extends Z
rs = this.regionsInTransition.get(e.getKey());
}
if (rs == null) continue;
- synchronized (rs) {
- rs.updateTimestampToNow();
- }
+ rs.updateTimestampToNow();
}
}
@@ -1311,9 +1308,20 @@ public class AssignmentManager extends Z
synchronized (regionsInTransition) {
state = regionsInTransition.get(encodedName);
if (state == null) {
+
+ // Create the znode in CLOSING state
+ try {
+ ZKAssign.createNodeClosing(
+ master.getZooKeeper(), region, master.getServerName());
+ } catch (KeeperException e) {
+ master.abort("Unexpected ZK exception creating node CLOSING", e);
+ return;
+ }
state = new RegionState(region, RegionState.State.PENDING_CLOSE);
regionsInTransition.put(encodedName, state);
} else if (force && state.isPendingClose()) {
+ // JD 05/25/11
+ // in my experience this is useless, when this happens it just spins
LOG.debug("Attempting to unassign region " +
region.getRegionNameAsString() + " which is already pending close "
+ "but forcing an additional close");
@@ -1893,9 +1901,7 @@ public class AssignmentManager extends Z
" has been CLOSED for too long, waiting on queued " +
"ClosedRegionHandler to run or server shutdown");
// Update our timestamp.
- synchronized(regionState) {
- regionState.update(regionState.getState());
- }
+ regionState.updateTimestampToNow();
break;
case OFFLINE:
LOG.info("Region has been OFFLINE for too long, " +
@@ -2320,10 +2326,13 @@ public class AssignmentManager extends Z
}
private State state;
- private long stamp;
+ // Many threads can update the state at the stamp at the same time
+ private final AtomicLong stamp;
private ServerName serverName;
- public RegionState() {}
+ public RegionState() {
+ this.stamp = new AtomicLong(System.currentTimeMillis());
+ }
RegionState(HRegionInfo region, State state) {
this(region, state, System.currentTimeMillis(), null);
@@ -2332,24 +2341,28 @@ public class AssignmentManager extends Z
RegionState(HRegionInfo region, State state, long stamp, ServerName
serverName) {
this.region = region;
this.state = state;
- this.stamp = stamp;
+ this.stamp = new AtomicLong(stamp);
this.serverName = serverName;
}
public void update(State state, long stamp, ServerName serverName) {
this.state = state;
- this.stamp = stamp;
+ updateTimestamp(stamp);
this.serverName = serverName;
}
public void update(State state) {
this.state = state;
- this.stamp = System.currentTimeMillis();
+ updateTimestampToNow();
this.serverName = null;
}
+ public void updateTimestamp(long stamp) {
+ this.stamp.set(stamp);
+ }
+
public void updateTimestampToNow() {
- this.stamp = System.currentTimeMillis();
+ this.stamp.set(System.currentTimeMillis());
}
public State getState() {
@@ -2357,7 +2370,7 @@ public class AssignmentManager extends Z
}
public long getStamp() {
- return stamp;
+ return stamp.get();
}
public HRegionInfo getRegion() {
@@ -2413,14 +2426,14 @@ public class AssignmentManager extends Z
region = new HRegionInfo();
region.readFields(in);
state = State.valueOf(in.readUTF());
- stamp = in.readLong();
+ stamp.set(in.readLong());
}
@Override
public void write(DataOutput out) throws IOException {
region.write(out);
out.writeUTF(state.name());
- out.writeLong(stamp);
+ out.writeLong(stamp.get());
}
}
Modified:
hbase/trunk/src/main/java/org/apache/hadoop/hbase/regionserver/SplitTransaction.java
URL:
http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/regionserver/SplitTransaction.java?rev=1136140&r1=1136139&r2=1136140&view=diff
==============================================================================
---
hbase/trunk/src/main/java/org/apache/hadoop/hbase/regionserver/SplitTransaction.java
(original)
+++
hbase/trunk/src/main/java/org/apache/hadoop/hbase/regionserver/SplitTransaction.java
Wed Jun 15 18:21:14 2011
@@ -304,14 +304,36 @@ public class SplitTransaction {
// Tell master about split by updating zk. If we fail, abort.
if (server != null && server.getZooKeeper() != null) {
try {
- transitionNodeSplit(server.getZooKeeper(), parent.getRegionInfo(),
- a.getRegionInfo(), b.getRegionInfo(), server.getServerName(),
- this.znodeVersion);
+ this.znodeVersion = transitionNodeSplit(server.getZooKeeper(),
+ parent.getRegionInfo(), a.getRegionInfo(), b.getRegionInfo(),
+ server.getServerName(), this.znodeVersion);
+
+ int spins = 0;
+ // Now wait for the master to process the split. We know it's done
+ // when the znode is deleted. The reason we keep tickling the znode is
+ // that it's possible for the master to miss an event.
+ do {
+ if (spins % 10 == 0) {
+ LOG.info("Still waiting on the master to process the split for " +
+ this.parent.getRegionInfo().getEncodedName());
+ }
+ Thread.sleep(100);
+ // When this returns -1 it means the znode doesn't exist
+ this.znodeVersion = tickleNodeSplit(server.getZooKeeper(),
+ parent.getRegionInfo(), a.getRegionInfo(), b.getRegionInfo(),
+ server.getServerName(), this.znodeVersion);
+ spins++;
+ } while (this.znodeVersion != -1);
} catch (Exception e) {
+ if (e instanceof InterruptedException) {
+ Thread.currentThread().interrupt();
+ }
server.abort("Failed telling master about split", e);
}
}
+
+
// Coprocessor callback
if (this.parent.getCoprocessorHost() != null) {
this.parent.getCoprocessorHost().postSplit(a,b);
@@ -701,13 +723,10 @@ public class SplitTransaction {
RegionTransitionData data =
new RegionTransitionData(EventType.RS_ZK_REGION_SPLITTING,
region.getRegionName(), serverName);
- // This synchronization is copied from ZKAssign.
- synchronized(zkw.getNodes()) {
- String node = ZKAssign.getNodeName(zkw, region.getEncodedName());
- zkw.getNodes().add(node);
- if (!ZKUtil.createEphemeralNodeAndWatch(zkw, node, data.getBytes())) {
- throw new IOException("Failed create of ephemeral " + node);
- }
+
+ String node = ZKAssign.getNodeName(zkw, region.getEncodedName());
+ if (!ZKUtil.createEphemeralNodeAndWatch(zkw, node, data.getBytes())) {
+ throw new IOException("Failed create of ephemeral " + node);
}
// Transition node from SPLITTING to SPLITTING and pick up version so we
// can be sure this znode is ours; version is needed deleting.
@@ -764,4 +783,14 @@ public class SplitTransaction {
return ZKAssign.transitionNode(zkw, parent, serverName,
EventType.RS_ZK_REGION_SPLITTING, EventType.RS_ZK_REGION_SPLITTING,
version);
}
+
+ private static int tickleNodeSplit(ZooKeeperWatcher zkw,
+ HRegionInfo parent, HRegionInfo a, HRegionInfo b, ServerName serverName,
+ final int znodeVersion)
+ throws KeeperException, IOException {
+ byte [] payload = Writables.getBytes(a, b);
+ return ZKAssign.transitionNode(zkw, parent, serverName,
+ EventType.RS_ZK_REGION_SPLIT, EventType.RS_ZK_REGION_SPLIT,
+ znodeVersion, payload);
+ }
}
Modified:
hbase/trunk/src/main/java/org/apache/hadoop/hbase/regionserver/handler/CloseRegionHandler.java
URL:
http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/regionserver/handler/CloseRegionHandler.java?rev=1136140&r1=1136139&r2=1136140&view=diff
==============================================================================
---
hbase/trunk/src/main/java/org/apache/hadoop/hbase/regionserver/handler/CloseRegionHandler.java
(original)
+++
hbase/trunk/src/main/java/org/apache/hadoop/hbase/regionserver/handler/CloseRegionHandler.java
Wed Jun 15 18:21:14 2011
@@ -109,7 +109,7 @@ public class CloseRegionHandler extends
int expectedVersion = FAILED;
if (this.zk) {
- expectedVersion = setClosingState();
+ expectedVersion = getCurrentVersion();
if (expectedVersion == FAILED) return;
}
@@ -169,16 +169,16 @@ public class CloseRegionHandler extends
}
/**
- * Create ZK node in CLOSING state.
- * @return The expectedVersion. If -1, we failed setting CLOSING.
+ * Get the node's current version
+ * @return The expectedVersion. If -1, we failed getting the node
*/
- private int setClosingState() {
+ private int getCurrentVersion() {
int expectedVersion = FAILED;
try {
- if ((expectedVersion = ZKAssign.createNodeClosing(
- server.getZooKeeper(), regionInfo, server.getServerName())) ==
FAILED) {
- LOG.warn("Error creating node in CLOSING state, aborting close of " +
- regionInfo.getRegionNameAsString());
+ if ((expectedVersion = ZKAssign.getVersion(
+ server.getZooKeeper(), regionInfo)) == FAILED) {
+ LOG.warn("Error getting node's version in CLOSING state," +
+ " aborting close of " + regionInfo.getRegionNameAsString());
}
} catch (KeeperException e) {
LOG.warn("Error creating node in CLOSING state, aborting close of " +
Modified: hbase/trunk/src/main/java/org/apache/hadoop/hbase/util/HBaseFsck.java
URL:
http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/util/HBaseFsck.java?rev=1136140&r1=1136139&r2=1136140&view=diff
==============================================================================
--- hbase/trunk/src/main/java/org/apache/hadoop/hbase/util/HBaseFsck.java
(original)
+++ hbase/trunk/src/main/java/org/apache/hadoop/hbase/util/HBaseFsck.java Wed
Jun 15 18:21:14 2011
@@ -95,6 +95,7 @@ public class HBaseFsck {
// Empty regioninfo qualifiers in .META.
private Set<Result> emptyRegionInfoQualifiers = new HashSet<Result>();
private int numThreads = MAX_NUM_THREADS;
+ private final HBaseAdmin admin;
ThreadPoolExecutor executor; // threads to retrieve data from regionservers
@@ -109,7 +110,7 @@ public class HBaseFsck {
throws MasterNotRunningException, ZooKeeperConnectionException,
IOException {
this.conf = conf;
- HBaseAdmin admin = new HBaseAdmin(conf);
+ admin = new HBaseAdmin(conf);
status = admin.getMaster().getClusterStatus();
connection = admin.getConnection();
@@ -466,7 +467,7 @@ public class HBaseFsck {
if (shouldFix()) {
errors.print("Trying to fix unassigned region...");
setShouldRerun();
- HBaseFsckRepair.fixUnassigned(this.conf, hbi.metaEntry);
+ HBaseFsckRepair.fixUnassigned(this.admin, hbi.metaEntry);
}
} else if (inMeta && inHdfs && isDeployed && !shouldBeDeployed) {
errors.reportError(ERROR_CODE.SHOULD_NOT_BE_DEPLOYED, "Region "
@@ -481,7 +482,7 @@ public class HBaseFsck {
if (shouldFix()) {
errors.print("Trying to fix assignment error...");
setShouldRerun();
- HBaseFsckRepair.fixDupeAssignment(this.conf, hbi.metaEntry,
hbi.deployedOn);
+ HBaseFsckRepair.fixDupeAssignment(this.admin, hbi.metaEntry,
hbi.deployedOn);
}
} else if (inMeta && inHdfs && isDeployed && !deploymentMatchesMeta) {
errors.reportError(ERROR_CODE.SERVER_DOES_NOT_MATCH_META, "Region "
@@ -492,7 +493,7 @@ public class HBaseFsck {
if (shouldFix()) {
errors.print("Trying to fix assignment error...");
setShouldRerun();
- HBaseFsckRepair.fixDupeAssignment(this.conf, hbi.metaEntry,
hbi.deployedOn);
+ HBaseFsckRepair.fixDupeAssignment(this.admin, hbi.metaEntry,
hbi.deployedOn);
}
} else {
errors.reportError(ERROR_CODE.UNKNOWN, "Region " + descriptiveName +
@@ -735,7 +736,7 @@ public class HBaseFsck {
errors.print("Trying to fix a problem with .META...");
setShouldRerun();
// try to fix it (treat it as unassigned region)
- HBaseFsckRepair.fixUnassigned(conf, root.metaEntry);
+ HBaseFsckRepair.fixUnassigned(this.admin, root.metaEntry);
}
}
// If there are more than one regions pretending to hold the .META.
@@ -749,7 +750,7 @@ public class HBaseFsck {
for (HbckInfo mRegion : metaRegions) {
deployedOn.add(mRegion.metaEntry.regionServer);
}
- HBaseFsckRepair.fixDupeAssignment(conf, root.metaEntry, deployedOn);
+ HBaseFsckRepair.fixDupeAssignment(this.admin, root.metaEntry,
deployedOn);
}
}
// rerun hbck with hopefully fixed META
Modified:
hbase/trunk/src/main/java/org/apache/hadoop/hbase/util/HBaseFsckRepair.java
URL:
http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/util/HBaseFsckRepair.java?rev=1136140&r1=1136139&r2=1136140&view=diff
==============================================================================
--- hbase/trunk/src/main/java/org/apache/hadoop/hbase/util/HBaseFsckRepair.java
(original)
+++ hbase/trunk/src/main/java/org/apache/hadoop/hbase/util/HBaseFsckRepair.java
Wed Jun 15 18:21:14 2011
@@ -23,16 +23,14 @@ import java.io.IOException;
import java.util.List;
import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.HRegionInfo;
import org.apache.hadoop.hbase.NotServingRegionException;
import org.apache.hadoop.hbase.ServerName;
import org.apache.hadoop.hbase.ZooKeeperConnectionException;
+import org.apache.hadoop.hbase.client.HBaseAdmin;
import org.apache.hadoop.hbase.client.HConnection;
import org.apache.hadoop.hbase.client.HConnectionManager;
-import org.apache.hadoop.hbase.client.HConnectionManager.HConnectable;
import org.apache.hadoop.hbase.ipc.HRegionInterface;
-import org.apache.hadoop.hbase.zookeeper.ZKAssign;
import org.apache.zookeeper.KeeperException;
public class HBaseFsckRepair {
@@ -41,14 +39,14 @@ public class HBaseFsckRepair {
* Fix dupe assignment by doing silent closes on each RS hosting the region
* and then force ZK unassigned node to OFFLINE to trigger assignment by
* master.
- * @param conf
+ * @param admin
* @param region
* @param servers
* @throws IOException
* @throws KeeperException
* @throws InterruptedException
*/
- public static void fixDupeAssignment(Configuration conf, HRegionInfo region,
+ public static void fixDupeAssignment(HBaseAdmin admin, HRegionInfo region,
List<ServerName> servers)
throws IOException, KeeperException, InterruptedException {
@@ -56,45 +54,33 @@ public class HBaseFsckRepair {
// Close region on the servers silently
for(ServerName server : servers) {
- closeRegionSilentlyAndWait(conf, server, actualRegion);
+ closeRegionSilentlyAndWait(admin.getConfiguration(), server,
actualRegion);
}
// Force ZK node to OFFLINE so master assigns
- forceOfflineInZK(conf, actualRegion);
+ forceOfflineInZK(admin, actualRegion);
}
/**
* Fix unassigned by creating/transition the unassigned ZK node for this
* region to OFFLINE state with a special flag to tell the master that this
* is a forced operation by HBCK.
- * @param conf
+ * @param admin
* @param region
* @throws IOException
* @throws KeeperException
*/
- public static void fixUnassigned(Configuration conf, HRegionInfo region)
+ public static void fixUnassigned(HBaseAdmin admin, HRegionInfo region)
throws IOException, KeeperException {
HRegionInfo actualRegion = new HRegionInfo(region);
// Force ZK node to OFFLINE so master assigns
- forceOfflineInZK(conf, actualRegion);
+ forceOfflineInZK(admin, actualRegion);
}
- private static void forceOfflineInZK(Configuration conf, final HRegionInfo
region)
+ private static void forceOfflineInZK(HBaseAdmin admin, final HRegionInfo
region)
throws ZooKeeperConnectionException, KeeperException, IOException {
- HConnectionManager.execute(new HConnectable<Void>(conf) {
- @Override
- public Void connect(HConnection connection) throws IOException {
- try {
- ZKAssign.createOrForceNodeOffline(
- connection.getZooKeeperWatcher(),
- region, HConstants.HBCK_CODE_SERVERNAME);
- } catch (KeeperException ke) {
- throw new IOException(ke);
- }
- return null;
- }
- });
+ admin.assign(region.getRegionName(), true);
}
private static void closeRegionSilentlyAndWait(Configuration conf,
Modified:
hbase/trunk/src/main/java/org/apache/hadoop/hbase/zookeeper/RegionServerTracker.java
URL:
http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/zookeeper/RegionServerTracker.java?rev=1136140&r1=1136139&r2=1136140&view=diff
==============================================================================
---
hbase/trunk/src/main/java/org/apache/hadoop/hbase/zookeeper/RegionServerTracker.java
(original)
+++
hbase/trunk/src/main/java/org/apache/hadoop/hbase/zookeeper/RegionServerTracker.java
Wed Jun 15 18:21:14 2011
@@ -66,16 +66,16 @@ public class RegionServerTracker extends
*/
public void start() throws KeeperException, IOException {
watcher.registerListener(this);
- List<NodeAndData> servers =
- ZKUtil.watchAndGetNewChildren(watcher, watcher.rsZNode);
+ List<String> servers =
+ ZKUtil.listChildrenAndWatchThem(watcher, watcher.rsZNode);
add(servers);
}
- private void add(final List<NodeAndData> servers) throws IOException {
+ private void add(final List<String> servers) throws IOException {
synchronized(this.regionServers) {
this.regionServers.clear();
- for (NodeAndData n: servers) {
- ServerName sn = new ServerName(ZKUtil.getNodeName(n.getNode()));
+ for (String n: servers) {
+ ServerName sn = new ServerName(ZKUtil.getNodeName(n));
this.regionServers.add(sn);
}
}
@@ -107,8 +107,8 @@ public class RegionServerTracker extends
public void nodeChildrenChanged(String path) {
if (path.equals(watcher.rsZNode)) {
try {
- List<NodeAndData> servers =
- ZKUtil.watchAndGetNewChildren(watcher, watcher.rsZNode);
+ List<String> servers =
+ ZKUtil.listChildrenAndWatchThem(watcher, watcher.rsZNode);
add(servers);
} catch (IOException e) {
abortable.abort("Unexpected zk exception getting RS nodes", e);
Modified:
hbase/trunk/src/main/java/org/apache/hadoop/hbase/zookeeper/ZKAssign.java
URL:
http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/zookeeper/ZKAssign.java?rev=1136140&r1=1136139&r2=1136140&view=diff
==============================================================================
--- hbase/trunk/src/main/java/org/apache/hadoop/hbase/zookeeper/ZKAssign.java
(original)
+++ hbase/trunk/src/main/java/org/apache/hadoop/hbase/zookeeper/ZKAssign.java
Wed Jun 15 18:21:14 2011
@@ -143,11 +143,8 @@ public class ZKAssign {
region.getEncodedName() + " in OFFLINE state"));
RegionTransitionData data = new RegionTransitionData(event,
region.getRegionName(), serverName);
- synchronized(zkw.getNodes()) {
- String node = getNodeName(zkw, region.getEncodedName());
- zkw.getNodes().add(node);
- ZKUtil.createAndWatch(zkw, node, data.getBytes());
- }
+ String node = getNodeName(zkw, region.getEncodedName());
+ ZKUtil.createAndWatch(zkw, node, data.getBytes());
}
/**
@@ -173,11 +170,8 @@ public class ZKAssign {
region.getEncodedName() + " with OFFLINE state"));
RegionTransitionData data = new RegionTransitionData(
EventType.M_ZK_REGION_OFFLINE, region.getRegionName(), serverName);
- synchronized(zkw.getNodes()) {
- String node = getNodeName(zkw, region.getEncodedName());
- zkw.getNodes().add(node);
- ZKUtil.asyncCreate(zkw, node, data.getBytes(), cb, ctx);
- }
+ String node = getNodeName(zkw, region.getEncodedName());
+ ZKUtil.asyncCreate(zkw, node, data.getBytes(), cb, ctx);
}
/**
@@ -205,11 +199,8 @@ public class ZKAssign {
region.getEncodedName() + " to OFFLINE state"));
RegionTransitionData data = new RegionTransitionData(
EventType.M_ZK_REGION_OFFLINE, region.getRegionName(), serverName);
- synchronized(zkw.getNodes()) {
- String node = getNodeName(zkw, region.getEncodedName());
- zkw.getNodes().add(node);
- ZKUtil.setData(zkw, node, data.getBytes());
- }
+ String node = getNodeName(zkw, region.getEncodedName());
+ ZKUtil.setData(zkw, node, data.getBytes());
}
@@ -238,25 +229,22 @@ public class ZKAssign {
region.getEncodedName() + " with OFFLINE state"));
RegionTransitionData data = new RegionTransitionData(
EventType.M_ZK_REGION_OFFLINE, region.getRegionName(), serverName);
- synchronized(zkw.getNodes()) {
- String node = getNodeName(zkw, region.getEncodedName());
- zkw.sync(node);
- zkw.getNodes().add(node);
- int version = ZKUtil.checkExists(zkw, node);
- if(version == -1) {
- ZKUtil.createAndWatch(zkw, node, data.getBytes());
+ String node = getNodeName(zkw, region.getEncodedName());
+ zkw.sync(node);
+ int version = ZKUtil.checkExists(zkw, node);
+ if (version == -1) {
+ ZKUtil.createAndWatch(zkw, node, data.getBytes());
+ } else {
+ if (!ZKUtil.setData(zkw, node, data.getBytes(), version)) {
+ return false;
} else {
- if (!ZKUtil.setData(zkw, node, data.getBytes(), version)) {
- return false;
- } else {
- // We successfully forced to OFFLINE, reset watch and handle if
- // the state changed in between our set and the watch
- RegionTransitionData curData =
+ // We successfully forced to OFFLINE, reset watch and handle if
+ // the state changed in between our set and the watch
+ RegionTransitionData curData =
ZKAssign.getData(zkw, region.getEncodedName());
- if (curData.getEventType() != data.getEventType()) {
- // state changed, need to process
- return false;
- }
+ if (curData.getEventType() != data.getEventType()) {
+ // state changed, need to process
+ return false;
}
}
}
@@ -408,19 +396,15 @@ public class ZKAssign {
" state but node is in " + data.getEventType() + " state"));
return false;
}
- synchronized(zkw.getNodes()) {
- // TODO: Does this go here or only if we successfully delete node?
- zkw.getNodes().remove(node);
- if(!ZKUtil.deleteNode(zkw, node, stat.getVersion())) {
- LOG.warn(zkw.prefix("Attempting to delete " +
+ if(!ZKUtil.deleteNode(zkw, node, stat.getVersion())) {
+ LOG.warn(zkw.prefix("Attempting to delete " +
"unassigned node in " + expectedState +
- " state but after verifying state, we got a version mismatch"));
- return false;
- }
- LOG.debug(zkw.prefix("Successfully deleted unassigned node for region " +
- regionName + " in expected state " + expectedState));
- return true;
+ " state but after verifying state, we got a version mismatch"));
+ return false;
}
+ LOG.debug(zkw.prefix("Successfully deleted unassigned node for region " +
+ regionName + " in expected state " + expectedState));
+ return true;
}
/**
@@ -473,11 +457,8 @@ public class ZKAssign {
RegionTransitionData data = new RegionTransitionData(
EventType.RS_ZK_REGION_CLOSING, region.getRegionName(), serverName);
- synchronized (zkw.getNodes()) {
- String node = getNodeName(zkw, region.getEncodedName());
- zkw.getNodes().add(node);
- return ZKUtil.createAndWatch(zkw, node, data.getBytes());
- }
+ String node = getNodeName(zkw, region.getEncodedName());
+ return ZKUtil.createAndWatch(zkw, node, data.getBytes());
}
/**
@@ -783,6 +764,19 @@ public class ZKAssign {
}
/**
+ * Get the version of the specified znode
+ * @param zkw zk reference
+ * @param region region's info
+ * @return the version of the znode, -1 if it doesn't exist
+ * @throws KeeperException
+ */
+ public static int getVersion(ZooKeeperWatcher zkw, HRegionInfo region)
+ throws KeeperException {
+ String znode = getNodeName(zkw, region.getEncodedName());
+ return ZKUtil.checkExists(zkw, znode);
+ }
+
+ /**
* Delete the assignment node regardless of its current state.
* <p>
* Fail silent even if the node does not exist at all.
Modified:
hbase/trunk/src/main/java/org/apache/hadoop/hbase/zookeeper/ZKUtil.java
URL:
http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/zookeeper/ZKUtil.java?rev=1136140&r1=1136139&r2=1136140&view=diff
==============================================================================
--- hbase/trunk/src/main/java/org/apache/hadoop/hbase/zookeeper/ZKUtil.java
(original)
+++ hbase/trunk/src/main/java/org/apache/hadoop/hbase/zookeeper/ZKUtil.java Wed
Jun 15 18:21:14 2011
@@ -349,30 +349,6 @@ public class ZKUtil {
}
/**
- * Atomically add watches and read data from all unwatched unassigned nodes.
- *
- * <p>This works because master is the only person deleting nodes.
- */
- public static List<NodeAndData> watchAndGetNewChildren(ZooKeeperWatcher zkw,
- String baseNode)
- throws KeeperException {
- List<NodeAndData> newNodes = new ArrayList<NodeAndData>();
- synchronized(zkw.getNodes()) {
- List<String> nodes =
- ZKUtil.listChildrenAndWatchForNewChildren(zkw, baseNode);
- for(String node : nodes) {
- String nodePath = ZKUtil.joinZNode(baseNode, node);
- if(!zkw.getNodes().contains(nodePath)) {
- byte [] data = ZKUtil.getDataAndWatch(zkw, nodePath);
- newNodes.add(new NodeAndData(nodePath, data));
- zkw.getNodes().add(nodePath);
- }
- }
- }
- return newNodes;
- }
-
- /**
* Simple class to hold a node path and node data.
*/
public static class NodeAndData {
Modified:
hbase/trunk/src/main/java/org/apache/hadoop/hbase/zookeeper/ZooKeeperWatcher.java
URL:
http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/zookeeper/ZooKeeperWatcher.java?rev=1136140&r1=1136139&r2=1136140&view=diff
==============================================================================
---
hbase/trunk/src/main/java/org/apache/hadoop/hbase/zookeeper/ZooKeeperWatcher.java
(original)
+++
hbase/trunk/src/main/java/org/apache/hadoop/hbase/zookeeper/ZooKeeperWatcher.java
Wed Jun 15 18:21:14 2011
@@ -20,7 +20,6 @@
package org.apache.hadoop.hbase.zookeeper;
import java.io.IOException;
-import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
@@ -68,9 +67,6 @@ public class ZooKeeperWatcher implements
private final List<ZooKeeperListener> listeners =
new CopyOnWriteArrayList<ZooKeeperListener>();
- // set of unassigned nodes watched
- private Set<String> unassignedNodes = new HashSet<String>();
-
// node names
// base znode for this cluster
@@ -373,14 +369,6 @@ public class ZooKeeperWatcher implements
}
/**
- * Get the set of already watched unassigned nodes.
- * @return Set of Nodes.
- */
- public Set<String> getNodes() {
- return unassignedNodes;
- }
-
- /**
* Handles KeeperExceptions in client calls.
* <p>
* This may be temporary but for now this gives one place to deal with these.
Modified:
hbase/trunk/src/test/java/org/apache/hadoop/hbase/MiniHBaseCluster.java
URL:
http://svn.apache.org/viewvc/hbase/trunk/src/test/java/org/apache/hadoop/hbase/MiniHBaseCluster.java?rev=1136140&r1=1136139&r2=1136140&view=diff
==============================================================================
--- hbase/trunk/src/test/java/org/apache/hadoop/hbase/MiniHBaseCluster.java
(original)
+++ hbase/trunk/src/test/java/org/apache/hadoop/hbase/MiniHBaseCluster.java Wed
Jun 15 18:21:14 2011
@@ -97,13 +97,6 @@ public class MiniHBaseCluster {
this.user = User.getCurrent();
}
- @Override
- public boolean closeRegion(HRegionInfo region)
- throws IOException {
- if (TEST_SKIP_CLOSE) return true;
- return super.closeRegion(region);
- }
-
/*
* @param c
* @param currentfs We return this if we did not make a new one.
Modified:
hbase/trunk/src/test/java/org/apache/hadoop/hbase/regionserver/TestSplitTransactionOnCluster.java
URL:
http://svn.apache.org/viewvc/hbase/trunk/src/test/java/org/apache/hadoop/hbase/regionserver/TestSplitTransactionOnCluster.java?rev=1136140&r1=1136139&r2=1136140&view=diff
==============================================================================
---
hbase/trunk/src/test/java/org/apache/hadoop/hbase/regionserver/TestSplitTransactionOnCluster.java
(original)
+++
hbase/trunk/src/test/java/org/apache/hadoop/hbase/regionserver/TestSplitTransactionOnCluster.java
Wed Jun 15 18:21:14 2011
@@ -89,69 +89,6 @@ public class TestSplitTransactionOnClust
}
/**
- * Test what happens if master goes to balance a region just as regionserver
- * goes to split it. The PENDING_CLOSE state is the strange one since its
- * in the Master's head only, not out in zk. Test this case.
- * @throws IOException
- * @throws InterruptedException
- * @throws NodeExistsException
- * @throws KeeperException
- */
- @Test (timeout = 600000) public void testPendingCloseAndSplit()
- throws IOException, InterruptedException, NodeExistsException,
KeeperException {
- final byte [] tableName = Bytes.toBytes("pendingCloseAndSplit");
-
- // Create table then get the single region for our new table.
- HTable t = TESTING_UTIL.createTable(tableName, HConstants.CATALOG_FAMILY);
-
- List<HRegion> regions = cluster.getRegions(tableName);
- HRegionInfo hri = getAndCheckSingleTableRegion(regions);
-
- int tableRegionIndex = ensureTableRegionNotOnSameServerAsMeta(admin, hri);
-
- // Turn off balancer so it doesn't cut in and mess up our placements.
- this.admin.balanceSwitch(false);
- // Turn off the meta scanner so it don't remove parent on us.
- this.cluster.getMaster().setCatalogJanitorEnabled(false);
- try {
- // Add a bit of load up into the table so splittable.
- TESTING_UTIL.loadTable(t, HConstants.CATALOG_FAMILY);
- // Get region pre-split.
- HRegionServer server = cluster.getRegionServer(tableRegionIndex);
- printOutRegions(server, "Initial regions: ");
- int regionCount = server.getOnlineRegions().size();
- // Now send in a close of a region but first make the close on the
regionserver
- // a NOOP. This way the master has all the state of it going to close
- // but then a SPLITTING arrives. This is what we want to test.
- // Here is how we turn CLOSE into NOOP in test.
- MiniHBaseCluster.MiniHBaseClusterRegionServer.TEST_SKIP_CLOSE = true;
- this.cluster.getMaster().unassign(hri.getRegionName(), false);
- // Now try splitting and it should work.
- LOG.info("Running split on server " + server.toString());
- split(hri, server, regionCount);
- // Get daughters
- List<HRegion> daughters = this.cluster.getRegions(tableName);
- assertTrue(daughters.size() >= 2);
- // Assert the ephemeral node is gone in zk.
- String path =
ZKAssign.getNodeName(t.getConnection().getZooKeeperWatcher(),
- hri.getEncodedName());
- Stat stat = null;
- for (int i = 0; i < 10; i++) {
- stat =
t.getConnection().getZooKeeperWatcher().getZooKeeper().exists(path, false);
- LOG.info("Stat for znode path=" + path + ": " + stat);
- if (stat == null) break;
- org.apache.hadoop.hbase.util.Threads.sleep(100);
- }
- assertTrue(stat == null);
- } finally {
- // Set this flag back.
- MiniHBaseCluster.MiniHBaseClusterRegionServer.TEST_SKIP_CLOSE = false;
- admin.balanceSwitch(true);
- cluster.getMaster().setCatalogJanitorEnabled(true);
- }
- }
-
- /**
* A test that intentionally has master fail the processing of the split
message.
* Tests that the regionserver split ephemeral node gets cleaned up if it
* crashes and that after we process server shutdown, the daughters are up on
Modified:
hbase/trunk/src/test/java/org/apache/hadoop/hbase/util/TestHBaseFsck.java
URL:
http://svn.apache.org/viewvc/hbase/trunk/src/test/java/org/apache/hadoop/hbase/util/TestHBaseFsck.java?rev=1136140&r1=1136139&r2=1136140&view=diff
==============================================================================
--- hbase/trunk/src/test/java/org/apache/hadoop/hbase/util/TestHBaseFsck.java
(original)
+++ hbase/trunk/src/test/java/org/apache/hadoop/hbase/util/TestHBaseFsck.java
Wed Jun 15 18:21:14 2011
@@ -20,6 +20,7 @@
package org.apache.hadoop.hbase.util;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
import java.io.IOException;
import java.util.ArrayList;
@@ -37,7 +38,9 @@ import org.apache.hadoop.hbase.HConstant
import org.apache.hadoop.hbase.HRegionInfo;
import org.apache.hadoop.hbase.HServerAddress;
import org.apache.hadoop.hbase.HTableDescriptor;
+import org.apache.hadoop.hbase.RemoteExceptionHandler;
import org.apache.hadoop.hbase.ServerName;
+import org.apache.hadoop.hbase.UnknownRegionException;
import org.apache.hadoop.hbase.client.HTable;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.Result;
@@ -168,7 +171,14 @@ public class TestHBaseFsck {
Thread.sleep(1 * 1000);
ArrayList servers = new ArrayList();
servers.add(rsAddressOrig);
- HBaseFsckRepair.fixDupeAssignment(conf, hriOrig, servers);
+ try {
+ HBaseFsckRepair.fixDupeAssignment(TEST_UTIL.getHBaseAdmin(), hriOrig,
servers);
+ } catch (IOException ex) {
+ ex = RemoteExceptionHandler.checkIOException(ex);
+ if (!(ex instanceof UnknownRegionException)) {
+ fail("Unexpected exception: " + ex);
+ }
+ }
// We created 1 table, should be fine
assertNoErrors(doFsck(false));