From 41fddd411e9869474a2e4745db57d4896e2d599d Mon Sep 17 00:00:00 2001 From: meiyi Date: Sun, 1 Sep 2019 22:42:47 +0800 Subject: [PATCH] HBASE-22945 Show quota infos in master UI (#560) Signed-off-by: Duo Zhang --- .../hadoop/hbase/quotas/ThrottleSettings.java | 7 +- .../hbase/tmpl/master/MasterStatusTmpl.jamon | 3 + .../hbase/quotas/MasterQuotaManager.java | 11 +- .../resources/hbase-webapps/master/header.jsp | 4 + .../resources/hbase-webapps/master/quotas.jsp | 204 ++++++++++++++++++ 5 files changed, 227 insertions(+), 2 deletions(-) create mode 100644 hbase-server/src/main/resources/hbase-webapps/master/quotas.jsp 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 c6166207b15..3c25d6e4f94 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 3b43250588e..79738b40a65 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() %>
  • Procedures & Locks
  • HBCK Report
  • + <%if master.getConfiguration().getBoolean(QuotaUtil.QUOTA_CONF_KEY, false) %> +
  • Quotas
  • +
  • Process Metrics
  • Local Logs
  • 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 039862f349d..d17f1d51b73 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 @@ -396,7 +396,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); @@ -407,6 +407,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(); @@ -434,6 +438,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 1d3d6b1c04b..98efdf0c557 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()){ %>
  • Procedures & Locks
  • HBCK Report
  • + <% if (master.getConfiguration().getBoolean(QuotaUtil.QUOTA_CONF_KEY, false)) { %> +
  • Quotas
  • + <% }%> <% }%>
  • Process Metrics
  • Local Logs
  • 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 00000000000..4909ab63c36 --- /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 regionServerThrottles = new ArrayList<>(); + List namespaceThrottles = new ArrayList<>(); + List 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); + } + } + } + } +%> + + + +
    +
    + +
    +
    + +
    +
    + +
    + <%if (master.getMasterQuotaManager().isRpcThrottleEnabled()) {%> +
    + Rpc throttle is enabled. +
    + <% } else {%> +
    + Rpc throttle is disabled. All requests will not be throttled.
    + Use 'enable_rpc_throttle' shell command to enable it. +
    + <% } %> +
    + +
    +
    + +
    + <%if (exceedThrottleQuotaEnabled) {%> +
    + Exceed throttle quota is enabled. The user/table/namespace throttle quotas can exceed the limit + if a region server has available quotas.
    + Use 'disable_exceed_throttle_quota' shell command to disable it. +
    + <% } else {%> +
    + Exceed throttle quota is disabled. +
    + <% } %> +
    + +
    +
    + +
    +<% + if (regionServerThrottles.size() > 0) { +%> + + + + + + + + + <% for (ThrottleSettings throttle : regionServerThrottles) { %> + + + + + + + <% if (exceedThrottleQuotaEnabled && throttle.getTimeUnit() != null && throttle.getTimeUnit() != TimeUnit.SECONDS) { %> + + <% }%> + + <% } %> +
    RegionServerLimitTypeTimeUnitScope
    <%= throttle.getRegionServer() == null ? "" : throttle.getRegionServer() %><%= throttle.getSoftLimit() %><%= throttle.getThrottleType() %><%= throttle.getTimeUnit() %><%= throttle.getQuotaScope() %>Exceed throttle quota is enabled, but RegionServer throttle is not in SECONDS time unit.
    + <% } else if (exceedThrottleQuotaEnabled) { %> +
    + Exceed throttle quota is enabled, but RegionServer throttle quotas are not set.
    + Please set RegionServer read and write throttle quotas in SECONDS time unit.
    + eg. set_quota TYPE => THROTTLE, REGIONSERVER => 'all', THROTTLE_TYPE => WRITE, LIMIT => '20000req/sec' +
    + <%}%> +
    + +
    +
    + +
    + <% + if (namespaceThrottles.size() > 0) { + %> + + + + + + + + + <% for (ThrottleSettings throttle : namespaceThrottles) { %> + + + + + + + + <% } %> +
    NamespaceLimitTypeTimeUnitScope
    <%= throttle.getNamespace() == null ? "" : throttle.getNamespace() %><%= throttle.getSoftLimit() %><%= throttle.getThrottleType() %><%= throttle.getTimeUnit() %><%= throttle.getQuotaScope() %>
    + <% } %> +
    + +
    +
    + +
    + <% + if (userThrottles.size() > 0) { + %> + + + + + + + + + + + <% for (ThrottleSettings throttle : userThrottles) { %> + + + + + + + + + + <% } %> +
    UserNamespaceTableLimitTypeTimeUnitScope
    <%= throttle.getUserName() == null ? "" : throttle.getUserName() %><%= throttle.getNamespace() == null ? "" : throttle.getNamespace() %><%= throttle.getTableName() == null ? "" : throttle.getTableName() %><%= throttle.getSoftLimit() %><%= throttle.getThrottleType() %><%= throttle.getTimeUnit() %><%= throttle.getQuotaScope() %>
    + <% } %> +
    + +