From db5cab199bb31cd0b9074b88a2cb5b65a9b6bd98 Mon Sep 17 00:00:00 2001 From: stack Date: Fri, 12 Feb 2016 15:06:38 -0800 Subject: [PATCH] =?UTF-8?q?HBASE-16262=20Backport=20HBASE-13839:=20Fix=20A?= =?UTF-8?q?ssgnmentManagerTmpl.jamon=20issues=20(coloring,=20content=20?= =?UTF-8?q?=E2=80=A6etc).=20Ignoring=20UI=20changes=20provided=20by=20HBAS?= =?UTF-8?q?E-11344.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tmpl/master/AssignmentManagerStatusTmpl.jamon | 146 +++++++++++++-------- .../apache/hadoop/hbase/master/RegionStates.java | 29 +++- .../hbase/master/TestMasterStatusServlet.java | 6 +- 3 files changed, 122 insertions(+), 59 deletions(-) diff --git a/hbase-server/src/main/jamon/org/apache/hadoop/hbase/tmpl/master/AssignmentManagerStatusTmpl.jamon b/hbase-server/src/main/jamon/org/apache/hadoop/hbase/tmpl/master/AssignmentManagerStatusTmpl.jamon index 64bb7ef..67816b2 100644 --- a/hbase-server/src/main/jamon/org/apache/hadoop/hbase/tmpl/master/AssignmentManagerStatusTmpl.jamon +++ b/hbase-server/src/main/jamon/org/apache/hadoop/hbase/tmpl/master/AssignmentManagerStatusTmpl.jamon @@ -23,81 +23,115 @@ org.apache.hadoop.hbase.master.RegionState; org.apache.hadoop.conf.Configuration; org.apache.hadoop.hbase.HBaseConfiguration; org.apache.hadoop.hbase.HConstants; +java.util.SortedSet; java.util.Iterator; +java.util.List; +java.util.ArrayList; java.util.Set; +java.util.HashSet; +java.lang.Integer; <%args> AssignmentManager assignmentManager; -int limit = 100; +int limit = Integer.MAX_VALUE; + +<%java SortedSet rit = assignmentManager + .getRegionStates().getRegionsInTransitionOrderedByTimestamp(); %> + +<%if !rit.isEmpty() %> <%java> -Set rit = assignmentManager.getRegionStates().getRegionsInTransition(); +Set ritsOverThreshold = new HashSet<>(); +Set ritsTwiceThreshold = new HashSet<>(); // process the map to find region in transition details Configuration conf = HBaseConfiguration.create(); int ritThreshold = conf.getInt(HConstants.METRICS_RIT_STUCK_WARNING_THRESHOLD, 60000); int numOfRITOverThreshold = 0; -long maxRITTime = Long.MIN_VALUE; long currentTime = System.currentTimeMillis(); -String regionIDForOldestRIT = ""; // avoiding null +List ritToDisplay = new ArrayList<>(); +int count = 0; for (RegionState rs : rit) { long ritTime = currentTime - rs.getStamp(); - if(ritTime > ritThreshold) { + if(ritTime > (ritThreshold * 2)) { numOfRITOverThreshold++; - } - if(maxRITTime < ritTime) { - maxRITTime = ritTime; - regionIDForOldestRIT = rs.getRegion().getEncodedName(); - } -} - -int totalRITs = rit.size(); -int toRemove = rit.size() - limit; -int removed = 0; -if (toRemove > 0) { - // getRegionsInTransition returned a copy, so we can mutate it - for (Iterator it = rit.iterator(); it.hasNext() && toRemove > 0;) { - RegionState rs = it.next(); - String regionEncodedName = rs.getRegion().getEncodedName(); - if (HRegionInfo.FIRST_META_REGIONINFO.getEncodedName().equals(regionEncodedName) || - regionIDForOldestRIT.equals(regionEncodedName)) { - // don't remove the meta & the oldest rit regions, they're too interesting! - continue; - } - it.remove(); - toRemove--; - removed++; + ritsTwiceThreshold.add(rs.getRegion().getEncodedName()); + } else if (ritTime > ritThreshold) { + numOfRITOverThreshold++; + ritsOverThreshold.add(rs.getRegion().getEncodedName()); + } + if (count++ < limit) { + ritToDisplay.add(rs); } } - +int numOfRITs = rit.size(); +int ritsPerPage = Math.min(5, numOfRITs); +int numOfPages = (int) Math.ceil(numOfRITs * 1.0 / ritsPerPage); - - -<%if !rit.isEmpty() %>

Regions in Transition

- - - <%for RegionState rs : rit %> - <%if regionIDForOldestRIT.equals(rs.getRegion().getEncodedName()) %> - - <%else> - - - - +

