From eb7eb98893c8057f7ee7322b104dad9ea1aa6ade Mon Sep 17 00:00:00 2001 From: Matt Warhaftig Date: Fri, 10 Jul 2015 21:12:54 -0400 Subject: [PATCH] HBASE-13839 Improve Region In Transition UI look and feel. --- .../tmpl/master/AssignmentManagerStatusTmpl.jamon | 134 +++++++++++++-------- .../apache/hadoop/hbase/master/RegionStates.java | 25 ++++ 2 files changed, 108 insertions(+), 51 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 f6ea464..d6de60c 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 @@ -25,78 +25,110 @@ org.apache.hadoop.hbase.HBaseConfiguration; org.apache.hadoop.hbase.HConstants; java.util.Iterator; java.util.Map; +java.util.List; +java.util.ArrayList; +java.util.Map.Entry; +java.util.Arrays; <%args> AssignmentManager assignmentManager; int limit = 100; + +<%java Map rit = assignmentManager + .getRegionStates().getRegionsInTransitionOrderedByTimestamp(); %> + +<%if !rit.isEmpty() %> <%java> -Map rit = assignmentManager - .getRegionStates().getRegionsInTransition(); +List ritsOverThreshold = new ArrayList<>(); +List ritsTwiceThreshold = new ArrayList<>(); // 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 for (Map.Entry e : rit.entrySet()) { long ritTime = currentTime - e.getValue().getStamp(); - if(ritTime > ritThreshold) { + if(ritTime > (ritThreshold * 2)) { numOfRITOverThreshold++; - } - if(maxRITTime < ritTime) { - maxRITTime = ritTime; - regionIDForOldestRIT = e.getKey(); - } -} - -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()) || - regionIDForOldestRIT.equals(e.getKey())) { - // don't remove the meta & the oldest rit regions, they're too interesting! - continue; - } - it.remove(); - toRemove--; - removed++; + ritsTwiceThreshold.add(e.getKey()); + }else if(ritTime > ritThreshold) { + numOfRITOverThreshold++; + ritsOverThreshold.add(e.getKey()); } } +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 Map.Entry entry : rit.entrySet() %> - <%if regionIDForOldestRIT.equals(entry.getKey()) %> - +

<% 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 Map.Entry entry : rit.entrySet() %> + <%if (recordItr % ritsPerPage) == 0 %> + <%if recordItr == 0 %> +
+ <%else> +
+ +
RegionStateRIT time (ms)
+ + + + <%if ritsOverThreshold.contains(entry.getKey()) %> + + <%elseif ritsTwiceThreshold.contains(entry.getKey()) %> + <%else> - - - - - - -
RegionStateRIT time (ms)
<% entry.getKey() %> - <% HRegionInfo.getDescriptiveNameFromRegionStateForDisplay( - entry.getValue(), conf) %><% (currentTime - entry.getValue().getStamp()) %>
Total number of Regions in Transition for more than <% ritThreshold %> milliseconds <% numOfRITOverThreshold %>
Total number of Regions in Transition<% rit.size() %>
- <%if removed > 0 %> - (<% removed %> more regions in transition not shown) - -
- + <% entry.getKey() %> + <% HRegionInfo.getDescriptiveNameFromRegionStateForDisplay( + entry.getValue(), conf) %> + <% (currentTime - entry.getValue().getStamp()) %> + + <%java recordItr++; %> + <%if (recordItr % ritsPerPage) == 0 %> + + + + + <%if (recordItr % ritsPerPage) != 0 %> + <%for ; (recordItr % ritsPerPage) != 0 ; recordItr++ %> + + + + + + + + + + \ No newline at end of file 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 658a879..a29a476 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 @@ -21,9 +21,12 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; @@ -207,6 +210,28 @@ public class RegionStates { return (Map)regionsInTransition.clone(); } + @SuppressWarnings("unchecked") + public synchronized Map getRegionsInTransitionOrderedByTimestamp() { + Map rit = (Map)regionsInTransition.clone(); + List> list = new LinkedList<>(rit.entrySet()); + + // Compare the RITs' timestamps for ordering. + Comparator> c = + new Comparator>() { + @Override + public int compare(Map.Entry o1, Map.Entry o2) { + return ((Long)o1.getValue().getStamp()).compareTo((Long)o2.getValue().getStamp()); + } + }; + + Collections.sort(list, c); + Map result = new LinkedHashMap<>(); + for (Map.Entry entry : list) { + result.put(entry.getKey(), entry.getValue()); + } + return result; + } + /** * @return True if specified region in transition. */ -- 2.3.2 (Apple Git-55)