You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by gx...@apache.org on 2019/11/19 12:22:41 UTC
[hbase] branch branch-2 updated: HBASE-23278 Add a table-level
compaction progress display on the UI (#816)
This is an automated email from the ASF dual-hosted git repository.
gxcheng pushed a commit to branch branch-2
in repository https://gitbox.apache.org/repos/asf/hbase.git
The following commit(s) were added to refs/heads/branch-2 by this push:
new c6ad71e HBASE-23278 Add a table-level compaction progress display on the UI (#816)
c6ad71e is described below
commit c6ad71e25666d4606e0cdaf4b411b1c005b463d6
Author: Baiqiang Zhao <zb...@gmail.com>
AuthorDate: Tue Nov 19 16:21:36 2019 +0800
HBASE-23278 Add a table-level compaction progress display on the UI (#816)
Signed-off-by: Guangxu Cheng <gx...@apache.org>
---
.../main/resources/hbase-webapps/master/table.jsp | 1507 +++++++++++---------
1 file changed, 857 insertions(+), 650 deletions(-)
diff --git a/hbase-server/src/main/resources/hbase-webapps/master/table.jsp b/hbase-server/src/main/resources/hbase-webapps/master/table.jsp
index c770126..6416510 100644
--- a/hbase-server/src/main/resources/hbase-webapps/master/table.jsp
+++ b/hbase-server/src/main/resources/hbase-webapps/master/table.jsp
@@ -19,41 +19,42 @@
--%>
<%@page import="java.net.URLEncoder"%>
<%@ page contentType="text/html;charset=UTF-8"
- import="static org.apache.commons.lang3.StringEscapeUtils.escapeXml"
- import="java.util.ArrayList"
- import="java.util.Collection"
- import="java.util.LinkedHashMap"
- import="java.util.List"
- import="java.util.Map"
- import="java.util.TreeMap"
- import=" java.util.concurrent.TimeUnit"
- import="org.apache.commons.lang3.StringEscapeUtils"
- import="org.apache.hadoop.conf.Configuration"
- import="org.apache.hadoop.hbase.HColumnDescriptor"
- import="org.apache.hadoop.hbase.HConstants"
- import="org.apache.hadoop.hbase.HRegionLocation"
- import="org.apache.hadoop.hbase.ServerName"
- import="org.apache.hadoop.hbase.TableName"
- import="org.apache.hadoop.hbase.TableNotFoundException"
- import="org.apache.hadoop.hbase.client.AsyncAdmin"
- import="org.apache.hadoop.hbase.client.AsyncConnection"
- import="org.apache.hadoop.hbase.client.CompactionState"
- import="org.apache.hadoop.hbase.client.ConnectionFactory"
- import="org.apache.hadoop.hbase.client.RegionInfo"
- import="org.apache.hadoop.hbase.client.RegionInfoBuilder"
- import="org.apache.hadoop.hbase.client.RegionLocator"
- import="org.apache.hadoop.hbase.client.RegionReplicaUtil"
- import="org.apache.hadoop.hbase.client.Table"
- import="org.apache.hadoop.hbase.master.HMaster"
- import="org.apache.hadoop.hbase.quotas.QuotaSettingsFactory"
- import="org.apache.hadoop.hbase.quotas.QuotaTableUtil"
- import="org.apache.hadoop.hbase.quotas.SpaceQuotaSnapshot"
- import="org.apache.hadoop.hbase.quotas.ThrottleSettings"
- import="org.apache.hadoop.hbase.util.Bytes"
- import="org.apache.hadoop.hbase.util.FSUtils"
- import="org.apache.hadoop.hbase.zookeeper.MetaTableLocator"
- import="org.apache.hadoop.util.StringUtils"
- import="org.apache.hbase.thirdparty.com.google.protobuf.ByteString"%>
+ import="static org.apache.commons.lang3.StringEscapeUtils.escapeXml"
+ import="java.util.ArrayList"
+ import="java.util.Collection"
+ import="java.util.HashMap"
+ import="java.util.LinkedHashMap"
+ import="java.util.List"
+ import="java.util.Map"
+ import="java.util.TreeMap"
+ import=" java.util.concurrent.TimeUnit"
+ import="org.apache.commons.lang3.StringEscapeUtils"
+ import="org.apache.hadoop.conf.Configuration"
+ import="org.apache.hadoop.hbase.HColumnDescriptor"
+ import="org.apache.hadoop.hbase.HConstants"
+ import="org.apache.hadoop.hbase.HRegionLocation"
+ import="org.apache.hadoop.hbase.ServerName"
+ import="org.apache.hadoop.hbase.TableName"
+ import="org.apache.hadoop.hbase.TableNotFoundException"
+ import="org.apache.hadoop.hbase.client.AsyncAdmin"
+ import="org.apache.hadoop.hbase.client.AsyncConnection"
+ import="org.apache.hadoop.hbase.client.CompactionState"
+ import="org.apache.hadoop.hbase.client.ConnectionFactory"
+ import="org.apache.hadoop.hbase.client.RegionInfo"
+ import="org.apache.hadoop.hbase.client.RegionInfoBuilder"
+ import="org.apache.hadoop.hbase.client.RegionLocator"
+ import="org.apache.hadoop.hbase.client.RegionReplicaUtil"
+ import="org.apache.hadoop.hbase.client.Table"
+ import="org.apache.hadoop.hbase.master.HMaster"
+ import="org.apache.hadoop.hbase.quotas.QuotaSettingsFactory"
+ import="org.apache.hadoop.hbase.quotas.QuotaTableUtil"
+ import="org.apache.hadoop.hbase.quotas.SpaceQuotaSnapshot"
+ import="org.apache.hadoop.hbase.quotas.ThrottleSettings"
+ import="org.apache.hadoop.hbase.util.Bytes"
+ import="org.apache.hadoop.hbase.util.FSUtils"
+ import="org.apache.hadoop.hbase.zookeeper.MetaTableLocator"
+ import="org.apache.hadoop.util.StringUtils"
+ import="org.apache.hbase.thirdparty.com.google.protobuf.ByteString"%>
<%@ page import="org.apache.hadoop.hbase.shaded.protobuf.generated.ClusterStatusProtos" %>
<%@ page import="org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos" %>
<%@ page import="org.apache.hadoop.hbase.shaded.protobuf.generated.QuotaProtos.Quotas" %>
@@ -62,6 +63,8 @@
<%@ page import="org.apache.hadoop.hbase.RegionMetrics" %>
<%@ page import="org.apache.hadoop.hbase.Size" %>
<%@ page import="org.apache.hadoop.hbase.RegionMetricsBuilder" %>
+<%@ page import="org.apache.hadoop.hbase.master.assignment.RegionStates" %>
+<%@ page import="org.apache.hadoop.hbase.master.RegionState" %>
<%!
/**
* @return An empty region load stamped with the passed in <code>regionInfo</code>
@@ -87,10 +90,10 @@
boolean showFragmentation = conf.getBoolean("hbase.master.ui.fragmentation.enabled", false);
boolean readOnly = conf.getBoolean("hbase.master.ui.readonly", false);
int numMetaReplicas = conf.getInt(HConstants.META_REPLICAS_NUM,
- HConstants.DEFAULT_META_REPLICA_NUM);
+ HConstants.DEFAULT_META_REPLICA_NUM);
Map<String, Integer> frags = null;
if (showFragmentation) {
- frags = FSUtils.getTableFragmentation(master);
+ frags = FSUtils.getTableFragmentation(master);
}
boolean quotasEnabled = conf.getBoolean("hbase.quota.enabled", false);
String action = request.getParameter("action");
@@ -118,9 +121,9 @@
String pageTitle;
if ( !readOnly && action != null ) {
- pageTitle = "HBase Master: " + StringEscapeUtils.escapeHtml4(master.getServerName().toString());
+ pageTitle = "HBase Master: " + StringEscapeUtils.escapeHtml4(master.getServerName().toString());
} else {
- pageTitle = "Table: " + escaped_fqtn;
+ pageTitle = "Table: " + escaped_fqtn;
}
pageContext.setAttribute("pageTitle", pageTitle);
AsyncConnection connection = ConnectionFactory.createAsyncConnection(master.getConfiguration()).get();
@@ -132,25 +135,22 @@
</jsp:include>
<%
-if (fqtn != null && master.isInitialized()) {
- try {
- table = master.getConnection().getTable(TableName.valueOf(fqtn));
- if (table.getTableDescriptor().getRegionReplication() > 1) {
- tableHeader = "<h2>Table Regions</h2><table id=\"tableRegionTable\" class=\"tablesorter table table-striped\" style=\"table-layout: fixed; word-wrap: break-word;\"><thead><tr><th>Name</th><th>Region Server</th><th>ReadRequests</th><th>WriteRequests</th><th>StorefileSize</th><th>Num.Storefiles</th><th>MemSize</th><th>Locality</th><th>Start Key</th><th>End Key</th><th>ReplicaID</th></tr></thead>";
- withReplica = true;
- } else {
- tableHeader = "<h2>Table Regions</h2><table id=\"tableRegionTable\" class=\"tablesorter table table-striped\" style=\"table-layout: fixed; word-wrap: break-word;\"><thead><tr><th>Name</th><th>Region Server</th><th>ReadRequests</th><th>WriteRequests</th><th>StorefileSize</th><th>Num.Storefiles</th><th>MemSize</th><th>Locality</th><th>Start Key</th><th>End Key</th></tr></thead>";
- }
- if ( !readOnly && action != null ) {
+ if (fqtn != null && master.isInitialized()) {
+ try {
+ table = master.getConnection().getTable(TableName.valueOf(fqtn));
+ if (table.getTableDescriptor().getRegionReplication() > 1) {
+ withReplica = true;
+ }
+ if ( !readOnly && action != null ) {
%>
<div class="container-fluid content">
- <div class="row inner_header">
- <div class="page-header">
- <h1>Table action request accepted</h1>
- </div>
- </div>
-<p><hr><p>
-<%
+ <div class="row inner_header">
+ <div class="page-header">
+ <h1>Table action request accepted</h1>
+ </div>
+ </div>
+ <p><hr><p>
+ <%
if (action.equals("split")) {
if (key != null && key.length() > 0) {
admin.split(TableName.valueOf(fqtn), Bytes.toBytes(key));
@@ -180,458 +180,651 @@ if (fqtn != null && master.isInitialized()) {
%> Merge request accepted. <%
}
%>
-<jsp:include page="redirect.jsp" />
+ <jsp:include page="redirect.jsp" />
</div>
<%
- } else {
+} else {
%>
<div class="container-fluid content">
- <div class="row inner_header">
- <div class="page-header">
- <h1>Table <small><%= escaped_fqtn %></small></h1>
+ <div class="row inner_header">
+ <div class="page-header">
+ <h1>Table <small><%= escaped_fqtn %></small></h1>
+ </div>
+ </div>
+ <div class="row">
+ <%
+ if(fqtn.equals(TableName.META_TABLE_NAME.getNameAsString())) {
+ %>
+ <h2>Table Regions</h2>
+ <div class="tabbable">
+ <ul class="nav nav-pills">
+ <li class="active">
+ <a href="#metaTab_baseStats" data-toggle="tab">Base Stats</a>
+ </li>
+ <li class="">
+ <a href="#metaTab_compactStats" data-toggle="tab">Compactions</a>
+ </li>
+ </ul>
+ <div class="tab-content" style="padding-bottom: 9px; border-bottom: 1px solid #ddd;">
+ <div class="tab-pane active" id="metaTab_baseStats">
+ <table id="tableRegionTable" class="tablesorter table table-striped">
+ <thead>
+ <tr>
+ <th>Name</th>
+ <th>Region Server</th>
+ <th>ReadRequests</th>
+ <th>WriteRequests</th>
+ <th>StorefileSize</th>
+ <th>Num.Storefiles</th>
+ <th>MemSize</th>
+ <th>Locality</th>
+ <th>Start Key</th>
+ <th>End Key</th>
+ <%
+ if (withReplica) {
+ %>
+ <th>ReplicaID</th>
+ <%
+ }
+ %>
+ </tr>
+ </thead>
+ <tbody>
+ <%
+ // NOTE: Presumes meta with one or more replicas
+ for (int j = 0; j < numMetaReplicas; j++) {
+ RegionInfo meta = RegionReplicaUtil.getRegionInfoForReplica(
+ RegionInfoBuilder.FIRST_META_REGIONINFO, j);
+ ServerName metaLocation = MetaTableLocator.waitMetaRegionLocation(master.getZooKeeper(), j, 1);
+ for (int i = 0; i < 1; i++) {
+ String hostAndPort = "";
+ String readReq = "N/A";
+ String writeReq = "N/A";
+ String fileSize = ZEROMB;
+ String fileCount = "N/A";
+ String memSize = ZEROMB;
+ float locality = 0.0f;
+ if (metaLocation != null) {
+ ServerMetrics sl = master.getServerManager().getLoad(metaLocation);
+ // The host name portion should be safe, but I don't know how we handle IDNs so err on the side of failing safely.
+ hostAndPort = URLEncoder.encode(metaLocation.getHostname()) + ":" + master.getRegionServerInfoPort(metaLocation);
+ if (sl != null) {
+ Map<byte[], RegionMetrics> map = sl.getRegionMetrics();
+ if (map.containsKey(meta.getRegionName())) {
+ RegionMetrics load = map.get(meta.getRegionName());
+ readReq = String.format("%,1d", load.getReadRequestCount());
+ writeReq = String.format("%,1d", load.getWriteRequestCount());
+ double rSize = load.getStoreFileSize().get(Size.Unit.BYTE);
+ if (rSize > 0) {
+ fileSize = StringUtils.byteDesc((long) rSize);
+ }
+ fileCount = String.format("%,1d", load.getStoreFileCount());
+ double mSize = load.getMemStoreSize().get(Size.Unit.BYTE);
+ if (mSize > 0) {
+ memSize = StringUtils.byteDesc((long)mSize);
+ }
+ locality = load.getDataLocality();
+ }
+ }
+ }
+ %>
+ <tr>
+ <td><%= escapeXml(meta.getRegionNameAsString()) %></td>
+ <td><a href="http://<%= hostAndPort %>/rs-status/"><%= StringEscapeUtils.escapeHtml4(hostAndPort) %></a></td>
+ <td><%= readReq%></td>
+ <td><%= writeReq%></td>
+ <td><%= fileSize%></td>
+ <td><%= fileCount%></td>
+ <td><%= memSize%></td>
+ <td><%= locality%></td>
+ <td><%= escapeXml(Bytes.toString(meta.getStartKey())) %></td>
+ <td><%= escapeXml(Bytes.toString(meta.getEndKey())) %></td>
+ <%
+ if (withReplica) {
+ %>
+ <td><%= meta.getReplicaId() %></td>
+ <%
+ }
+ %>
+ </tr>
+ <% } %>
+ <%} %>
+ </tbody>
+ </table>
</div>
+ <div class="tab-pane" id="metaTab_compactStats">
+ <table id="metaTableCompactStatsTable" class="tablesorter table table-striped">
+ <thead>
+ <tr>
+ <th>Name</th>
+ <th>Region Server</th>
+ <th>Num. Compacting Cells</th>
+ <th>Num. Compacted Cells</th>
+ <th>Remaining Cells</th>
+ <th>Compaction Progress</th>
+ </tr>
+ </thead>
+ <tbody>
+ <%
+ // NOTE: Presumes meta with one or more replicas
+ for (int j = 0; j < numMetaReplicas; j++) {
+ RegionInfo meta = RegionReplicaUtil.getRegionInfoForReplica(
+ RegionInfoBuilder.FIRST_META_REGIONINFO, j);
+ ServerName metaLocation = MetaTableLocator.waitMetaRegionLocation(master.getZooKeeper(), j, 1);
+ for (int i = 0; i < 1; i++) {
+ String hostAndPort = "";
+ long compactingCells = 0;
+ long compactedCells = 0;
+ String compactionProgress = "";
+ if (metaLocation != null) {
+ ServerMetrics sl = master.getServerManager().getLoad(metaLocation);
+ hostAndPort = URLEncoder.encode(metaLocation.getHostname()) + ":" + master.getRegionServerInfoPort(metaLocation);
+ if (sl != null) {
+ Map<byte[], RegionMetrics> map = sl.getRegionMetrics();
+ if (map.containsKey(meta.getRegionName())) {
+ RegionMetrics load = map.get(meta.getRegionName());
+ compactingCells = load.getCompactingCellCount();
+ compactedCells = load.getCompactedCellCount();
+ if (compactingCells > 0) {
+ compactionProgress = String.format("%.2f", 100 * ((float)
+ compactedCells / compactingCells)) + "%";
+ }
+ }
+ }
+ }
+ %>
+ <tr>
+ <td><%= escapeXml(meta.getRegionNameAsString()) %></td>
+ <td><a href="http://<%= hostAndPort %>/rs-status/"><%= StringEscapeUtils.escapeHtml4(hostAndPort) %></a></td>
+ <td><%= String.format("%,1d", compactingCells)%></td>
+ <td><%= String.format("%,1d", compactedCells)%></td>
+ <td><%= String.format("%,1d", compactingCells - compactedCells)%></td>
+ <td><%= compactionProgress%></td>
+ </tr>
+ <% } %>
+ <%} %>
+ </tbody>
+ </table>
+ </div>
+ </div>
</div>
- <div class="row">
-<%
- if(fqtn.equals(TableName.META_TABLE_NAME.getNameAsString())) {
-%>
-<%= tableHeader %>
-<tbody>
-<%
- // NOTE: Presumes meta with one or more replicas
- for (int j = 0; j < numMetaReplicas; j++) {
- RegionInfo meta = RegionReplicaUtil.getRegionInfoForReplica(
- RegionInfoBuilder.FIRST_META_REGIONINFO, j);
- ServerName metaLocation = MetaTableLocator.waitMetaRegionLocation(master.getZooKeeper(), j, 1);
- for (int i = 0; i < 1; i++) {
- String hostAndPort = "";
- String readReq = "N/A";
- String writeReq = "N/A";
- String fileSize = ZEROMB;
- String fileCount = "N/A";
- String memSize = ZEROMB;
- float locality = 0.0f;
-
- if (metaLocation != null) {
- ServerMetrics sl = master.getServerManager().getLoad(metaLocation);
- // The host name portion should be safe, but I don't know how we handle IDNs so err on the side of failing safely.
- hostAndPort = URLEncoder.encode(metaLocation.getHostname()) + ":" + master.getRegionServerInfoPort(metaLocation);
- if (sl != null) {
- Map<byte[], RegionMetrics> map = sl.getRegionMetrics();
- if (map.containsKey(meta.getRegionName())) {
- RegionMetrics load = map.get(meta.getRegionName());
- readReq = String.format("%,1d", load.getReadRequestCount());
- writeReq = String.format("%,1d", load.getWriteRequestCount());
- double rSize = load.getStoreFileSize().get(Size.Unit.BYTE);
- if (rSize > 0) {
- fileSize = StringUtils.byteDesc((long) rSize);
+ <%} else {
+ RegionStates states = master.getAssignmentManager().getRegionStates();
+ Map<RegionState.State, List<RegionInfo>> regionStates = states.getRegionByStateOfTable(table.getName());
+ Map<String, RegionState.State> stateMap = new HashMap<>();
+ for (RegionState.State regionState : regionStates.keySet()) {
+ for (RegionInfo regionInfo : regionStates.get(regionState)) {
+ stateMap.put(regionInfo.getEncodedName(), regionState);
+ }
+ }
+ RegionLocator r = master.getConnection().getRegionLocator(table.getName());
+ try { %>
+ <h2>Table Attributes</h2>
+ <table class="table table-striped">
+ <tr>
+ <th>Attribute Name</th>
+ <th>Value</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td>Enabled</td>
+ <td><%= master.getAssignmentManager().isTableEnabled(table.getName()) %></td>
+ <td>Is the table enabled</td>
+ </tr>
+ <tr>
+ <td>Compaction</td>
+ <td>
+ <%
+ if (master.getAssignmentManager().isTableEnabled(table.getName())) {
+ try {
+ CompactionState compactionState = admin.getCompactionState(table.getName()).get();
+ %><%= compactionState %><%
+ } catch (Exception e) {
+ // Nothing really to do here
+ for(StackTraceElement element : e.getStackTrace()) {
+ %><%= StringEscapeUtils.escapeHtml4(element.toString()) %><%
+ }
+ %> Unknown <%
+ }
+ } else {
+ %><%= CompactionState.NONE %><%
+ }
+ %>
+ </td>
+ <td>Is the table compacting</td>
+ </tr>
+ <% if (showFragmentation) { %>
+ <tr>
+ <td>Fragmentation</td>
+ <td><%= frags.get(fqtn) != null ? frags.get(fqtn).intValue() + "%" : "n/a" %></td>
+ <td>How fragmented is the table. After a major compaction it is 0%.</td>
+ </tr>
+ <% } %>
+ <%
+ if (quotasEnabled) {
+ TableName tn = TableName.valueOf(fqtn);
+ SpaceQuotaSnapshot masterSnapshot = null;
+ Quotas quota = QuotaTableUtil.getTableQuota(master.getConnection(), tn);
+ if (quota == null || !quota.hasSpace()) {
+ quota = QuotaTableUtil.getNamespaceQuota(master.getConnection(), tn.getNamespaceAsString());
+ if (quota != null) {
+ masterSnapshot = master.getQuotaObserverChore().getNamespaceQuotaSnapshots()
+ .get(tn.getNamespaceAsString());
}
- fileCount = String.format("%,1d", load.getStoreFileCount());
- double mSize = load.getMemStoreSize().get(Size.Unit.BYTE);
- if (mSize > 0) {
- memSize = StringUtils.byteDesc((long)mSize);
+ } else {
+ masterSnapshot = master.getQuotaObserverChore().getTableQuotaSnapshots().get(tn);
+ }
+ if (quota != null && quota.hasSpace()) {
+ SpaceQuota spaceQuota = quota.getSpace();
+ %>
+ <tr>
+ <td>Space Quota</td>
+ <td>
+ <table>
+ <tr>
+ <th>Property</th>
+ <th>Value</th>
+ </tr>
+ <tr>
+ <td>Limit</td>
+ <td><%= StringUtils.byteDesc(spaceQuota.getSoftLimit()) %></td>
+ </tr>
+ <tr>
+ <td>Policy</td>
+ <td><%= spaceQuota.getViolationPolicy() %></td>
+ </tr>
+ <%
+ if (masterSnapshot != null) {
+ %>
+ <tr>
+ <td>Usage</td>
+ <td><%= StringUtils.byteDesc(masterSnapshot.getUsage()) %></td>
+ </tr>
+ <tr>
+ <td>State</td>
+ <td><%= masterSnapshot.getQuotaStatus().isInViolation() ? "In Violation" : "In Observance" %></td>
+ </tr>
+ <%
+ }
+ %>
+ </table>
+ </td>
+ <td>Information about a Space Quota on this table, if set.</td>
+ </tr>
+ <%
+ }
+ if (quota != null && quota.hasThrottle()) {
+ List<ThrottleSettings> throttles = QuotaSettingsFactory.fromTableThrottles(table.getName(), quota.getThrottle());
+ if (throttles.size() > 0) {
+ %>
+ <tr>
+ <td>Throttle Quota</td>
+ <td>
+ <table>
+ <tr>
+ <th>Limit</th>
+ <th>Type</th>
+ <th>TimeUnit</th>
+ <th>Scope</th>
+ </tr>
+ <%
+ for (ThrottleSettings throttle : throttles) {
+ %>
+ <tr>
+ <td><%= throttle.getSoftLimit() %></td>
+ <td><%= throttle.getThrottleType() %></td>
+ <td><%= throttle.getTimeUnit() %></td>
+ <td><%= throttle.getQuotaScope() %></td>
+ </tr>
+ <%
+ }
+ %>
+ </table>
+ </td>
+ <td>Information about a Throttle Quota on this table, if set.</td>
+ </tr>
+ <%
}
- locality = load.getDataLocality();
}
}
- }
-%>
-<tr>
- <td><%= escapeXml(meta.getRegionNameAsString()) %></td>
- <td><a href="http://<%= hostAndPort %>/rs-status/"><%= StringEscapeUtils.escapeHtml4(hostAndPort) %></a></td>
- <td><%= readReq%></td>
- <td><%= writeReq%></td>
- <td><%= fileSize%></td>
- <td><%= fileCount%></td>
- <td><%= memSize%></td>
- <td><%= locality%></td>
- <td><%= escapeXml(Bytes.toString(meta.getStartKey())) %></td>
- <td><%= escapeXml(Bytes.toString(meta.getEndKey())) %></td>
-<%
- if (withReplica) {
-%>
- <td><%= meta.getReplicaId() %></td>
-<%
- }
-%>
-</tr>
-<% } %>
-<%} %>
-</tbody>
-</table>
-<%} else {
- RegionLocator r = master.getConnection().getRegionLocator(table.getName());
- try { %>
-<h2>Table Attributes</h2>
-<table class="table table-striped">
- <tr>
- <th>Attribute Name</th>
- <th>Value</th>
- <th>Description</th>
- </tr>
- <tr>
- <td>Enabled</td>
- <td><%= master.getAssignmentManager().isTableEnabled(table.getName()) %></td>
- <td>Is the table enabled</td>
- </tr>
- <tr>
- <td>Compaction</td>
- <td>
-<%
- if (master.getAssignmentManager().isTableEnabled(table.getName())) {
- try {
- CompactionState compactionState = admin.getCompactionState(table.getName()).get();
- %><%= compactionState %><%
- } catch (Exception e) {
- // Nothing really to do here
- for(StackTraceElement element : e.getStackTrace()) {
- %><%= StringEscapeUtils.escapeHtml4(element.toString()) %><%
- }
- %> Unknown <%
- }
- } else {
- %><%= CompactionState.NONE %><%
- }
-%>
- </td>
- <td>Is the table compacting</td>
- </tr>
-<% if (showFragmentation) { %>
- <tr>
- <td>Fragmentation</td>
- <td><%= frags.get(fqtn) != null ? frags.get(fqtn).intValue() + "%" : "n/a" %></td>
- <td>How fragmented is the table. After a major compaction it is 0%.</td>
- </tr>
-<% } %>
-<%
- if (quotasEnabled) {
- TableName tn = TableName.valueOf(fqtn);
- SpaceQuotaSnapshot masterSnapshot = null;
- Quotas quota = QuotaTableUtil.getTableQuota(master.getConnection(), tn);
- if (quota == null || !quota.hasSpace()) {
- quota = QuotaTableUtil.getNamespaceQuota(master.getConnection(), tn.getNamespaceAsString());
- if (quota != null) {
- masterSnapshot = master.getQuotaObserverChore().getNamespaceQuotaSnapshots()
- .get(tn.getNamespaceAsString());
- }
- } else {
- masterSnapshot = master.getQuotaObserverChore().getTableQuotaSnapshots().get(tn);
- }
- if (quota != null && quota.hasSpace()) {
- SpaceQuota spaceQuota = quota.getSpace();
-%>
- <tr>
- <td>Space Quota</td>
- <td>
- <table>
- <tr>
- <th>Property</th>
- <th>Value</th>
- </tr>
- <tr>
- <td>Limit</td>
- <td><%= StringUtils.byteDesc(spaceQuota.getSoftLimit()) %></td>
- </tr>
- <tr>
- <td>Policy</td>
- <td><%= spaceQuota.getViolationPolicy() %></td>
- </tr>
-<%
- if (masterSnapshot != null) {
-%>
- <tr>
- <td>Usage</td>
- <td><%= StringUtils.byteDesc(masterSnapshot.getUsage()) %></td>
- </tr>
- <tr>
- <td>State</td>
- <td><%= masterSnapshot.getQuotaStatus().isInViolation() ? "In Violation" : "In Observance" %></td>
- </tr>
-<%
- }
-%>
- </table>
- </td>
- <td>Information about a Space Quota on this table, if set.</td>
- </tr>
-<%
- }
- if (quota != null && quota.hasThrottle()) {
- List<ThrottleSettings> throttles = QuotaSettingsFactory.fromTableThrottles(table.getName(), quota.getThrottle());
- if (throttles.size() > 0) {
-%>
- <tr>
- <td>Throttle Quota</td>
- <td>
- <table>
- <tr>
- <th>Limit</th>
- <th>Type</th>
- <th>TimeUnit</th>
- <th>Scope</th>
- </tr>
-<%
- for (ThrottleSettings throttle : throttles) {
-%>
- <tr>
- <td><%= throttle.getSoftLimit() %></td>
- <td><%= throttle.getThrottleType() %></td>
- <td><%= throttle.getTimeUnit() %></td>
- <td><%= throttle.getQuotaScope() %></td>
- </tr>
-<%
- }
-%>
- </table>
- </td>
- <td>Information about a Throttle Quota on this table, if set.</td>
- </tr>
-<%
- }
- }
- }
-%>
-</table>
-<h2>Table Schema</h2>
-<table class="table table-striped">
- <tr>
- <th>Column Family Name</th>
- <th></th>
- </tr>
- <%
- Collection<HColumnDescriptor> families = table.getTableDescriptor().getFamilies();
- for (HColumnDescriptor family: families) {
- %>
- <tr>
- <td><%= StringEscapeUtils.escapeHtml4(family.getNameAsString()) %></td>
- <td>
+ %>
+ </table>
+ <h2>Table Schema</h2>
<table class="table table-striped">
<tr>
- <th>Property</th>
- <th>Value</th>
+ <th>Column Family Name</th>
+ <th></th>
</tr>
- <%
- Map<Bytes, Bytes> familyValues = family.getValues();
- for (Bytes familyKey: familyValues.keySet()) {
- %>
+ <%
+ Collection<HColumnDescriptor> families = table.getTableDescriptor().getFamilies();
+ for (HColumnDescriptor family: families) {
+ %>
<tr>
+ <td><%= StringEscapeUtils.escapeHtml4(family.getNameAsString()) %></td>
<td>
- <%= StringEscapeUtils.escapeHtml4(familyKey.toString()) %>
- </td>
- <td>
- <%= StringEscapeUtils.escapeHtml4(familyValues.get(familyKey).toString()) %>
+ <table class="table table-striped">
+ <tr>
+ <th>Property</th>
+ <th>Value</th>
+ </tr>
+ <%
+ Map<Bytes, Bytes> familyValues = family.getValues();
+ for (Bytes familyKey: familyValues.keySet()) {
+ %>
+ <tr>
+ <td>
+ <%= StringEscapeUtils.escapeHtml4(familyKey.toString()) %>
+ </td>
+ <td>
+ <%= StringEscapeUtils.escapeHtml4(familyValues.get(familyKey).toString()) %>
+ </td>
+ </tr>
+ <% } %>
+ </table>
</td>
</tr>
- <% } %>
+ <% } %>
</table>
- </td>
- </tr>
- <% } %>
-</table>
-<%
- long totalReadReq = 0;
- long totalWriteReq = 0;
- long totalSize = 0;
- long totalStoreFileCount = 0;
- long totalMemSize = 0;
- String totalMemSizeStr = ZEROMB;
- String totalSizeStr = ZEROMB;
- String urlRegionServer = null;
- Map<ServerName, Integer> regDistribution = new TreeMap<>();
- Map<ServerName, Integer> primaryRegDistribution = new TreeMap<>();
- List<HRegionLocation> regions = r.getAllRegionLocations();
- Map<RegionInfo, RegionMetrics> regionsToLoad = new LinkedHashMap<>();
- Map<RegionInfo, ServerName> regionsToServer = new LinkedHashMap<>();
- for (HRegionLocation hriEntry : regions) {
- RegionInfo regionInfo = hriEntry.getRegionInfo();
- ServerName addr = hriEntry.getServerName();
- regionsToServer.put(regionInfo, addr);
+ <%
+ long totalReadReq = 0;
+ long totalWriteReq = 0;
+ long totalSize = 0;
+ long totalStoreFileCount = 0;
+ long totalMemSize = 0;
+ long totalCompactingCells = 0;
+ long totalCompactedCells = 0;
+ String totalCompactionProgress = "";
+ String totalMemSizeStr = ZEROMB;
+ String totalSizeStr = ZEROMB;
+ String urlRegionServer = null;
+ Map<ServerName, Integer> regDistribution = new TreeMap<>();
+ Map<ServerName, Integer> primaryRegDistribution = new TreeMap<>();
+ List<HRegionLocation> regions = r.getAllRegionLocations();
+ Map<RegionInfo, RegionMetrics> regionsToLoad = new LinkedHashMap<>();
+ Map<RegionInfo, ServerName> regionsToServer = new LinkedHashMap<>();
+ for (HRegionLocation hriEntry : regions) {
+ RegionInfo regionInfo = hriEntry.getRegionInfo();
+ ServerName addr = hriEntry.getServerName();
+ regionsToServer.put(regionInfo, addr);
- if (addr != null) {
- ServerMetrics sl = master.getServerManager().getLoad(addr);
- if (sl != null) {
- RegionMetrics regionMetrics = sl.getRegionMetrics().get(regionInfo.getRegionName());
- regionsToLoad.put(regionInfo, regionMetrics);
- if(regionMetrics != null) {
- totalReadReq += regionMetrics.getReadRequestCount();
- totalWriteReq += regionMetrics.getWriteRequestCount();
- totalSize += regionMetrics.getStoreFileSize().get(Size.Unit.MEGABYTE);
- totalStoreFileCount += regionMetrics.getStoreFileCount();
- totalMemSize += regionMetrics.getMemStoreSize().get(Size.Unit.MEGABYTE);
- totalStoreFileSizeMB += regionMetrics.getStoreFileSize().get(Size.Unit.MEGABYTE);
+ if (addr != null) {
+ ServerMetrics sl = master.getServerManager().getLoad(addr);
+ if (sl != null) {
+ RegionMetrics regionMetrics = sl.getRegionMetrics().get(regionInfo.getRegionName());
+ regionsToLoad.put(regionInfo, regionMetrics);
+ if (regionMetrics != null) {
+ totalReadReq += regionMetrics.getReadRequestCount();
+ totalWriteReq += regionMetrics.getWriteRequestCount();
+ totalSize += regionMetrics.getStoreFileSize().get(Size.Unit.MEGABYTE);
+ totalStoreFileCount += regionMetrics.getStoreFileCount();
+ totalMemSize += regionMetrics.getMemStoreSize().get(Size.Unit.MEGABYTE);
+ totalStoreFileSizeMB += regionMetrics.getStoreFileSize().get(Size.Unit.MEGABYTE);
+ totalCompactingCells += regionMetrics.getCompactingCellCount();
+ totalCompactedCells += regionMetrics.getCompactedCellCount();
+ } else {
+ RegionMetrics load0 = getEmptyRegionMetrics(regionInfo);
+ regionsToLoad.put(regionInfo, load0);
+ }
+ } else{
+ RegionMetrics load0 = getEmptyRegionMetrics(regionInfo);
+ regionsToLoad.put(regionInfo, load0);
+ }
} else {
RegionMetrics load0 = getEmptyRegionMetrics(regionInfo);
regionsToLoad.put(regionInfo, load0);
}
- } else{
- RegionMetrics load0 = getEmptyRegionMetrics(regionInfo);
- regionsToLoad.put(regionInfo, load0);
}
- } else {
- RegionMetrics load0 = getEmptyRegionMetrics(regionInfo);
- regionsToLoad.put(regionInfo, load0);
- }
- }
- if (totalSize > 0) {
- totalSizeStr = StringUtils.byteDesc(totalSize*1024l*1024);
- }
- if (totalMemSize > 0) {
- totalMemSizeStr = StringUtils.byteDesc(totalMemSize*1024l*1024);
- }
-
- if(regions != null && regions.size() > 0) { %>
-<h2>Table Regions</h2>
-<table id="regionServerDetailsTable" class="tablesorter table table-striped">
-<thead>
-<tr>
-<th>Name(<%= String.format("%,1d", regions.size())%>)</th>
-<th>Region Server</th>
-<th>ReadRequests<br>(<%= String.format("%,1d", totalReadReq)%>)</th>
-<th>WriteRequests<br>(<%= String.format("%,1d", totalWriteReq)%>)</th>
-<th>StorefileSize<br>(<%= totalSizeStr %>)</th>
-<th>Num.Storefiles<br>(<%= String.format("%,1d", totalStoreFileCount)%>)</th>
-<th>MemSize<br>(<%= totalMemSizeStr %>)</th>
-<th>Locality</th>
-<th>Start Key</th>
-<th>End Key</th>
-<%
- if (withReplica) {
-%>
-<th>ReplicaID</th>
-<%
- }
-%>
-</thead>
-</tr>
-<tbody>
-
-<%
- List<Map.Entry<RegionInfo, RegionMetrics>> entryList = new ArrayList<>(regionsToLoad.entrySet());
- numRegions = regions.size();
- int numRegionsRendered = 0;
- // render all regions
- if (numRegionsToRender < 0) {
- numRegionsToRender = numRegions;
- }
- for (Map.Entry<RegionInfo, RegionMetrics> hriEntry : entryList) {
- RegionInfo regionInfo = hriEntry.getKey();
- ServerName addr = regionsToServer.get(regionInfo);
- RegionMetrics load = hriEntry.getValue();
- String readReq = "N/A";
- String writeReq = "N/A";
- String regionSize = ZEROMB;
- String fileCount = "N/A";
- String memSize = ZEROMB;
- float locality = 0.0f;
- if(load != null) {
- readReq = String.format("%,1d", load.getReadRequestCount());
- writeReq = String.format("%,1d", load.getWriteRequestCount());
- double rSize = load.getStoreFileSize().get(Size.Unit.BYTE);
- if (rSize > 0) {
- regionSize = StringUtils.byteDesc((long)rSize);
+ if (totalSize > 0) {
+ totalSizeStr = StringUtils.byteDesc(totalSize*1024l*1024);
}
- fileCount = String.format("%,1d", load.getStoreFileCount());
- double mSize = load.getMemStoreSize().get(Size.Unit.BYTE);
- if (mSize > 0) {
- memSize = StringUtils.byteDesc((long)mSize);
+ if (totalMemSize > 0) {
+ totalMemSizeStr = StringUtils.byteDesc(totalMemSize*1024l*1024);
}
- locality = load.getDataLocality();
- }
-
- if (addr != null) {
- ServerMetrics sl = master.getServerManager().getLoad(addr);
- // This port might be wrong if RS actually ended up using something else.
- urlRegionServer =
- "//" + URLEncoder.encode(addr.getHostname()) + ":" + master.getRegionServerInfoPort(addr) + "/rs-status";
- if(sl != null) {
- Integer i = regDistribution.get(addr);
- if (null == i) i = Integer.valueOf(0);
- regDistribution.put(addr, i + 1);
- if (withReplica && RegionReplicaUtil.isDefaultReplica(regionInfo.getReplicaId())) {
- i = primaryRegDistribution.get(addr);
- if (null == i) i = Integer.valueOf(0);
- primaryRegDistribution.put(addr, i+1);
- }
+ if (totalCompactingCells > 0) {
+ totalCompactionProgress = String.format("%.2f", 100 *
+ ((float) totalCompactedCells / totalCompactingCells)) + "%";
}
- }
- if (numRegionsRendered < numRegionsToRender) {
- numRegionsRendered++;
-%>
-<tr>
- <td><%= escapeXml(Bytes.toStringBinary(regionInfo.getRegionName())) %></td>
- <%
- if (urlRegionServer != null) {
- %>
- <td>
- <a href="<%= urlRegionServer %>"><%= addr == null? "-": StringEscapeUtils.escapeHtml4(addr.getHostname().toString()) + ":" + master.getRegionServerInfoPort(addr) %></a>
- </td>
- <%
- } else {
- %>
- <td class="undeployed-region">not deployed</td>
- <%
- }
- %>
- <td><%= readReq%></td>
- <td><%= writeReq%></td>
- <td><%= regionSize%></td>
- <td><%= fileCount%></td>
- <td><%= memSize%></td>
- <td><%= locality%></td>
- <td><%= escapeXml(Bytes.toStringBinary(regionInfo.getStartKey()))%></td>
- <td><%= escapeXml(Bytes.toStringBinary(regionInfo.getEndKey()))%></td>
- <%
- if (withReplica) {
- %>
- <td><%= regionInfo.getReplicaId() %></td>
- <%
- }
- %>
-</tr>
-<% } %>
-<% } %>
-</tbody>
-</table>
-<% if (numRegions > numRegionsRendered) {
- String allRegionsUrl = "?name=" + URLEncoder.encode(fqtn,"UTF-8") + "&numRegions=all";
-%>
- <p>This table has <b><%= numRegions %></b> regions in total, in order to improve the page load time,
- only <b><%= numRegionsRendered %></b> regions are displayed here, <a href="<%= allRegionsUrl %>">click
- here</a> to see all regions.</p>
-<% } %>
-<h2>Regions by Region Server</h2>
-<%
-if (withReplica) {
-%>
-<table id="regionServerTable" class="tablesorter table table-striped"><thead><tr><th>Region Server</th><th>Region Count</th><th>Primary Region Count</th></tr></thead>
-<%
+ if(regions != null && regions.size() > 0) { %>
+ <h2>Table Regions</h2>
+ <div class="tabbable">
+ <ul class="nav nav-pills">
+ <li class="active">
+ <a href="#tab_baseStats" data-toggle="tab">Base Stats</a>
+ </li>
+ <li class="">
+ <a href="#tab_compactStats" data-toggle="tab">Compactions</a>
+ </li>
+ </ul>
+ <div class="tab-content" style="padding-bottom: 9px; border-bottom: 1px solid #ddd;">
+ <div class="tab-pane active" id="tab_baseStats">
+ <table id="regionServerDetailsTable" class="tablesorter table table-striped">
+ <thead>
+ <tr>
+ <th>Name(<%= String.format("%,1d", regions.size())%>)</th>
+ <th>Region Server</th>
+ <th>ReadRequests<br>(<%= String.format("%,1d", totalReadReq)%>)</th>
+ <th>WriteRequests<br>(<%= String.format("%,1d", totalWriteReq)%>)</th>
+ <th>StorefileSize<br>(<%= totalSizeStr %>)</th>
+ <th>Num.Storefiles<br>(<%= String.format("%,1d", totalStoreFileCount)%>)</th>
+ <th>MemSize<br>(<%= totalMemSizeStr %>)</th>
+ <th>Locality</th>
+ <th>Start Key</th>
+ <th>End Key</th>
+ <th>Region State</th>
+ <%
+ if (withReplica) {
+ %>
+ <th>ReplicaID</th>
+ <%
+ }
+ %>
+ </tr>
+ </thead>
+ <tbody>
+ <%
+ List<Map.Entry<RegionInfo, RegionMetrics>> entryList = new ArrayList<>(regionsToLoad.entrySet());
+ numRegions = regions.size();
+ int numRegionsRendered = 0;
+ // render all regions
+ if (numRegionsToRender < 0) {
+ numRegionsToRender = numRegions;
+ }
+ for (Map.Entry<RegionInfo, RegionMetrics> hriEntry : entryList) {
+ RegionInfo regionInfo = hriEntry.getKey();
+ ServerName addr = regionsToServer.get(regionInfo);
+ RegionMetrics load = hriEntry.getValue();
+ String readReq = "N/A";
+ String writeReq = "N/A";
+ String regionSize = ZEROMB;
+ String fileCount = "N/A";
+ String memSize = ZEROMB;
+ float locality = 0.0f;
+ String state = "N/A";
+ if (load != null) {
+ readReq = String.format("%,1d", load.getReadRequestCount());
+ writeReq = String.format("%,1d", load.getWriteRequestCount());
+ double rSize = load.getStoreFileSize().get(Size.Unit.BYTE);
+ if (rSize > 0) {
+ regionSize = StringUtils.byteDesc((long)rSize);
+ }
+ fileCount = String.format("%,1d", load.getStoreFileCount());
+ double mSize = load.getMemStoreSize().get(Size.Unit.BYTE);
+ if (mSize > 0) {
+ memSize = StringUtils.byteDesc((long)mSize);
+ }
+ locality = load.getDataLocality();
+ }
+ if (stateMap.containsKey(regionInfo.getEncodedName())) {
+ state = stateMap.get(regionInfo.getEncodedName()).toString();
+ }
+ if (addr != null) {
+ ServerMetrics sl = master.getServerManager().getLoad(addr);
+ // This port might be wrong if RS actually ended up using something else.
+ urlRegionServer =
+ "//" + URLEncoder.encode(addr.getHostname()) + ":" + master.getRegionServerInfoPort(addr) + "/rs-status";
+ if(sl != null) {
+ Integer i = regDistribution.get(addr);
+ if (null == i) i = Integer.valueOf(0);
+ regDistribution.put(addr, i + 1);
+ if (withReplica && RegionReplicaUtil.isDefaultReplica(regionInfo.getReplicaId())) {
+ i = primaryRegDistribution.get(addr);
+ if (null == i) i = Integer.valueOf(0);
+ primaryRegDistribution.put(addr, i+1);
+ }
+ }
+ }
+ if (numRegionsRendered < numRegionsToRender) {
+ numRegionsRendered++;
+ %>
+ <tr>
+ <td><%= escapeXml(Bytes.toStringBinary(regionInfo.getRegionName())) %></td>
+ <%
+ if (urlRegionServer != null) {
+ %>
+ <td>
+ <a href="<%= urlRegionServer %>"><%= addr == null? "-": StringEscapeUtils.escapeHtml4(addr.getHostname().toString()) + ":" + master.getRegionServerInfoPort(addr) %></a>
+ </td>
+ <%
+ } else {
+ %>
+ <td class="undeployed-region">not deployed</td>
+ <%
+ }
+ %>
+ <td><%= readReq%></td>
+ <td><%= writeReq%></td>
+ <td><%= regionSize%></td>
+ <td><%= fileCount%></td>
+ <td><%= memSize%></td>
+ <td><%= locality%></td>
+ <td><%= escapeXml(Bytes.toStringBinary(regionInfo.getStartKey()))%></td>
+ <td><%= escapeXml(Bytes.toStringBinary(regionInfo.getEndKey()))%></td>
+ <td><%= state%></td>
+ <%
+ if (withReplica) {
+ %>
+ <td><%= regionInfo.getReplicaId() %></td>
+ <%
+ }
+ %>
+ </tr>
+ <% } %>
+ <% } %>
+ </tbody>
+ </table>
+ <% if (numRegions > numRegionsRendered) {
+ String allRegionsUrl = "?name=" + URLEncoder.encode(fqtn,"UTF-8") + "&numRegions=all";
+ %>
+ <p>This table has <b><%= numRegions %></b> regions in total, in order to improve the page load time,
+ only <b><%= numRegionsRendered %></b> regions are displayed here, <a href="<%= allRegionsUrl %>">click
+ here</a> to see all regions.</p>
+ <% } %>
+ </div>
+ <div class="tab-pane" id="tab_compactStats">
+ <table id="tableCompactStatsTable" class="tablesorter table table-striped">
+ <thead>
+ <tr>
+ <th>Name(<%= String.format("%,1d", regions.size())%>)</th>
+ <th>Region Server</th>
+ <th>Num. Compacting Cells<br>(<%= String.format("%,1d", totalCompactingCells)%>)</th>
+ <th>Num. Compacted Cells<br>(<%= String.format("%,1d", totalCompactedCells)%>)</th>
+ <th>Remaining Cells<br>(<%= String.format("%,1d", totalCompactingCells-totalCompactedCells)%>)</th>
+ <th>Compaction Progress<br>(<%= totalCompactionProgress %>)</th>
+ </tr>
+ </thead>
+ <tbody>
+ <%
+ numRegionsRendered = 0;
+ for (Map.Entry<RegionInfo, RegionMetrics> hriEntry : entryList) {
+ RegionInfo regionInfo = hriEntry.getKey();
+ ServerName addr = regionsToServer.get(regionInfo);
+ RegionMetrics load = hriEntry.getValue();
+ long compactingCells = 0;
+ long compactedCells = 0;
+ String compactionProgress = "";
+ if (load != null) {
+ compactingCells = load.getCompactingCellCount();
+ compactedCells = load.getCompactedCellCount();
+ if (compactingCells > 0) {
+ compactionProgress = String.format("%.2f", 100 * ((float)
+ compactedCells / compactingCells)) + "%";
+ }
+ }
+ if (addr != null) {
+ // This port might be wrong if RS actually ended up using something else.
+ urlRegionServer =
+ "//" + URLEncoder.encode(addr.getHostname()) + ":" + master.getRegionServerInfoPort(addr) + "/rs-status";
+ }
+ if (numRegionsRendered < numRegionsToRender) {
+ numRegionsRendered++;
+ %>
+ <tr>
+ <td><%= escapeXml(Bytes.toStringBinary(regionInfo.getRegionName())) %></td>
+ <%
+ if (urlRegionServer != null) {
+ %>
+ <td>
+ <a href="<%= urlRegionServer %>"><%= addr == null? "-": StringEscapeUtils.escapeHtml4(addr.getHostname().toString()) + ":" + master.getRegionServerInfoPort(addr) %></a>
+ </td>
+ <%
+ } else {
+ %>
+ <td class="undeployed-region">not deployed</td>
+ <%
+ }
+ %>
+ <td><%= String.format("%,1d", compactingCells)%></td>
+ <td><%= String.format("%,1d", compactedCells)%></td>
+ <td><%= String.format("%,1d", compactingCells - compactedCells)%></td>
+ <td><%= compactionProgress%></td>
+ </tr>
+ <% } %>
+ <% } %>
+ </tbody>
+ </table>
+ <% if (numRegions > numRegionsRendered) {
+ String allRegionsUrl = "?name=" + URLEncoder.encode(fqtn,"UTF-8") + "&numRegions=all";
+ %>
+ <p>This table has <b><%= numRegions %></b> regions in total, in order to improve the page load time,
+ only <b><%= numRegionsRendered %></b> regions are displayed here, <a href="<%= allRegionsUrl %>">click
+ here</a> to see all regions.</p>
+ <% } %>
+ </div>
+ </div>
+ </div>
+ <h2>Regions by Region Server</h2>
+ <%
+ if (withReplica) {
+ %>
+ <table id="regionServerTable" class="tablesorter table table-striped"><thead><tr><th>Region Server</th><th>Region Count</th><th>Primary Region Count</th></tr></thead>
+ <%
} else {
%>
-<table id="regionServerTable" class="tablesorter table table-striped"><thead><tr><th>Region Server</th><th>Region Count</th></tr></thead>
-<tbody>
-<%
-}
-%>
-<%
- for (Map.Entry<ServerName, Integer> rdEntry : regDistribution.entrySet()) {
- ServerName addr = rdEntry.getKey();
- String url = "//" + URLEncoder.encode(addr.getHostname()) + ":" + master.getRegionServerInfoPort(addr) + "/rs-status";
-%>
-<tr>
- <td><a href="<%= url %>"><%= StringEscapeUtils.escapeHtml4(addr.getHostname().toString()) + ":" + master.getRegionServerInfoPort(addr) %></a></td>
- <td><%= rdEntry.getValue()%></td>
-<%
-if (withReplica) {
-%>
- <td><%= primaryRegDistribution.get(addr)%></td>
-<%
-}
-%>
-</tr>
-<% } %>
-</tbody>
-</table>
-<% }
+ <table id="regionServerTable" class="tablesorter table table-striped"><thead><tr><th>Region Server</th><th>Region Count</th></tr></thead>
+ <tbody>
+ <%
+ }
+ %>
+ <%
+ for (Map.Entry<ServerName, Integer> rdEntry : regDistribution.entrySet()) {
+ ServerName addr = rdEntry.getKey();
+ String url = "//" + URLEncoder.encode(addr.getHostname()) + ":" + master.getRegionServerInfoPort(addr) + "/rs-status";
+ %>
+ <tr>
+ <td><a href="<%= url %>"><%= StringEscapeUtils.escapeHtml4(addr.getHostname().toString()) + ":" + master.getRegionServerInfoPort(addr) %></a></td>
+ <td><%= rdEntry.getValue()%></td>
+ <%
+ if (withReplica) {
+ %>
+ <td><%= primaryRegDistribution.get(addr)%></td>
+ <%
+ }
+ %>
+ </tr>
+ <% } %>
+ </tbody>
+ </table>
+ <% }
} catch(Exception ex) {
for(StackTraceElement element : ex.getStackTrace()) {
%><%= StringEscapeUtils.escapeHtml4(element.toString()) %><%
@@ -642,129 +835,129 @@ if (withReplica) {
} // end else
%>
-<h2>Table Stats</h2>
-<table class="table table-striped">
- <tr>
- <th>Name</th>
- <th>Value</th>
- <th>Description</th>
- </tr>
- <tr>
- <td>Size</td>
- <td>
- <%
- if (totalStoreFileSizeMB > 0) {
- %>
- <%= StringUtils.TraditionalBinaryPrefix.
- long2String(totalStoreFileSizeMB * 1024 * 1024, "B", 2)%></td>
- <%
- } else {
- %>
- 0 MB </td>
- <%
- }
- %>
- <td>Total size of store files</td>
- </tr>
-</table>
+ <h2>Table Stats</h2>
+ <table class="table table-striped">
+ <tr>
+ <th>Name</th>
+ <th>Value</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td>Size</td>
+ <td>
+ <%
+ if (totalStoreFileSizeMB > 0) {
+ %>
+ <%= StringUtils.TraditionalBinaryPrefix.
+ long2String(totalStoreFileSizeMB * 1024 * 1024, "B", 2)%></td>
+ <%
+ } else {
+ %>
+ 0 MB </td>
+ <%
+ }
+ %>
+ <td>Total size of store files</td>
+ </tr>
+ </table>
-<% if (!readOnly) { %>
-<p><hr/></p>
-Actions:
-<p>
-<center>
-<table class="table" style="border: 0;" width="95%" >
-<tr>
- <form method="get">
- <input type="hidden" name="action" value="compact" />
- <input type="hidden" name="name" value="<%= escaped_fqtn %>" />
- <td class="centered">
- <input style="font-size: 12pt; width: 10em" type="submit" value="Compact" class="btn" />
- </td>
- <td style="text-align: center;">
- <input type="text" name="key" size="40" placeholder="Row Key (optional)" />
- </td>
- <td>
- This action will force a compaction of all regions of the table, or,
- if a key is supplied, only the region containing the
- given key.
- </td>
- </form>
-</tr>
-<tr>
- <form method="get">
- <input type="hidden" name="action" value="split" />
- <input type="hidden" name="name" value="<%= escaped_fqtn %>" />
- <td class="centered">
- <input style="font-size: 12pt; width: 10em" type="submit" value="Split" class="btn" />
- </td>
- <td style="text-align: center;">
- <input type="text" name="key" size="40" placeholder="Row Key (optional)" />
- </td>
- <td>
- This action will force a split of all eligible
- regions of the table, or, if a key is supplied, only the region containing the
- given key. An eligible region is one that does not contain any references to
- other regions. Split requests for noneligible regions will be ignored.
- </td>
- </form>
-</tr>
-<tr>
- <form method="get">
- <input type="hidden" name="action" value="merge" />
- <input type="hidden" name="name" value="<%= escaped_fqtn %>" />
- <td class="centered">
- <input style="font-size: 12pt; width: 10em" type="submit" value="Merge" class="btn" />
- </td>
- <td style="text-align: center;">
- <input type="text" name="left" size="40" placeholder="Region Key (required)" />
- <input type="text" name="right" size="40" placeholder="Region Key (required)" />
- </td>
- <td>
- This action will merge two regions of the table, Merge requests for
- noneligible regions will be ignored.
- </td>
- </form>
-</tr>
-</table>
-</center>
-</p>
-<% } %>
-</div>
+ <% if (!readOnly) { %>
+ <p><hr/></p>
+ Actions:
+ <p>
+ <center>
+ <table class="table" style="border: 0;" width="95%" >
+ <tr>
+ <form method="get">
+ <input type="hidden" name="action" value="compact" />
+ <input type="hidden" name="name" value="<%= escaped_fqtn %>" />
+ <td class="centered">
+ <input style="font-size: 12pt; width: 10em" type="submit" value="Compact" class="btn" />
+ </td>
+ <td style="text-align: center;">
+ <input type="text" name="key" size="40" placeholder="Row Key (optional)" />
+ </td>
+ <td>
+ This action will force a compaction of all regions of the table, or,
+ if a key is supplied, only the region containing the
+ given key.
+ </td>
+ </form>
+ </tr>
+ <tr>
+ <form method="get">
+ <input type="hidden" name="action" value="split" />
+ <input type="hidden" name="name" value="<%= escaped_fqtn %>" />
+ <td class="centered">
+ <input style="font-size: 12pt; width: 10em" type="submit" value="Split" class="btn" />
+ </td>
+ <td style="text-align: center;">
+ <input type="text" name="key" size="40" placeholder="Row Key (optional)" />
+ </td>
+ <td>
+ This action will force a split of all eligible
+ regions of the table, or, if a key is supplied, only the region containing the
+ given key. An eligible region is one that does not contain any references to
+ other regions. Split requests for noneligible regions will be ignored.
+ </td>
+ </form>
+ </tr>
+ <tr>
+ <form method="get">
+ <input type="hidden" name="action" value="merge" />
+ <input type="hidden" name="name" value="<%= escaped_fqtn %>" />
+ <td class="centered">
+ <input style="font-size: 12pt; width: 10em" type="submit" value="Merge" class="btn" />
+ </td>
+ <td style="text-align: center;">
+ <input type="text" name="left" size="40" placeholder="Region Key (required)" />
+ <input type="text" name="right" size="40" placeholder="Region Key (required)" />
+ </td>
+ <td>
+ This action will merge two regions of the table, Merge requests for
+ noneligible regions will be ignored.
+ </td>
+ </form>
+ </tr>
+ </table>
+ </center>
+ </p>
+ <% } %>
+ </div>
</div>
<% }
- } catch(TableNotFoundException e) { %>
- <div class="container-fluid content">
- <div class="row inner_header">
- <div class="page-header">
- <h1>Table not found</h1>
- </div>
+} catch(TableNotFoundException e) { %>
+<div class="container-fluid content">
+ <div class="row inner_header">
+ <div class="page-header">
+ <h1>Table not found</h1>
</div>
- <p><hr><p>
- <p>Go <a href="javascript:history.back()">Back</a>
- </div> <%
- } catch(IllegalArgumentException e) { %>
- <div class="container-fluid content">
- <div class="row inner_header">
- <div class="page-header">
- <h1>Table qualifier must not be empty</h1>
- </div>
+ </div>
+ <p><hr><p>
+ <p>Go <a href="javascript:history.back()">Back</a>
+</div> <%
+} catch(IllegalArgumentException e) { %>
+<div class="container-fluid content">
+ <div class="row inner_header">
+ <div class="page-header">
+ <h1>Table qualifier must not be empty</h1>
</div>
- <p><hr><p>
- <p>Go <a href="javascript:history.back()">Back</a>
- </div> <%
+ </div>
+ <p><hr><p>
+ <p>Go <a href="javascript:history.back()">Back</a>
+</div> <%
}
}
- else { // handle the case for fqtn is null or master is not initialized with error message + redirect
+else { // handle the case for fqtn is null or master is not initialized with error message + redirect
%>
<div class="container-fluid content">
- <div class="row inner_header">
- <div class="page-header">
- <h1>Table not ready</h1>
- </div>
+ <div class="row inner_header">
+ <div class="page-header">
+ <h1>Table not ready</h1>
</div>
-<p><hr><p>
-<jsp:include page="redirect.jsp" />
+ </div>
+ <p><hr><p>
+ <jsp:include page="redirect.jsp" />
</div>
<% } %>
@@ -774,64 +967,78 @@ Actions:
<script src="/static/js/bootstrap.min.js" type="text/javascript"></script>
<script>
-$(document).ready(function()
- {
- $.tablesorter.addParser(
+ $(document).ready(function()
{
- id: 'filesize',
- is: function(s) {
- return s.match(new RegExp( /([\.0-9]+)\ (B|KB|MB|GB|TB)/ ));
- },
- format: function(s) {
- var suf = s.match(new RegExp( /(B|KB|MB|GB|TB)$/ ))[1];
- var num = parseFloat(s.match( new RegExp( /([\.0-9]+)\ (B|KB|MB|GB|TB)/ ))[0]);
- switch(suf) {
- case 'B':
- return num;
- case 'KB':
- return num * 1024;
- case 'MB':
- return num * 1024 * 1024;
- case 'GB':
- return num * 1024 * 1024 * 1024;
- case 'TB':
- return num * 1024 * 1024 * 1024 * 1024;
+ $.tablesorter.addParser(
+ {
+ id: 'filesize',
+ is: function(s) {
+ return s.match(new RegExp( /([\.0-9]+)\ (B|KB|MB|GB|TB)/ ));
+ },
+ format: function(s) {
+ var suf = s.match(new RegExp( /(B|KB|MB|GB|TB)$/ ))[1];
+ var num = parseFloat(s.match( new RegExp( /([\.0-9]+)\ (B|KB|MB|GB|TB)/ ))[0]);
+ switch(suf) {
+ case 'B':
+ return num;
+ case 'KB':
+ return num * 1024;
+ case 'MB':
+ return num * 1024 * 1024;
+ case 'GB':
+ return num * 1024 * 1024 * 1024;
+ case 'TB':
+ return num * 1024 * 1024 * 1024 * 1024;
+ }
+ },
+ type: 'numeric'
+ });
+ $.tablesorter.addParser(
+ {
+ id: "separator",
+ is: function (s) {
+ return /^[0-9]?[0-9,]*$/.test(s);
+ }, format: function (s) {
+ return $.tablesorter.formatFloat( s.replace(/,/g,'') );
+ }, type: "numeric"
+ });
+ $("#regionServerTable").tablesorter({
+ headers: {
+ 1: {sorter: 'separator'}
}
- },
- type: 'numeric'
- });
- $.tablesorter.addParser(
- {
- id: "separator",
- is: function (s) {
- return /^[0-9]?[0-9,]*$/.test(s);
- }, format: function (s) {
- return $.tablesorter.formatFloat( s.replace(/,/g,'') );
- }, type: "numeric"
- });
- $("#regionServerTable").tablesorter({
- headers: {
- 1: {sorter: 'separator'}
- }
- });
- $("#regionServerDetailsTable").tablesorter({
- headers: {
- 2: {sorter: 'separator'},
- 3: {sorter: 'separator'},
- 4: {sorter: 'filesize'},
- 5: {sorter: 'separator'},
- 6: {sorter: 'filesize'}
- }
- });
- $("#tableRegionTable").tablesorter({
- headers: {
- 2: {sorter: 'separator'},
- 3: {sorter: 'separator'},
- 4: {sorter: 'filesize'},
- 5: {sorter: 'separator'},
- 6: {sorter: 'filesize'}
- }
- });
- }
-);
+ });
+ $("#regionServerDetailsTable").tablesorter({
+ headers: {
+ 2: {sorter: 'separator'},
+ 3: {sorter: 'separator'},
+ 4: {sorter: 'filesize'},
+ 5: {sorter: 'separator'},
+ 6: {sorter: 'filesize'}
+ }
+ });
+ $("#tableRegionTable").tablesorter({
+ headers: {
+ 2: {sorter: 'separator'},
+ 3: {sorter: 'separator'},
+ 4: {sorter: 'filesize'},
+ 5: {sorter: 'separator'},
+ 6: {sorter: 'filesize'}
+ }
+ });
+ $("#tableCompactStatsTable").tablesorter({
+ headers: {
+ 2: {sorter: 'separator'},
+ 3: {sorter: 'separator'},
+ 4: {sorter: 'separator'}
+ }
+ });
+ $("#metaTableCompactStatsTable").tablesorter({
+ headers: {
+ 2: {sorter: 'separator'},
+ 3: {sorter: 'separator'},
+ 4: {sorter: 'separator'}
+ }
+ });
+ }
+ );
</script>