<% numOfRITs %> region(s) in transition. + <%if !ritsTwiceThreshold.isEmpty() %> + + <%elseif !ritsOverThreshold.isEmpty() %> + + <%else> + + + <% numOfRITOverThreshold %> region(s) in transition for + more than <% ritThreshold %> milliseconds. + +

+
+
+ <%java int recordItr = 0; %> + <%for RegionState rs : ritToDisplay %> + <%if (recordItr % ritsPerPage) == 0 %> + <%if recordItr == 0 %> +
+ <%else> +
+ +
RegionStateRIT time (ms)
<% rs.getRegion().getEncodedName() %><% rs.toDescriptiveString() %><% (currentTime - rs.getStamp()) %>
+ + + + <%if ritsOverThreshold.contains(rs.getRegion().getEncodedName()) %> + + <%elseif ritsTwiceThreshold.contains(rs.getRegion().getEncodedName()) %> + + <%else> + + + + + <%java recordItr++; %> + <%if (recordItr % ritsPerPage) == 0 %> +
RegionStateRIT time (ms)
<% rs.getRegion().getEncodedName() %> + <% rs.toDescriptiveString() %><% (currentTime - rs.getStamp()) %>
+ + - <%if numOfRITOverThreshold > 0 %> - - <%else> - - - Total number of Regions in Transition for more than <% ritThreshold %> milliseconds <% numOfRITOverThreshold %> - - Total number of Regions in Transition<% totalRITs %> - - <%if removed > 0 %> - (<% removed %> more regions in transition not shown) - -
- + <%if (recordItr % ritsPerPage) != 0 %> + <%for ; (recordItr % ritsPerPage) != 0 ; recordItr++ %> + + + + + + + + + + diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/RegionStates.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/RegionStates.java index e6f5707..52cc92d 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/RegionStates.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/RegionStates.java @@ -20,13 +20,14 @@ package org.apache.hadoop.hbase.master; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.Comparator; +import java.util.SortedSet; import java.util.TreeMap; import java.util.TreeSet; @@ -67,6 +68,21 @@ import com.google.common.base.Preconditions; public class RegionStates { private static final Log LOG = LogFactory.getLog(RegionStates.class); + public final static RegionStateStampComparator REGION_STATE_COMPARATOR = + new RegionStateStampComparator(); + + // This comparator sorts the RegionStates by time stamp then Region name. + // Comparing by timestamp alone can lead us to discard different RegionStates that happen + // to share a timestamp. + private static class RegionStateStampComparator implements Comparator { + @Override + public int compare(RegionState l, RegionState r) { + return Long.compare(l.getStamp(), r.getStamp()) == 0 ? + Bytes.compareTo(l.getRegion().getRegionName(), r.getRegion().getRegionName()) : + Long.compare(l.getStamp(), r.getStamp()); + } + } + /** * Regions currently in transition. */ @@ -214,6 +230,17 @@ public class RegionStates { } /** + * @return a set of the regions in transition that are sorted by timestamp + */ + public synchronized SortedSet getRegionsInTransitionOrderedByTimestamp() { + final TreeSet rit = new TreeSet(REGION_STATE_COMPARATOR); + for (RegionState rs: regionsInTransition.values()) { + rit.add(rs); + } + return rit; + } + + /** * @return True if specified region in transition. */ public synchronized boolean isRegionInTransition(final HRegionInfo hri) { diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestMasterStatusServlet.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestMasterStatusServlet.java index 801566b..19ba132 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestMasterStatusServlet.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestMasterStatusServlet.java @@ -25,6 +25,8 @@ import java.io.StringWriter; import java.util.HashSet; import java.util.List; import java.util.Set; +import java.util.SortedSet; +import java.util.TreeSet; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -45,7 +47,6 @@ import org.junit.experimental.categories.Category; 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. @@ -157,7 +158,7 @@ public class TestMasterStatusServlet { RegionStates rs = Mockito.mock(RegionStates.class); // Add 100 regions as in-transition - HashSet regionsInTransition = new HashSet(); + SortedSet regionsInTransition = new TreeSet<>(RegionStates.REGION_STATE_COMPARATOR); for (byte i = 0; i < 100; i++) { HRegionInfo hri = new HRegionInfo(FAKE_TABLE.getTableName(), new byte[]{i}, new byte[]{(byte) (i+1)}); @@ -170,6 +171,7 @@ public class TestMasterStatusServlet { RegionState.State.CLOSING, 123L, FAKE_HOST)); Mockito.doReturn(rs).when(am).getRegionStates(); Mockito.doReturn(regionsInTransition).when(rs).getRegionsInTransition(); + Mockito.doReturn(regionsInTransition).when(rs).getRegionsInTransitionOrderedByTimestamp(); // Render to a string StringWriter sw = new StringWriter(); -- 2.8.0-rc2