You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by zh...@apache.org on 2019/09/01 14:42:53 UTC

[hbase] branch master updated: HBASE-22945 Show quota infos in master UI (#560)

This is an automated email from the ASF dual-hosted git repository.

zhangduo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hbase.git


The following commit(s) were added to refs/heads/master by this push:
     new 345c21d  HBASE-22945 Show quota infos in master UI (#560)
345c21d is described below

commit 345c21dbe7a663cc0364dc1e3642103ac21751cf
Author: meiyi <my...@gmail.com>
AuthorDate: Sun Sep 1 22:42:47 2019 +0800

    HBASE-22945 Show quota infos in master UI (#560)
    
    Signed-off-by: Duo Zhang <zh...@apache.org>
---
 .../hadoop/hbase/quotas/ThrottleSettings.java      |   7 +-
 .../hbase/tmpl/master/MasterStatusTmpl.jamon       |   3 +
 .../hadoop/hbase/quotas/MasterQuotaManager.java    |  11 +-
 .../main/resources/hbase-webapps/master/header.jsp |   4 +
 .../main/resources/hbase-webapps/master/quotas.jsp | 204 +++++++++++++++++++++
 5 files changed, 227 insertions(+), 2 deletions(-)

diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/quotas/ThrottleSettings.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/quotas/ThrottleSettings.java
index c616620..3c25d6e 100644
--- a/hbase-client/src/main/java/org/apache/hadoop/hbase/quotas/ThrottleSettings.java
+++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/quotas/ThrottleSettings.java
@@ -32,7 +32,7 @@ import org.apache.hadoop.hbase.shaded.protobuf.generated.QuotaProtos.TimedQuota;
 
 @InterfaceAudience.Private
 @InterfaceStability.Evolving
-class ThrottleSettings extends QuotaSettings {
+public class ThrottleSettings extends QuotaSettings {
   final QuotaProtos.ThrottleRequest proto;
 
   ThrottleSettings(final String userName, final TableName tableName, final String namespace,
@@ -62,6 +62,11 @@ class ThrottleSettings extends QuotaSettings {
       ProtobufUtil.toTimeUnit(proto.getTimedQuota().getTimeUnit()) : null;
   }
 
+  public QuotaScope getQuotaScope() {
+    return proto.hasTimedQuota() ? ProtobufUtil.toQuotaScope(proto.getTimedQuota().getScope())
+        : null;
+  }
+
   @Override
   public QuotaType getQuotaType() {
     return QuotaType.THROTTLE;
diff --git a/hbase-server/src/main/jamon/org/apache/hadoop/hbase/tmpl/master/MasterStatusTmpl.jamon b/hbase-server/src/main/jamon/org/apache/hadoop/hbase/tmpl/master/MasterStatusTmpl.jamon
index 5423c17..e5541a7 100644
--- a/hbase-server/src/main/jamon/org/apache/hadoop/hbase/tmpl/master/MasterStatusTmpl.jamon
+++ b/hbase-server/src/main/jamon/org/apache/hadoop/hbase/tmpl/master/MasterStatusTmpl.jamon
@@ -151,6 +151,9 @@ AssignmentManager assignmentManager = master.getAssignmentManager();
                 <%if master.isActiveMaster() %>
                     <li><a href="/procedures.jsp">Procedures &amp; Locks</a></li>
                     <li><a href="/hbck.jsp">HBCK Report</a></li>
+                    <%if master.getConfiguration().getBoolean(QuotaUtil.QUOTA_CONF_KEY, false) %>
+                        <li><a href="/quotas.jsp">Quotas</a></li>
+                    </%if>
                 </%if>
                 <li><a href="/processMaster.jsp">Process Metrics</a></li>
                 <li><a href="/logs/">Local Logs</a></li>
diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/quotas/MasterQuotaManager.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/quotas/MasterQuotaManager.java
index 65a47d1..01fe427 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/quotas/MasterQuotaManager.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/quotas/MasterQuotaManager.java
@@ -406,7 +406,7 @@ public class MasterQuotaManager implements RegionStateListener {
       throws IOException {
     if (initialized) {
       masterServices.getMasterCoprocessorHost().preIsRpcThrottleEnabled();
-      boolean enabled = rpcThrottleStorage.isRpcThrottleEnabled();
+      boolean enabled = isRpcThrottleEnabled();
       IsRpcThrottleEnabledResponse response =
           IsRpcThrottleEnabledResponse.newBuilder().setRpcThrottleEnabled(enabled).build();
       masterServices.getMasterCoprocessorHost().postIsRpcThrottleEnabled(enabled);
@@ -417,6 +417,10 @@ public class MasterQuotaManager implements RegionStateListener {
     }
   }
 
+  public boolean isRpcThrottleEnabled() throws IOException {
+    return initialized ? rpcThrottleStorage.isRpcThrottleEnabled() : false;
+  }
+
   public SwitchExceedThrottleQuotaResponse
       switchExceedThrottleQuota(SwitchExceedThrottleQuotaRequest request) throws IOException {
     boolean enabled = request.getExceedThrottleQuotaEnabled();
@@ -444,6 +448,11 @@ public class MasterQuotaManager implements RegionStateListener {
     }
   }
 
+  public boolean isExceedThrottleQuotaEnabled() throws IOException {
+    return initialized ? QuotaUtil.isExceedThrottleQuotaEnabled(masterServices.getConnection())
+        : false;
+  }
+
   private void setQuota(final SetQuotaRequest req, final SetQuotaOperations quotaOps)
       throws IOException, InterruptedException {
     if (req.hasRemoveAll() && req.getRemoveAll() == true) {
diff --git a/hbase-server/src/main/resources/hbase-webapps/master/header.jsp b/hbase-server/src/main/resources/hbase-webapps/master/header.jsp
index 1d3d6b1..98efdf0 100644
--- a/hbase-server/src/main/resources/hbase-webapps/master/header.jsp
+++ b/hbase-server/src/main/resources/hbase-webapps/master/header.jsp
@@ -19,6 +19,7 @@
 --%>
 <%@ page contentType="text/html;charset=UTF-8"
     import="org.apache.hadoop.hbase.master.HMaster"
+    import="org.apache.hadoop.hbase.quotas.QuotaUtil"
     import="org.apache.hadoop.hbase.HBaseConfiguration"
 %>
 <%
@@ -59,6 +60,9 @@
             <% if (master.isActiveMaster()){ %>
               <li><a href="/procedures.jsp">Procedures &amp; Locks</a></li>
               <li><a href="/hbck.jsp">HBCK Report</a></li>
+              <% if (master.getConfiguration().getBoolean(QuotaUtil.QUOTA_CONF_KEY, false)) { %>
+                <li><a href="/quotas.jsp">Quotas</a></li>
+              <% }%>
             <% }%>
             <li><a href="/processMaster.jsp">Process Metrics</a></li>
             <li><a href="/logs/">Local Logs</a></li>
diff --git a/hbase-server/src/main/resources/hbase-webapps/master/quotas.jsp b/hbase-server/src/main/resources/hbase-webapps/master/quotas.jsp
new file mode 100644
index 0000000..4909ab6
--- /dev/null
+++ b/hbase-server/src/main/resources/hbase-webapps/master/quotas.jsp
@@ -0,0 +1,204 @@
+<%--
+/**
+ * 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.
+ */
+--%>
+<%@ page contentType="text/html;charset=UTF-8"
+  import="java.util.concurrent.TimeUnit"
+  import="java.util.ArrayList"
+  import="java.util.List"
+  import="org.apache.hadoop.conf.Configuration"
+  import="org.apache.hadoop.hbase.master.HMaster"
+  import="org.apache.hadoop.hbase.quotas.QuotaRetriever"
+  import="org.apache.hadoop.hbase.quotas.QuotaSettings"
+  import="org.apache.hadoop.hbase.quotas.ThrottleSettings"
+%>
+<%
+  HMaster master = (HMaster) getServletContext().getAttribute(HMaster.MASTER);
+  Configuration conf = master.getConfiguration();
+  pageContext.setAttribute("pageTitle", "HBase Master Quotas: " + master.getServerName());
+  boolean exceedThrottleQuotaEnabled = master.getMasterQuotaManager().isExceedThrottleQuotaEnabled();
+  List<ThrottleSettings> regionServerThrottles = new ArrayList<>();
+  List<ThrottleSettings> namespaceThrottles = new ArrayList<>();
+  List<ThrottleSettings> userThrottles = new ArrayList<>();
+  try (QuotaRetriever scanner = QuotaRetriever.open(conf, null)) {
+    for (QuotaSettings quota : scanner) {
+      if (quota instanceof ThrottleSettings) {
+        ThrottleSettings throttle = (ThrottleSettings) quota;
+        if (throttle.getUserName() != null) {
+          userThrottles.add(throttle);
+        } else if (throttle.getNamespace() != null) {
+          namespaceThrottles.add(throttle);
+        } else if (throttle.getRegionServer() != null) {
+          regionServerThrottles.add(throttle);
+        }
+      }
+    }
+  }
+%>
+<jsp:include page="header.jsp">
+    <jsp:param name="pageTitle" value="${pageTitle}"/>
+</jsp:include>
+<div class="container-fluid content">
+  <div class="row">
+    <div class="page-header">
+      <h1>Throttle Quotas</h1>
+    </div>
+  </div>
+</div>
+
+<div class="container-fluid content">
+  <div class="row">
+    <div class="page-header">
+      <h2>Rpc Throttle Enabled</h2>
+    </div>
+  </div>
+  <%if (master.getMasterQuotaManager().isRpcThrottleEnabled()) {%>
+  <div class="alert alert-success">
+    Rpc throttle is enabled.
+  </div>
+  <% } else {%>
+  <div class="alert alert-info">
+    Rpc throttle is disabled. All requests will not be throttled.<br/>
+    Use 'enable_rpc_throttle' shell command to enable it.
+  </div>
+  <% } %>
+</div>
+
+<div class="container-fluid content">
+  <div class="row">
+    <div class="page-header">
+      <h2>Exceed Throttle Quota Enabled</h2>
+    </div>
+  </div>
+  <%if (exceedThrottleQuotaEnabled) {%>
+  <div class="alert alert-success">
+    Exceed throttle quota is enabled. The user/table/namespace throttle quotas can exceed the limit
+    if a region server has available quotas.<br/>
+    Use 'disable_exceed_throttle_quota' shell command to disable it.
+  </div>
+  <% } else {%>
+  <div class="alert alert-info">
+    Exceed throttle quota is disabled.
+  </div>
+  <% } %>
+</div>
+
+<div class="container-fluid content">
+  <div class="row">
+    <div class="page-header">
+      <h2>RegionServer Throttle Quotas</h2>
+    </div>
+  </div>
+<%
+  if (regionServerThrottles.size() > 0) {
+%>
+  <table class="table table-striped" width="90%" >
+    <tr>
+      <th>RegionServer</th>
+      <th>Limit</th>
+      <th>Type</th>
+      <th>TimeUnit</th>
+      <th>Scope</th>
+    </tr>
+    <% for (ThrottleSettings throttle : regionServerThrottles) { %>
+      <tr>
+        <td><%= throttle.getRegionServer() == null ? "" : throttle.getRegionServer() %></td>
+        <td><%= throttle.getSoftLimit() %></td>
+        <td><%= throttle.getThrottleType() %></td>
+        <td><%= throttle.getTimeUnit() %></td>
+        <td><%= throttle.getQuotaScope() %></td>
+        <% if (exceedThrottleQuotaEnabled && throttle.getTimeUnit() != null && throttle.getTimeUnit() != TimeUnit.SECONDS) { %>
+        <td style="color:red;">Exceed throttle quota is enabled, but RegionServer throttle is not in SECONDS time unit.</td>
+        <% }%>
+      </tr>
+    <% } %>
+  </table>
+  <% } else if (exceedThrottleQuotaEnabled) { %>
+  <div class="alert alert-danger">
+    Exceed throttle quota is enabled, but RegionServer throttle quotas are not set.<br/>
+    Please set RegionServer read and write throttle quotas in SECONDS time unit.<br/>
+    eg. set_quota TYPE => THROTTLE, REGIONSERVER => 'all', THROTTLE_TYPE => WRITE, LIMIT => '20000req/sec'
+  </div>
+  <%}%>
+</div>
+
+<div class="container-fluid content">
+  <div class="row">
+    <div class="page-header">
+      <h2>Namespace Throttle Quotas</h2>
+    </div>
+  </div>
+  <%
+    if (namespaceThrottles.size() > 0) {
+  %>
+  <table class="table table-striped" width="90%" >
+    <tr>
+      <th>Namespace</th>
+      <th>Limit</th>
+      <th>Type</th>
+      <th>TimeUnit</th>
+      <th>Scope</th>
+    </tr>
+    <% for (ThrottleSettings throttle : namespaceThrottles) { %>
+    <tr>
+      <td><%= throttle.getNamespace() == null ? "" : throttle.getNamespace() %></td>
+      <td><%= throttle.getSoftLimit() %></td>
+      <td><%= throttle.getThrottleType() %></td>
+      <td><%= throttle.getTimeUnit() %></td>
+      <td><%= throttle.getQuotaScope() %></td>
+    </tr>
+    <% } %>
+  </table>
+  <% } %>
+</div>
+
+<div class="container-fluid content">
+  <div class="row">
+    <div class="page-header">
+      <h2>User Throttle Quotas</h2>
+    </div>
+  </div>
+  <%
+    if (userThrottles.size() > 0) {
+  %>
+  <table class="table table-striped" width="90%" >
+    <tr>
+      <th>User</th>
+      <th>Namespace</th>
+      <th>Table</th>
+      <th>Limit</th>
+      <th>Type</th>
+      <th>TimeUnit</th>
+      <th>Scope</th>
+    </tr>
+    <% for (ThrottleSettings throttle : userThrottles) { %>
+    <tr>
+      <td><%= throttle.getUserName() == null ? "" : throttle.getUserName() %></td>
+      <td><%= throttle.getNamespace() == null ? "" : throttle.getNamespace() %></td>
+      <td><%= throttle.getTableName() == null ? "" : throttle.getTableName() %></td>
+      <td><%= throttle.getSoftLimit() %></td>
+      <td><%= throttle.getThrottleType() %></td>
+      <td><%= throttle.getTimeUnit() %></td>
+      <td><%= throttle.getQuotaScope() %></td>
+    </tr>
+    <% } %>
+  </table>
+  <% } %>
+</div>
+
+<jsp:include page="footer.jsp" />