From 8efece3ba55a5b8d42fe76aa1a331025c50ad966 Mon Sep 17 00:00:00 2001 From: Todd Lipcon Date: Fri, 2 Sep 2011 20:24:48 +0000 Subject: [PATCH] HBASE-4257 Limit the number of regions in transitions displayed on master webpage. git-svn-id: https://svn.apache.org/repos/asf/hbase/trunk@1164690 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES.txt | 2 + .../master/AssignmentManagerStatusTmpl.jamon | 28 ++++++++++ .../hbase/master/TestMasterStatusServlet.java | 52 +++++++++++++++---- 3 files changed, 73 insertions(+), 9 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 01c95d84612..504c80f7d4b 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -434,6 +434,8 @@ Release 0.91.0 - Unreleased HBASE-4275 RS should communicate fatal "aborts" back to the master (todd) HBASE-4263 New config property for user-table only RegionObservers (Lars Hofhansl) + HBASE-4257 Limit the number of regions in transitions displayed on + master webpage. (todd) TASKS HBASE-3559 Move report of split to master OFF the heartbeat channel diff --git a/src/main/jamon/org/apache/hbase/tmpl/master/AssignmentManagerStatusTmpl.jamon b/src/main/jamon/org/apache/hbase/tmpl/master/AssignmentManagerStatusTmpl.jamon index 62a63b1f921..0dc0691a894 100644 --- a/src/main/jamon/org/apache/hbase/tmpl/master/AssignmentManagerStatusTmpl.jamon +++ b/src/main/jamon/org/apache/hbase/tmpl/master/AssignmentManagerStatusTmpl.jamon @@ -18,15 +18,40 @@ See the License for the specific language governing permissions and limitations under the License. <%import> +org.apache.hadoop.hbase.HRegionInfo; org.apache.hadoop.hbase.master.AssignmentManager; org.apache.hadoop.hbase.master.AssignmentManager.RegionState; +java.util.Iterator; java.util.Map; <%args> AssignmentManager assignmentManager; +int limit = 100; <%java> Map rit = assignmentManager.getRegionsInTransition(); + +int toRemove = rit.size() - limit; +int removed = 0; +if (toRemove > 0) { + // getRegionsInTransition returned a copy, so we can mutate it + for (Iterator> it = rit.entrySet().iterator(); + it.hasNext() && toRemove > 0; + ) { + Map.Entry e = it.next(); + if (HRegionInfo.FIRST_META_REGIONINFO.getEncodedName().equals( + e.getKey()) || + HRegionInfo.ROOT_REGIONINFO.getEncodedName().equals( + e.getKey())) { + // don't remove the meta regions, they're too interesting! + continue; + } + it.remove(); + toRemove--; + removed++; + } +} +

Regions in Transition

@@ -39,4 +64,7 @@ No regions in transition. <% entry.getKey() %><% entry.getValue().toDescriptiveString() %> + <%if removed > 0 %> + (<% removed %> more regions in transition not shown) + \ No newline at end of file diff --git a/src/test/java/org/apache/hadoop/hbase/master/TestMasterStatusServlet.java b/src/test/java/org/apache/hadoop/hbase/master/TestMasterStatusServlet.java index 286749108a7..4266685104d 100644 --- a/src/test/java/org/apache/hadoop/hbase/master/TestMasterStatusServlet.java +++ b/src/test/java/org/apache/hadoop/hbase/master/TestMasterStatusServlet.java @@ -19,10 +19,14 @@ */ package org.apache.hadoop.hbase.master; +import static org.junit.Assert.*; + import java.io.IOException; import java.io.StringWriter; import java.util.List; import java.util.NavigableMap; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.*; @@ -33,6 +37,7 @@ import org.apache.hadoop.hbase.master.ServerManager; import org.apache.hadoop.hbase.regionserver.HRegion; import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.hbase.zookeeper.ZooKeeperWatcher; +import org.apache.hbase.tmpl.master.AssignmentManagerStatusTmpl; import org.apache.hbase.tmpl.master.MasterStatusTmpl; import org.junit.Before; import org.junit.Test; @@ -57,17 +62,8 @@ public class TestMasterStatusServlet { static final HRegionInfo FAKE_HRI = new HRegionInfo(FAKE_TABLE.getName(), Bytes.toBytes("a"), Bytes.toBytes("b")); - // static final HRegionInfo FAKE_REGION = null; - @Before public void setupBasicMocks() { - try { - HRegion.createHRegion(FAKE_HRI, HBaseTestingUtility.getTestDir(), - HBaseConfiguration.create(), FAKE_TABLE); - } catch(IOException ioe) { - - } - conf = HBaseConfiguration.create(); master = Mockito.mock(HMaster.class); @@ -146,5 +142,43 @@ public class TestMasterStatusServlet { .render(new StringWriter(), master, admin); } + + @Test + public void testAssignmentManagerTruncatedList() throws IOException { + AssignmentManager am = Mockito.mock(AssignmentManager.class); + + // Add 100 regions as in-transition + NavigableMap regionsInTransition = + Maps.newTreeMap(); + for (byte i = 0; i < 100; i++) { + HRegionInfo hri = new HRegionInfo(FAKE_TABLE.getName(), + new byte[]{i}, new byte[]{(byte) (i+1)}); + regionsInTransition.put(hri.getEncodedName(), + new RegionState(hri, RegionState.State.CLOSING, 12345L, FAKE_HOST)); + } + // Add META in transition as well + regionsInTransition.put( + HRegionInfo.FIRST_META_REGIONINFO.getEncodedName(), + new RegionState(HRegionInfo.FIRST_META_REGIONINFO, + RegionState.State.CLOSING, 12345L, FAKE_HOST)); + Mockito.doReturn(regionsInTransition).when(am).getRegionsInTransition(); + // Render to a string + StringWriter sw = new StringWriter(); + new AssignmentManagerStatusTmpl() + .setLimit(50) + .render(sw, am); + String result = sw.toString(); + + // Should always include META + assertTrue(result.contains(HRegionInfo.FIRST_META_REGIONINFO.getEncodedName())); + + // Make sure we only see 50 of them + Matcher matcher = Pattern.compile("CLOSING").matcher(result); + int count = 0; + while (matcher.find()) { + count++; + } + assertEquals(50, count); + } }