Skip to content

Commit 9a6544b

Browse files
committed
HBASE-26147: Add dry_run_balancer and related Admin interfaces for running the balancer without executing any region moves
1 parent dd22fec commit 9a6544b

File tree

14 files changed

+239
-6
lines changed

14 files changed

+239
-6
lines changed

hbase-client/src/main/java/org/apache/hadoop/hbase/client/Admin.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1253,6 +1253,15 @@ default boolean balancer() throws IOException {
12531253
*/
12541254
boolean balance() throws IOException;
12551255

1256+
/**
1257+
* Invoke the balancer in dry run mode. Will show plan but not actually move any regions.
1258+
* Can NOT run for various reasons. Check logs.
1259+
*
1260+
* @return <code>true</code> if dry run ran, <code>false</code> otherwise.
1261+
* @throws IOException if a remote or network exception occurs
1262+
*/
1263+
boolean dryRunBalance() throws IOException;
1264+
12561265
/**
12571266
* Invoke the balancer. Will run the balancer and if regions to move, it will
12581267
* go ahead and do the reassignments. If there is region in transition, force parameter of true

hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncAdmin.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import static org.apache.hadoop.hbase.util.FutureUtils.addListener;
2121

2222
import com.google.protobuf.RpcChannel;
23+
import java.io.IOException;
2324
import java.util.Arrays;
2425
import java.util.Collection;
2526
import java.util.EnumSet;
@@ -1270,6 +1271,14 @@ default CompletableFuture<Boolean> balance() {
12701271
*/
12711272
CompletableFuture<Boolean> balance(boolean forcible);
12721273

1274+
/**
1275+
* Invoke the balancer in dry run mode. Will show plan but not actually move any regions.
1276+
* Can NOT run for various reasons. Check logs.
1277+
*
1278+
* @return <code>true</code> if dry run ran, <code>false</code> otherwise.
1279+
*/
1280+
CompletableFuture<Boolean> dryRunBalance();
1281+
12731282
/**
12741283
* Query the current state of the balancer.
12751284
* @return true if the balance switch is on, false otherwise. The return value will be wrapped by a

hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncHBaseAdmin.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -688,6 +688,11 @@ public CompletableFuture<Boolean> balance(boolean forcible) {
688688
return wrap(rawAdmin.balance(forcible));
689689
}
690690

691+
@Override
692+
public CompletableFuture<Boolean> dryRunBalance() {
693+
return wrap(rawAdmin.dryRunBalance());
694+
}
695+
691696
@Override
692697
public CompletableFuture<Boolean> isBalancerEnabled() {
693698
return wrap(rawAdmin.isBalancerEnabled());

hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionImplementation.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1488,6 +1488,12 @@ public MasterProtos.BalanceResponse balance(RpcController controller,
14881488
return stub.balance(controller, request);
14891489
}
14901490

1491+
@Override
1492+
public MasterProtos.BalanceResponse dryRunBalance(RpcController controller,
1493+
MasterProtos.BalanceRequest request) throws ServiceException {
1494+
return stub.dryRunBalance(controller, request);
1495+
}
1496+
14911497
@Override
14921498
public MasterProtos.SetBalancerRunningResponse setBalancerRunning(
14931499
RpcController controller, MasterProtos.SetBalancerRunningRequest request)

hbase-client/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1498,6 +1498,17 @@ protected Boolean rpcCall() throws Exception {
14981498
});
14991499
}
15001500

1501+
@Override
1502+
public boolean dryRunBalance() throws IOException {
1503+
return executeCallable(new MasterCallable<Boolean>(getConnection(), getRpcControllerFactory()) {
1504+
@Override
1505+
protected Boolean rpcCall() throws Exception {
1506+
return master.dryRunBalance(getRpcController(),
1507+
RequestConverter.buildBalanceRequest(false)).getBalancerRan();
1508+
}
1509+
});
1510+
}
1511+
15011512
@Override
15021513
public boolean isBalancerEnabled() throws IOException {
15031514
return executeCallable(new MasterCallable<Boolean>(getConnection(), getRpcControllerFactory()) {

hbase-client/src/main/java/org/apache/hadoop/hbase/client/RawAsyncHBaseAdmin.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3219,6 +3219,16 @@ public CompletableFuture<Boolean> balance(boolean forcible) {
32193219
(s, c, req, done) -> s.balance(c, req, done), (resp) -> resp.getBalancerRan())).call();
32203220
}
32213221

3222+
@Override
3223+
public CompletableFuture<Boolean> dryRunBalance() {
3224+
return this
3225+
.<Boolean> newMasterCaller()
3226+
.action(
3227+
(controller, stub) -> this.<BalanceRequest, BalanceResponse, Boolean> call(controller,
3228+
stub, RequestConverter.buildBalanceRequest(false),
3229+
(s, c, req, done) -> s.dryRunBalance(c, req, done), (resp) -> resp.getBalancerRan())).call();
3230+
}
3231+
32223232
@Override
32233233
public CompletableFuture<Boolean> isBalancerEnabled() {
32243234
return this

hbase-client/src/main/java/org/apache/hadoop/hbase/client/ShortCircuitMasterConnection.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -599,6 +599,12 @@ public BalanceResponse balance(RpcController controller, BalanceRequest request)
599599
return stub.balance(controller, request);
600600
}
601601

602+
@Override
603+
public BalanceResponse dryRunBalance(RpcController controller, BalanceRequest request)
604+
throws ServiceException {
605+
return stub.dryRunBalance(controller, request);
606+
}
607+
602608
@Override
603609
public AssignRegionResponse assignRegion(RpcController controller, AssignRegionRequest request)
604610
throws ServiceException {

hbase-protocol-shaded/src/main/protobuf/Master.proto

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -841,6 +841,14 @@ service MasterService {
841841
rpc Balance(BalanceRequest)
842842
returns(BalanceResponse);
843843

844+
/**
845+
* Execute a dry-run of the balancer. This executes the balancer along with all
846+
* logging but does not actually move any regions. This is useful for debugging
847+
* balancer changes. Can NOT run for various reasons. Check logs.
848+
*/
849+
rpc DryRunBalance(BalanceRequest)
850+
returns (BalanceResponse);
851+
844852
/**
845853
* Turn the load balancer on or off.
846854
* If synchronous is true, it waits until current balance() call, if outstanding, to return.

hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1724,7 +1724,7 @@ private void balanceThrottling(long nextBalanceStartTime, int maxRegionsInTransi
17241724
}
17251725

17261726
public boolean balance() throws IOException {
1727-
return balance(false);
1727+
return balance(LoadBalancer.RunMode.NORMAL);
17281728
}
17291729

17301730
/**
@@ -1750,8 +1750,8 @@ public boolean skipRegionManagementAction(final String action) {
17501750
return false;
17511751
}
17521752

1753-
public boolean balance(boolean force) throws IOException {
1754-
if (loadBalancerTracker == null || !loadBalancerTracker.isBalancerOn()) {
1753+
public boolean balance(LoadBalancer.RunMode runMode) throws IOException {
1754+
if (loadBalancerTracker == null || (!loadBalancerTracker.isBalancerOn() && !runMode.isDryRun())) {
17551755
return false;
17561756
}
17571757
if (skipRegionManagementAction("balancer")) {
@@ -1772,8 +1772,8 @@ public boolean balance(boolean force) throws IOException {
17721772
toPrint = regionsInTransition.subList(0, max);
17731773
truncated = true;
17741774
}
1775-
if (!force || metaInTransition) {
1776-
LOG.info("Not running balancer (force=" + force + ", metaRIT=" + metaInTransition +
1775+
if (!runMode.isForced() || metaInTransition) {
1776+
LOG.info("Not running balancer (force=" + runMode.isForced() + ", metaRIT=" + metaInTransition +
17771777
") because " + regionsInTransition.size() + " region(s) in transition: " + toPrint +
17781778
(truncated? "(truncated list)": ""));
17791779
return false;
@@ -1809,6 +1809,10 @@ public boolean balance(boolean force) throws IOException {
18091809

18101810
List<RegionPlan> plans = this.balancer.balanceCluster(assignments);
18111811

1812+
if (runMode.isDryRun()) {
1813+
return true;
1814+
}
1815+
18121816
if (skipRegionManagementAction("balancer")) {
18131817
// make one last check that the cluster isn't shutting down before proceeding.
18141818
return false;

hbase-server/src/main/java/org/apache/hadoop/hbase/master/LoadBalancer.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,18 @@ public interface LoadBalancer extends Stoppable, ConfigurationObserver {
8686
// We deliberately use 'localhost' so the operation will fail fast
8787
ServerName BOGUS_SERVER_NAME = ServerName.valueOf("localhost,1,1");
8888

89+
enum RunMode {
90+
NORMAL, FORCE, DRY_RUN;
91+
92+
boolean isForced() {
93+
return this == FORCE;
94+
}
95+
96+
boolean isDryRun() {
97+
return this == DRY_RUN;
98+
}
99+
}
100+
89101
/**
90102
* Set the current cluster status. This allows a LoadBalancer to map host name to a server
91103
*/

0 commit comments

Comments
 (0)