HBASE-13222 Add isBalancerEnabled method to Master and Admin.
Include some basic tests for the method on a testing cluster. Also update master page to show an alert when balancer is disabled. Signed-off-by: Enis Soztutar <enis@apache.org>
This commit is contained in:
parent
a4a235b8d1
commit
98b1e72d1c
|
@ -702,6 +702,13 @@ public interface Admin extends Abortable, Closeable {
|
|||
*/
|
||||
boolean balancer() throws IOException;
|
||||
|
||||
/**
|
||||
* Query the current state of the balancer
|
||||
*
|
||||
* @return true if the balancer is enabled, false otherwise.
|
||||
*/
|
||||
boolean isBalancerEnabled() throws IOException;
|
||||
|
||||
/**
|
||||
* Enable/Disable the catalog janitor
|
||||
*
|
||||
|
|
|
@ -22,6 +22,7 @@ import com.google.common.annotations.VisibleForTesting;
|
|||
import com.google.protobuf.BlockingRpcChannel;
|
||||
import com.google.protobuf.RpcController;
|
||||
import com.google.protobuf.ServiceException;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.hadoop.conf.Configuration;
|
||||
|
@ -53,6 +54,8 @@ import org.apache.hadoop.hbase.protobuf.RequestConverter;
|
|||
import org.apache.hadoop.hbase.protobuf.generated.AdminProtos;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.ClientProtos;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsBalancerEnabledRequest;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsBalancerEnabledResponse;
|
||||
import org.apache.hadoop.hbase.regionserver.RegionServerStoppedException;
|
||||
import org.apache.hadoop.hbase.security.User;
|
||||
import org.apache.hadoop.hbase.util.Bytes;
|
||||
|
@ -1589,6 +1592,12 @@ class ConnectionImplementation implements ClusterConnection, Closeable {
|
|||
throws ServiceException {
|
||||
return stub.getLastMajorCompactionTimestampForRegion(controller, request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IsBalancerEnabledResponse isBalancerEnabled(RpcController controller,
|
||||
IsBalancerEnabledRequest request) throws ServiceException {
|
||||
return stub.isBalancerEnabled(controller, request);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1970,6 +1970,23 @@ public class HBaseAdmin implements Admin {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Query the state of the balancer from the Master. It's not a guarantee that the balancer is
|
||||
* actually running this very moment, but that it will run.
|
||||
*
|
||||
* @return True if the balancer is enabled, false otherwise.
|
||||
*/
|
||||
@Override
|
||||
public boolean isBalancerEnabled() throws IOException {
|
||||
return executeCallable(new MasterCallable<Boolean>(getConnection()) {
|
||||
@Override
|
||||
public Boolean call(int callTimeout) throws ServiceException {
|
||||
return master.isBalancerEnabled(null, RequestConverter.buildIsBalancerEnabledRequest())
|
||||
.getEnabled();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable/Disable the catalog janitor
|
||||
* @param enable if true enables the catalog janitor
|
||||
|
|
|
@ -92,6 +92,7 @@ import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetSchemaAlterSta
|
|||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetTableDescriptorsRequest;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetTableNamesRequest;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetTableStateRequest;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsBalancerEnabledRequest;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsCatalogJanitorEnabledRequest;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsMasterRunningRequest;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.ModifyColumnRequest;
|
||||
|
@ -1339,6 +1340,15 @@ public final class RequestConverter {
|
|||
return SetBalancerRunningRequest.newBuilder().setOn(on).setSynchronous(synchronous).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a protocol buffer IsBalancerEnabledRequest
|
||||
*
|
||||
* @return a IsBalancerEnabledRequest
|
||||
*/
|
||||
public static IsBalancerEnabledRequest buildIsBalancerEnabledRequest() {
|
||||
return IsBalancerEnabledRequest.newBuilder().build();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see {@link #buildGetClusterStatusRequest}
|
||||
*/
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -232,6 +232,13 @@ message SetBalancerRunningResponse {
|
|||
optional bool prev_balance_value = 1;
|
||||
}
|
||||
|
||||
message IsBalancerEnabledRequest {
|
||||
}
|
||||
|
||||
message IsBalancerEnabledResponse {
|
||||
required bool enabled = 1;
|
||||
}
|
||||
|
||||
message RunCatalogScanRequest {
|
||||
}
|
||||
|
||||
|
@ -508,6 +515,12 @@ service MasterService {
|
|||
rpc SetBalancerRunning(SetBalancerRunningRequest)
|
||||
returns(SetBalancerRunningResponse);
|
||||
|
||||
/**
|
||||
* Query whether the Region Balancer is running.
|
||||
*/
|
||||
rpc IsBalancerEnabled(IsBalancerEnabledRequest)
|
||||
returns(IsBalancerEnabledResponse);
|
||||
|
||||
/** Get a run of the catalog janitor */
|
||||
rpc RunCatalogScan(RunCatalogScanRequest)
|
||||
returns(RunCatalogScanResponse);
|
||||
|
|
|
@ -158,6 +158,13 @@ AssignmentManager assignmentManager = master.getAssignmentManager();
|
|||
re-enabled from the hbase shell by running the command 'catalogjanitor_switch true'
|
||||
</div>
|
||||
</%if>
|
||||
<%if !master.isBalancerOn() %>
|
||||
<div class="alert alert-warning">
|
||||
The Load Balancer is not enabled which will eventually cause performance degradation
|
||||
in HBase as Regions will not be distributed across all RegionServers. The balancer
|
||||
is only expected to be disabled during rolling upgrade scenarios.
|
||||
</div>
|
||||
</%if>
|
||||
|
||||
<section>
|
||||
<h2>Region Servers</h2>
|
||||
|
@ -298,6 +305,11 @@ AssignmentManager assignmentManager = master.getAssignmentManager();
|
|||
java.util.Arrays.toString(master.getMasterCoprocessors()) %></td>
|
||||
<td>Coprocessors currently loaded by the master</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>LoadBalancer</td>
|
||||
<td><% master.getLoadBalancerClassName() %></td>
|
||||
<td>LoadBalancer to be used in the Master</td>
|
||||
</tr>
|
||||
</%if>
|
||||
</table>
|
||||
</section>
|
||||
|
|
|
@ -2302,4 +2302,25 @@ public class HMaster extends HRegionServer implements MasterServices, Server {
|
|||
public long getLastMajorCompactionTimestampForRegion(byte[] regionName) throws IOException {
|
||||
return getClusterStatus().getLastMajorCompactionTsForRegion(regionName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries the state of the {@link LoadBalancerTracker}. If the balancer is not initialized,
|
||||
* false is returned.
|
||||
*
|
||||
* @return The state of the load balancer, or false if the load balancer isn't defined.
|
||||
*/
|
||||
public boolean isBalancerOn() {
|
||||
if (null == loadBalancerTracker) return false;
|
||||
return loadBalancerTracker.isBalancerOn();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the configured {@link LoadBalancer} class name. If none is set, a default is returned.
|
||||
*
|
||||
* @return The name of the {@link LoadBalancer} in use.
|
||||
*/
|
||||
public String getLoadBalancerClassName() {
|
||||
return conf.get(HConstants.HBASE_MASTER_LOADBALANCER_CLASS, LoadBalancerFactory
|
||||
.getDefaultLoadBalancerClass().getName());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -92,6 +92,8 @@ import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetTableDescripto
|
|||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetTableDescriptorsResponse;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetTableNamesRequest;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetTableNamesResponse;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsBalancerEnabledRequest;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsBalancerEnabledResponse;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsCatalogJanitorEnabledRequest;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsCatalogJanitorEnabledResponse;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsMasterRunningRequest;
|
||||
|
@ -1305,4 +1307,12 @@ public class MasterRpcServices extends RSRpcServices
|
|||
}
|
||||
return response.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IsBalancerEnabledResponse isBalancerEnabled(RpcController controller,
|
||||
IsBalancerEnabledRequest request) throws ServiceException {
|
||||
IsBalancerEnabledResponse.Builder response = IsBalancerEnabledResponse.newBuilder();
|
||||
response.setEnabled(master.isBalancerOn());
|
||||
return response.build();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,6 +29,15 @@ import org.apache.hadoop.util.ReflectionUtils;
|
|||
@InterfaceAudience.Private
|
||||
public class LoadBalancerFactory {
|
||||
|
||||
/**
|
||||
* The default {@link LoadBalancer} class.
|
||||
*
|
||||
* @return The Class for the default {@link LoadBalancer}.
|
||||
*/
|
||||
public static Class<? extends LoadBalancer> getDefaultLoadBalancerClass() {
|
||||
return StochasticLoadBalancer.class;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a loadbalancer from the given conf.
|
||||
* @param conf
|
||||
|
@ -38,7 +47,7 @@ public class LoadBalancerFactory {
|
|||
|
||||
// Create the balancer
|
||||
Class<? extends LoadBalancer> balancerKlass =
|
||||
conf.getClass(HConstants.HBASE_MASTER_LOADBALANCER_CLASS, StochasticLoadBalancer.class,
|
||||
conf.getClass(HConstants.HBASE_MASTER_LOADBALANCER_CLASS, getDefaultLoadBalancerClass(),
|
||||
LoadBalancer.class);
|
||||
return ReflectionUtils.newInstance(balancerKlass, conf);
|
||||
|
||||
|
|
|
@ -726,4 +726,26 @@ public class TestAdmin2 {
|
|||
pair = rawAdmin.getRegion(region.getEncodedNameAsBytes());
|
||||
assertTrue(Bytes.equals(regionName, pair.getFirst().getRegionName()));
|
||||
}
|
||||
|
||||
@Test(timeout = 30000)
|
||||
public void testBalancer() throws Exception {
|
||||
boolean initialState = admin.isBalancerEnabled();
|
||||
|
||||
// Start the balancer, wait for it.
|
||||
boolean prevState = admin.setBalancerRunning(!initialState, true);
|
||||
|
||||
// The previous state should be the original state we observed
|
||||
assertEquals(initialState, prevState);
|
||||
|
||||
// Current state should be opposite of the original
|
||||
assertEquals(!initialState, admin.isBalancerEnabled());
|
||||
|
||||
// Reset it back to what it was
|
||||
prevState = admin.setBalancerRunning(initialState, true);
|
||||
|
||||
// The previous state should be the opposite of the initial state
|
||||
assertEquals(!initialState, prevState);
|
||||
// Current state should be the original state again
|
||||
assertEquals(initialState, admin.isBalancerEnabled());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -114,6 +114,13 @@ module Hbase
|
|||
java.lang.Boolean::valueOf(enableDisable), java.lang.Boolean::valueOf(false))
|
||||
end
|
||||
|
||||
#----------------------------------------------------------------------------------------------
|
||||
# Query the current state of the LoadBalancer.
|
||||
# Returns the balancer's state (true is enabled).
|
||||
def balancer_enabled?()
|
||||
@admin.isBalancerEnabled()
|
||||
end
|
||||
|
||||
#----------------------------------------------------------------------------------------------
|
||||
# Request a scan of the catalog table (for garbage collection)
|
||||
# Returns an int signifying the number of entries cleaned
|
||||
|
|
|
@ -313,6 +313,7 @@ Shell.load_command_group(
|
|||
assign
|
||||
balancer
|
||||
balance_switch
|
||||
balancer_enabled
|
||||
close_region
|
||||
compact
|
||||
flush
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
#!/usr/bin/env hbase-jruby
|
||||
#
|
||||
# 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.
|
||||
|
||||
# Prints the current balancer status
|
||||
|
||||
module Shell
|
||||
module Commands
|
||||
class BalancerEnabled < Command
|
||||
def help
|
||||
return <<-EOF
|
||||
Query the balancer's state.
|
||||
Examples:
|
||||
|
||||
hbase> balancer_enabled
|
||||
EOF
|
||||
end
|
||||
|
||||
def command()
|
||||
format_simple_command do
|
||||
formatter.row([
|
||||
admin.balancer_enabled?.to_s
|
||||
])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue