Author: todd
Date: Tue May 3 19:07:54 2011
New Revision: 1099199
URL: http://svn.apache.org/viewvc?rev=1099199&view=rev
Log:
HBASE-3837 Show regions in transition on the master web page
Added:
hbase/trunk/src/main/jamon/org/apache/hbase/tmpl/master/AssignmentManagerStatusTmpl.jamon
Modified:
hbase/trunk/CHANGES.txt
hbase/trunk/src/main/jamon/org/apache/hbase/tmpl/master/MasterStatusTmpl.jamon
hbase/trunk/src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java
hbase/trunk/src/test/java/org/apache/hadoop/hbase/master/TestMasterFailover.java
hbase/trunk/src/test/java/org/apache/hadoop/hbase/master/TestMasterStatusServlet.java
Modified: hbase/trunk/CHANGES.txt
URL:
http://svn.apache.org/viewvc/hbase/trunk/CHANGES.txt?rev=1099199&r1=1099198&r2=1099199&view=diff
==============================================================================
--- hbase/trunk/CHANGES.txt (original)
+++ hbase/trunk/CHANGES.txt Tue May 3 19:07:54 2011
@@ -236,6 +236,7 @@ Release 0.91.0 - Unreleased
(Prakash Khemani)
HBASE-3836 Add facility to track currently progressing actions and
workflows. (todd)
+ HBASE-3837 Show regions in transition on the master web page (todd)
Release 0.90.3 - Unreleased
Added:
hbase/trunk/src/main/jamon/org/apache/hbase/tmpl/master/AssignmentManagerStatusTmpl.jamon
URL:
http://svn.apache.org/viewvc/hbase/trunk/src/main/jamon/org/apache/hbase/tmpl/master/AssignmentManagerStatusTmpl.jamon?rev=1099199&view=auto
==============================================================================
---
hbase/trunk/src/main/jamon/org/apache/hbase/tmpl/master/AssignmentManagerStatusTmpl.jamon
(added)
+++
hbase/trunk/src/main/jamon/org/apache/hbase/tmpl/master/AssignmentManagerStatusTmpl.jamon
Tue May 3 19:07:54 2011
@@ -0,0 +1,42 @@
+<%doc>
+Copyright 2011 The Apache Software Foundation
+
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+</%doc>
+<%import>
+org.apache.hadoop.hbase.master.AssignmentManager;
+org.apache.hadoop.hbase.master.AssignmentManager.RegionState;
+java.util.Map;
+</%import>
+<%args>
+AssignmentManager assignmentManager;
+</%args>
+<%java>
+Map<String, RegionState> rit = assignmentManager.getRegionsInTransition();
+</%java>
+
+<h2>Regions in Transition</h2>
+<%if rit.isEmpty() %>
+No regions in transition.
+<%else>
+ <table>
+ <tr><th>Region</th><th>State</th></tr>
+ <%for Map.Entry<String, RegionState> entry : rit.entrySet() %>
+ <tr><td><% entry.getKey() %></td><td><% entry.getValue() %></td>
+ </%for>
+ </table>
+</%if>
\ No newline at end of file
Modified:
hbase/trunk/src/main/jamon/org/apache/hbase/tmpl/master/MasterStatusTmpl.jamon
URL:
http://svn.apache.org/viewvc/hbase/trunk/src/main/jamon/org/apache/hbase/tmpl/master/MasterStatusTmpl.jamon?rev=1099199&r1=1099198&r2=1099199&view=diff
==============================================================================
---
hbase/trunk/src/main/jamon/org/apache/hbase/tmpl/master/MasterStatusTmpl.jamon
(original)
+++
hbase/trunk/src/main/jamon/org/apache/hbase/tmpl/master/MasterStatusTmpl.jamon
Tue May 3 19:07:54 2011
@@ -97,6 +97,9 @@ org.apache.hadoop.hbase.HTableDescriptor
<%if (servers != null) %>
<& regionServers &>
</%if>
+
+<& AssignmentManagerStatusTmpl;
assignmentManager=master.getAssignmentManager()&>
+
</body>
</html>
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=1099199&r1=1099198&r2=1099199&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
Tue May 3 19:07:54 2011
@@ -332,20 +332,23 @@ public class AssignmentManager extends Z
// Just insert region into RIT.
// If this never updates the timeout will trigger new assignment
regionsInTransition.put(encodedRegionName, new RegionState(
- regionInfo, RegionState.State.CLOSING, data.getStamp()));
+ regionInfo, RegionState.State.CLOSING,
+ data.getStamp(), data.getOrigin()));
break;
case RS_ZK_REGION_CLOSED:
// Region is closed, insert into RIT and handle it
regionsInTransition.put(encodedRegionName, new RegionState(
- regionInfo, RegionState.State.CLOSED, data.getStamp()));
+ regionInfo, RegionState.State.CLOSED,
+ data.getStamp(), data.getOrigin()));
new ClosedRegionHandler(master, this, regionInfo).process();
break;
case M_ZK_REGION_OFFLINE:
// Region is offline, insert into RIT and handle it like a closed
regionsInTransition.put(encodedRegionName, new RegionState(
- regionInfo, RegionState.State.OFFLINE, data.getStamp()));
+ regionInfo, RegionState.State.OFFLINE,
+ data.getStamp(), data.getOrigin()));
new ClosedRegionHandler(master, this, regionInfo).process();
break;
@@ -353,13 +356,15 @@ public class AssignmentManager extends Z
// Just insert region into RIT
// If this never updates the timeout will trigger new assignment
regionsInTransition.put(encodedRegionName, new RegionState(
- regionInfo, RegionState.State.OPENING, data.getStamp()));
+ regionInfo, RegionState.State.OPENING,
+ data.getStamp(), data.getOrigin()));
break;
case RS_ZK_REGION_OPENED:
// Region is opened, insert into RIT and handle it
regionsInTransition.put(encodedRegionName, new RegionState(
- regionInfo, RegionState.State.OPENING, data.getStamp()));
+ regionInfo, RegionState.State.OPENING,
+ data.getStamp(), data.getOrigin()));
ServerName sn =
data.getOrigin() == null? null: data.getOrigin();
// hsi could be null if this server is no longer online. If
@@ -422,7 +427,7 @@ public class AssignmentManager extends Z
case RS_ZK_REGION_SPLITTING:
if (!isInStateForSplitting(regionState)) break;
- addSplittingToRIT(sn.toString(), encodedName);
+ addSplittingToRIT(sn, encodedName);
break;
case RS_ZK_REGION_SPLIT:
@@ -433,7 +438,7 @@ public class AssignmentManager extends Z
LOG.info("Received SPLIT for region " + prettyPrintedRegionName +
" from server " + sn +
" but region was not first in SPLITTING state; continuing");
- addSplittingToRIT(sn.toString(), encodedName);
+ addSplittingToRIT(sn, encodedName);
}
// Check it has daughters.
byte [] payload = data.getPayload();
@@ -468,7 +473,8 @@ public class AssignmentManager extends Z
return;
}
// Transition to CLOSING (or update stamp if already CLOSING)
- regionState.update(RegionState.State.CLOSING, data.getStamp());
+ regionState.update(RegionState.State.CLOSING,
+ data.getStamp(), data.getOrigin());
break;
case RS_ZK_REGION_CLOSED:
@@ -484,7 +490,8 @@ public class AssignmentManager extends Z
// Handle CLOSED by assigning elsewhere or stopping if a disable
// If we got here all is good. Need to update RegionState -- else
// what follows will fail because not in expected state.
- regionState.update(RegionState.State.CLOSED, data.getStamp());
+ regionState.update(RegionState.State.CLOSED,
+ data.getStamp(), data.getOrigin());
this.executorService.submit(new ClosedRegionHandler(master,
this, regionState.getRegion()));
break;
@@ -502,7 +509,8 @@ public class AssignmentManager extends Z
return;
}
// Transition to OPENING (or update stamp if already OPENING)
- regionState.update(RegionState.State.OPENING, data.getStamp());
+ regionState.update(RegionState.State.OPENING,
+ data.getStamp(), data.getOrigin());
break;
case RS_ZK_REGION_OPENED:
@@ -517,7 +525,8 @@ public class AssignmentManager extends Z
return;
}
// Handle OPENED by removing from transition and deleted zk node
- regionState.update(RegionState.State.OPEN, data.getStamp());
+ regionState.update(RegionState.State.OPEN,
+ data.getStamp(), data.getOrigin());
this.executorService.submit(
new OpenedRegionHandler(master, this, regionState.getRegion(),
data.getOrigin()));
@@ -564,12 +573,13 @@ public class AssignmentManager extends Z
* @return The SPLITTING RegionState we added to RIT for the passed region
* <code>encodedName</code>
*/
- private RegionState addSplittingToRIT(final String serverName,
+ private RegionState addSplittingToRIT(final ServerName serverName,
final String encodedName) {
RegionState regionState = null;
synchronized (this.regions) {
regionState = findHRegionInfoThenAddToRIT(serverName, encodedName);
- regionState.update(RegionState.State.SPLITTING);
+ regionState.update(RegionState.State.SPLITTING,
+ System.currentTimeMillis(), serverName);
}
return regionState;
}
@@ -580,7 +590,7 @@ public class AssignmentManager extends Z
* @param encodedName
* @return The instance of RegionState that was added to RIT or null if
error.
*/
- private RegionState findHRegionInfoThenAddToRIT(final String serverName,
+ private RegionState findHRegionInfoThenAddToRIT(final ServerName serverName,
final String encodedName) {
HRegionInfo hri = findHRegionInfo(serverName, encodedName);
if (hri == null) {
@@ -598,9 +608,8 @@ public class AssignmentManager extends Z
* @param encodedName
* @return Found HRegionInfo or null.
*/
- private HRegionInfo findHRegionInfo(final String serverName,
+ private HRegionInfo findHRegionInfo(final ServerName sn,
final String encodedName) {
- ServerName sn = new ServerName(serverName);
if (!this.serverManager.isServerOnline(sn)) return null;
List<HRegionInfo> hris = this.servers.get(sn);
HRegionInfo foundHri = null;
@@ -824,7 +833,7 @@ public class AssignmentManager extends Z
}
if (rs == null) continue;
synchronized (rs) {
- rs.update(rs.getState());
+ rs.updateTimestampToNow();
}
}
}
@@ -1028,7 +1037,7 @@ public class AssignmentManager extends Z
// Async exists to set a watcher so we'll get triggered when
// unassigned node changes.
this.zkw.getZooKeeper().exists(path, this.zkw,
- new ExistsUnassignedAsyncCallback(this.counter), ctx);
+ new ExistsUnassignedAsyncCallback(this.counter, destination), ctx);
}
}
@@ -1039,9 +1048,11 @@ public class AssignmentManager extends Z
static class ExistsUnassignedAsyncCallback implements
AsyncCallback.StatCallback {
private final Log LOG =
LogFactory.getLog(ExistsUnassignedAsyncCallback.class);
private final AtomicInteger counter;
+ private ServerName destination;
- ExistsUnassignedAsyncCallback(final AtomicInteger counter) {
+ ExistsUnassignedAsyncCallback(final AtomicInteger counter, ServerName
destination) {
this.counter = counter;
+ this.destination = destination;
}
@Override
@@ -1059,7 +1070,7 @@ public class AssignmentManager extends Z
// yet sent out the actual open but putting this state change after the
// call to open risks our writing PENDING_OPEN after state has been moved
// to OPENING by the regionserver.
- state.update(RegionState.State.PENDING_OPEN);
+ state.update(RegionState.State.PENDING_OPEN, System.currentTimeMillis(),
destination);
this.counter.addAndGet(1);
}
}
@@ -1113,7 +1124,8 @@ public class AssignmentManager extends Z
LOG.debug("Assigning region " +
state.getRegion().getRegionNameAsString() +
" to " + plan.getDestination().toString());
// Transition RegionState to PENDING_OPEN
- state.update(RegionState.State.PENDING_OPEN);
+ state.update(RegionState.State.PENDING_OPEN,
System.currentTimeMillis(),
+ plan.getDestination());
// Send OPEN RPC. This can fail if the server on other end is is not
up.
serverManager.sendRegionOpen(plan.getDestination(), state.getRegion());
break;
@@ -2151,27 +2163,35 @@ public class AssignmentManager extends Z
private State state;
private long stamp;
+ private ServerName serverName;
public RegionState() {}
RegionState(HRegionInfo region, State state) {
- this(region, state, System.currentTimeMillis());
+ this(region, state, System.currentTimeMillis(), null);
}
- RegionState(HRegionInfo region, State state, long stamp) {
+ RegionState(HRegionInfo region, State state, long stamp, ServerName
serverName) {
this.region = region;
this.state = state;
this.stamp = stamp;
+ this.serverName = serverName;
}
- public void update(State state, long stamp) {
+ public void update(State state, long stamp, ServerName serverName) {
this.state = state;
this.stamp = stamp;
+ this.serverName = serverName;
}
public void update(State state) {
this.state = state;
this.stamp = System.currentTimeMillis();
+ this.serverName = null;
+ }
+
+ public void updateTimestampToNow() {
+ this.stamp = System.currentTimeMillis();
}
public State getState() {
@@ -2224,8 +2244,10 @@ public class AssignmentManager extends Z
@Override
public String toString() {
- return region.getRegionNameAsString() + " state=" + state +
- ", ts=" + stamp;
+ return region.getRegionNameAsString()
+ + " state=" + state
+ + ", ts=" + stamp
+ + ", server=" + serverName;
}
@Override
Modified:
hbase/trunk/src/test/java/org/apache/hadoop/hbase/master/TestMasterFailover.java
URL:
http://svn.apache.org/viewvc/hbase/trunk/src/test/java/org/apache/hadoop/hbase/master/TestMasterFailover.java?rev=1099199&r1=1099198&r2=1099199&view=diff
==============================================================================
---
hbase/trunk/src/test/java/org/apache/hadoop/hbase/master/TestMasterFailover.java
(original)
+++
hbase/trunk/src/test/java/org/apache/hadoop/hbase/master/TestMasterFailover.java
Tue May 3 19:07:54 2011
@@ -808,13 +808,13 @@ public class TestMasterFailover {
region = enabledRegions.remove(0);
regionsThatShouldBeOnline.add(region);
master.assignmentManager.regionsInTransition.put(region.getEncodedName(),
- new RegionState(region, RegionState.State.PENDING_OPEN, 0));
+ new RegionState(region, RegionState.State.PENDING_OPEN, 0, null));
ZKAssign.createNodeOffline(zkw, region, master.getServerName());
// PENDING_OPEN and disabled
region = disabledRegions.remove(0);
regionsThatShouldBeOffline.add(region);
master.assignmentManager.regionsInTransition.put(region.getEncodedName(),
- new RegionState(region, RegionState.State.PENDING_OPEN, 0));
+ new RegionState(region, RegionState.State.PENDING_OPEN, 0, null));
ZKAssign.createNodeOffline(zkw, region, master.getServerName());
// This test is bad. It puts up a PENDING_CLOSE but doesn't say what
// server we were PENDING_CLOSE against -- i.e. an entry in
Modified:
hbase/trunk/src/test/java/org/apache/hadoop/hbase/master/TestMasterStatusServlet.java
URL:
http://svn.apache.org/viewvc/hbase/trunk/src/test/java/org/apache/hadoop/hbase/master/TestMasterStatusServlet.java?rev=1099199&r1=1099198&r2=1099199&view=diff
==============================================================================
---
hbase/trunk/src/test/java/org/apache/hadoop/hbase/master/TestMasterStatusServlet.java
(original)
+++
hbase/trunk/src/test/java/org/apache/hadoop/hbase/master/TestMasterStatusServlet.java
Tue May 3 19:07:54 2011
@@ -22,14 +22,18 @@ package org.apache.hadoop.hbase.master;
import java.io.IOException;
import java.io.StringWriter;
import java.util.List;
+import java.util.NavigableMap;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
+import org.apache.hadoop.hbase.HRegionInfo;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.ServerName;
import org.apache.hadoop.hbase.client.HBaseAdmin;
+import org.apache.hadoop.hbase.master.AssignmentManager.RegionState;
import org.apache.hadoop.hbase.master.HMaster;
import org.apache.hadoop.hbase.master.ServerManager;
+import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.zookeeper.ZooKeeperWatcher;
import org.apache.hbase.tmpl.master.MasterStatusTmpl;
import org.junit.Before;
@@ -37,6 +41,7 @@ import org.junit.Test;
import org.mockito.Mockito;
import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
/**
* Tests for the master status page and its template.
@@ -47,13 +52,19 @@ public class TestMasterStatusServlet {
private Configuration conf;
private HBaseAdmin admin;
+ static final ServerName FAKE_HOST =
+ new ServerName("fakehost", 12345, 1234567890);
+ static final HTableDescriptor FAKE_TABLE =
+ new HTableDescriptor("mytable");
+ static final HRegionInfo FAKE_REGION =
+ new HRegionInfo(FAKE_TABLE, Bytes.toBytes("a"), Bytes.toBytes("b"));
+
@Before
public void setupBasicMocks() {
conf = HBaseConfiguration.create();
master = Mockito.mock(HMaster.class);
- Mockito.doReturn(new ServerName("fakehost", 12345, 1234567890))
- .when(master).getServerName();
+ Mockito.doReturn(FAKE_HOST).when(master).getServerName();
Mockito.doReturn(conf).when(master).getConfiguration();
// Fake serverManager
@@ -61,6 +72,15 @@ public class TestMasterStatusServlet {
Mockito.doReturn(1.0).when(serverManager).getAverageLoad();
Mockito.doReturn(serverManager).when(master).getServerManager();
+ // Fake AssignmentManager and RIT
+ AssignmentManager am = Mockito.mock(AssignmentManager.class);
+ NavigableMap<String, RegionState> regionsInTransition =
+ Maps.newTreeMap();
+ regionsInTransition.put("r1",
+ new RegionState(FAKE_REGION, RegionState.State.CLOSING, 12345L,
FAKE_HOST));
+ Mockito.doReturn(regionsInTransition).when(am).getRegionsInTransition();
+ Mockito.doReturn(am).when(master).getAssignmentManager();
+
// Fake ZKW
ZooKeeperWatcher zkw = Mockito.mock(ZooKeeperWatcher.class);
Mockito.doReturn("fakequorum").when(zkw).getQuorum();