HBASE-22945 Show quota infos in master UI (#560)

Signed-off-by: Duo Zhang <zhangduo@apache.org>
This commit is contained in:
meiyi 2019-09-01 22:42:47 +08:00 committed by Duo Zhang
parent 97fbaa658e
commit 345c21dbe7
5 changed files with 227 additions and 2 deletions

View File

@ -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;

View File

@ -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>

View File

@ -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) {

View File

@ -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>

View File

@ -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" />