Skip to content

Commit

Permalink
[PLAT-14787] Implement a master tablet lb api for YW
Browse files Browse the repository at this point in the history
Summary:
An API that returns if the master tablet load balancer is disabled, enabled & idle or enabled & running. If running, an estimate of the time to go back to idle is provided if it is possible to get such an estimate.

```
$ '/usr/bin/curl' '-s' '--insecure' '-H' 'X-AUTH-TOKEN: xxxxx' '-X' 'GET' 'http://localhost:9000/api/v1/customers/f33e3c9b-75ab-4c30-80ad-cba85646ea39/universes/180f069f-adf3-49b9-86ab-7a4fb4bc5d3e/master_lb_state'

{"isEnabled":false}
{"isEnabled":true, "isIdle": true}
{"isEnabled":true, "isIdle": false, "estTimeToBalanceSecs":987}

```

Also added the relevant metrics used here on the metrics page.

Test Plan:
1. Turn off the master lb with `tserver/bin/yb-admin --init_master_addrs=10.9.207.233 set_load_balancer_enabled 0`, verify the response is
```
{"isEnabled":false}
```

2. Turn back the master lb on with `tserver/bin/yb-admin --init_master_addrs=10.9.207.233 set_load_balancer_enabled 1`, verify the response is
```
{"isEnabled":true,"isIdle":true}
```

3. Verify lb progress is reflected correctly. Create some tables with lot of tablets

```
seq 1 10 | while read i; do
tserver/bin/ysqlsh -h /tmp/.yb.10.9.207.233\:5433/ -c "create table foo$i(id int) split into 150 tablets; insert into foo$i (select * from generate_series(1,1000));";
done
```

and slow down the master LB by setting master gflag `load_balancer_max_concurrent_moves to 1`. Then trigger the master lb by leader blacklisting one of the tservers `tserver/bin/yb-admin --init_master_addrs=10.9.207.233 change_leader_blacklist ADD 10.9.142.7`. Verify that the master LB is now running via
```
 tserver/bin/yb-admin --init_master_addrs=10.9.207.233 get_is_load_balancer_idle
Idle = 0
```
and that the API response matches this
```
{"isEnabled":true,"isIdle":false}
```
After all the moves are complete, verify that the response returns to
```
{"isEnabled":true,"isIdle":true}
```

Reviewers: cwang, yshchetinin

Reviewed By: cwang, yshchetinin

Subscribers: yugaware

Differential Revision: https://phorge.dev.yugabyte.com/D36164
  • Loading branch information
iSignal committed Aug 8, 2024
1 parent edd8e3f commit 4a2657e
Show file tree
Hide file tree
Showing 32 changed files with 743 additions and 166 deletions.
2 changes: 1 addition & 1 deletion java/interface-annotations/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
<parent>
<groupId>org.yb</groupId>
<artifactId>yb-parent</artifactId>
<version>0.8.92-SNAPSHOT</version>
<version>0.8.93-SNAPSHOT</version>
</parent>

<artifactId>interface-annotations</artifactId>
Expand Down
2 changes: 1 addition & 1 deletion java/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@

<groupId>org.yb</groupId>
<artifactId>yb-parent</artifactId>
<version>0.8.92-SNAPSHOT</version>
<version>0.8.93-SNAPSHOT</version>
<packaging>pom</packaging>

<name>Yugabyte</name>
Expand Down
2 changes: 1 addition & 1 deletion java/yb-cdc/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>org.yb</groupId>
<artifactId>yb-parent</artifactId>
<version>0.8.92-SNAPSHOT</version>
<version>0.8.93-SNAPSHOT</version>
</parent>
<artifactId>yb-cdc</artifactId>
<name>YB CDC Connector</name>
Expand Down
2 changes: 1 addition & 1 deletion java/yb-cli/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
<parent>
<groupId>org.yb</groupId>
<artifactId>yb-parent</artifactId>
<version>0.8.92-SNAPSHOT</version>
<version>0.8.93-SNAPSHOT</version>
</parent>

<artifactId>yb-cli</artifactId>
Expand Down
2 changes: 1 addition & 1 deletion java/yb-client/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
<parent>
<groupId>org.yb</groupId>
<artifactId>yb-parent</artifactId>
<version>0.8.92-SNAPSHOT</version>
<version>0.8.93-SNAPSHOT</version>
</parent>

<artifactId>yb-client</artifactId>
Expand Down
13 changes: 13 additions & 0 deletions java/yb-client/src/main/java/org/yb/client/AsyncYBClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -1059,6 +1059,19 @@ public Deferred<ChangeLoadBalancerStateResponse> changeLoadBalancerState(boolean
return sendRpcToTablet(rpc);
}

/**
* Get the load balancer state on master.
*
* @return a deferred object that yields the response to the config change.
*/
public Deferred<GetLoadBalancerStateResponse> getLoadBalancerState() {
checkIsClosed();
GetLoadBalancerStateRequest rpc =
new GetLoadBalancerStateRequest(this.masterTable);
rpc.setTimeoutMillis(defaultAdminOperationTimeoutMs);
return sendRpcToTablet(rpc);
}

/**
* Get the tablet load move completion percentage for blacklisted nodes.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// Copyright (c) YugaByte, Inc.
//
// Licensed 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.
//

package org.yb.client;

import com.google.protobuf.Message;
import io.netty.buffer.ByteBuf;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.yb.annotations.InterfaceAudience;
import org.yb.master.MasterClusterOuterClass;
import org.yb.master.MasterClusterOuterClass.GetLoadBalancerStateRequestPB;
import org.yb.util.Pair;

@InterfaceAudience.Public
public class GetLoadBalancerStateRequest extends YRpc<GetLoadBalancerStateResponse> {

public static final Logger LOG = LoggerFactory.getLogger(GetLoadBalancerStateRequest.class);

public GetLoadBalancerStateRequest(YBTable table) {
// The passed table will be a master table from AsyncYBClient since this service is registered
// on master.
super(table);
}

@Override
ByteBuf serialize(Message header) {
assert header.isInitialized();
final GetLoadBalancerStateRequestPB.Builder builder =
GetLoadBalancerStateRequestPB.newBuilder();
return toChannelBuffer(header, builder.build());
}

@Override
String serviceName() {
return MASTER_SERVICE_NAME;
}

@Override
String method() {
return "GetLoadBalancerState";
}

@Override
Pair<GetLoadBalancerStateResponse, Object> deserialize(CallResponse callResponse, String uuid)
throws Exception {
final MasterClusterOuterClass.GetLoadBalancerStateResponsePB.Builder respBuilder =
MasterClusterOuterClass.GetLoadBalancerStateResponsePB.newBuilder();
readProtobuf(callResponse.getPBMessage(), respBuilder);

GetLoadBalancerStateResponse response =
new GetLoadBalancerStateResponse(
deadlineTracker.getElapsedMillis(), uuid, respBuilder.build());
return new Pair<GetLoadBalancerStateResponse, Object>(
response, respBuilder.hasError() ? respBuilder.getError() : null);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Copyright (c) YugaByte, Inc.
//
// Licensed 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.
//

package org.yb.client;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.yb.annotations.InterfaceAudience;
import org.yb.master.MasterClusterOuterClass.GetLoadBalancerStateResponsePB;
import org.yb.master.MasterTypes.MasterErrorPB;

@InterfaceAudience.Public
public class GetLoadBalancerStateResponse extends YRpcResponse {

public static final Logger LOG = LoggerFactory.getLogger(GetLoadBalancerStateResponse.class);

private GetLoadBalancerStateResponsePB masterLBState;

public GetLoadBalancerStateResponse(
long elapsedMillis, String uuid, GetLoadBalancerStateResponsePB response) {
super(elapsedMillis, uuid);
this.masterLBState = response;
}

public MasterErrorPB getServerError() {
return masterLBState.getError();
}

public boolean hasError() {
return masterLBState.hasError();
}

public String errorMessage() {
return masterLBState.hasError() ? masterLBState.getError().getStatus().getMessage() : null;
}

public boolean hasIsEnabled() {
return masterLBState.hasIsEnabled();
}

public boolean isEnabled() {
return masterLBState.getIsEnabled();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ ByteBuf serialize(Message header) {
assert header.isInitialized();
final MasterClusterOuterClass.IsLoadBalancedRequestPB.Builder builder =
MasterClusterOuterClass.IsLoadBalancedRequestPB.newBuilder();
builder.setExpectedNumServers(expectedServers);
if (expectedServers != 0) {
builder.setExpectedNumServers(expectedServers);
}
return toChannelBuffer(header, builder.build());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ public IsLoadBalancerIdleResponse(long ellapsedMillis,
serverError = error;
}

public MasterTypes.MasterErrorPB getError() {
return serverError;
}

public boolean hasError() {
return serverError != null;
}
Expand Down
11 changes: 11 additions & 0 deletions java/yb-client/src/main/java/org/yb/client/YBClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,17 @@ public ChangeLoadBalancerStateResponse changeLoadBalancerState(boolean isEnable)
return d.join(getDefaultAdminOperationTimeoutMs());
}

/**
* Get the load balancer state.
*
* @return the response of the operation.
*/
public GetLoadBalancerStateResponse getLoadBalancerState()
throws Exception {
Deferred<GetLoadBalancerStateResponse> d = asyncClient.getLoadBalancerState();
return d.join(getDefaultAdminOperationTimeoutMs());
}

/**
* Get the tablet load move completion percentage for blacklisted nodes, if any.
*
Expand Down
2 changes: 1 addition & 1 deletion java/yb-cql-4x/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<parent>
<groupId>org.yb</groupId>
<artifactId>yb-parent</artifactId>
<version>0.8.92-SNAPSHOT</version>
<version>0.8.93-SNAPSHOT</version>
</parent>
<artifactId>yb-cql-4x</artifactId>
<name>YB CQL Support for 4.x Driver</name>
Expand Down
2 changes: 1 addition & 1 deletion java/yb-cql/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<parent>
<groupId>org.yb</groupId>
<artifactId>yb-parent</artifactId>
<version>0.8.92-SNAPSHOT</version>
<version>0.8.93-SNAPSHOT</version>
</parent>
<artifactId>yb-cql</artifactId>
<name>YB CQL Support</name>
Expand Down
2 changes: 1 addition & 1 deletion java/yb-jedis-tests/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<parent>
<groupId>org.yb</groupId>
<artifactId>yb-parent</artifactId>
<version>0.8.92-SNAPSHOT</version>
<version>0.8.93-SNAPSHOT</version>
</parent>
<artifactId>yb-jedis-tests</artifactId>
<name>YB Jedis Tests</name>
Expand Down
2 changes: 1 addition & 1 deletion java/yb-loadtester/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<parent>
<groupId>org.yb</groupId>
<artifactId>yb-parent</artifactId>
<version>0.8.92-SNAPSHOT</version>
<version>0.8.93-SNAPSHOT</version>
</parent>

<artifactId>yb-loadtester</artifactId>
Expand Down
2 changes: 1 addition & 1 deletion java/yb-multiapi/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<parent>
<groupId>org.yb</groupId>
<artifactId>yb-parent</artifactId>
<version>0.8.92-SNAPSHOT</version>
<version>0.8.93-SNAPSHOT</version>
</parent>

<artifactId>yb-multiapi</artifactId>
Expand Down
2 changes: 1 addition & 1 deletion java/yb-pgsql/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<parent>
<groupId>org.yb</groupId>
<artifactId>yb-parent</artifactId>
<version>0.8.92-SNAPSHOT</version>
<version>0.8.93-SNAPSHOT</version>
</parent>
<artifactId>yb-pgsql</artifactId>
<name>YB PostgreSQL Support</name>
Expand Down
2 changes: 1 addition & 1 deletion java/yb-sample/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<parent>
<groupId>org.yb</groupId>
<artifactId>yb-parent</artifactId>
<version>0.8.92-SNAPSHOT</version>
<version>0.8.93-SNAPSHOT</version>
</parent>
<artifactId>yb-sample</artifactId>
<name>YB Manual Support</name>
Expand Down
2 changes: 1 addition & 1 deletion java/yb-ysql-conn-mgr/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
<parent>
<groupId>org.yb</groupId>
<artifactId>yb-parent</artifactId>
<version>0.8.92-SNAPSHOT</version>
<version>0.8.93-SNAPSHOT</version>
</parent>
<artifactId>yb-ysql-conn-mgr</artifactId>
<name>Ysql Connection Manager Tests</name>
Expand Down
2 changes: 1 addition & 1 deletion java/yb-yugabyted/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<parent>
<groupId>org.yb</groupId>
<artifactId>yb-parent</artifactId>
<version>0.8.92-SNAPSHOT</version>
<version>0.8.93-SNAPSHOT</version>
</parent>
<artifactId>yb-yugabyted</artifactId>

Expand Down
2 changes: 1 addition & 1 deletion managed/build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -926,7 +926,7 @@ runPlatform := {
Project.extract(newState).runTask(runPlatformTask, newState)
}

libraryDependencies += "org.yb" % "yb-client" % "0.8.92-SNAPSHOT"
libraryDependencies += "org.yb" % "yb-client" % "0.8.93-SNAPSHOT"
libraryDependencies += "org.yb" % "ybc-client" % "2.2.0.0-b3"
libraryDependencies += "org.yb" % "yb-perf-advisor" % "1.0.0-b33"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
import com.yugabyte.yw.common.rbac.PermissionInfo.Action;
import com.yugabyte.yw.common.rbac.PermissionInfo.ResourceType;
import com.yugabyte.yw.common.services.YBClientService;
import com.yugabyte.yw.controllers.apiModels.MasterLBStateResponse;
import com.yugabyte.yw.controllers.handlers.MetaMasterHandler;
import com.yugabyte.yw.forms.PlatformResults;
import com.yugabyte.yw.models.Customer;
import com.yugabyte.yw.models.Universe;
Expand Down Expand Up @@ -42,6 +44,8 @@ public class MetaMasterController extends Controller {

@Inject KubernetesManagerFactory kubernetesManagerFactory;

@Inject MetaMasterHandler metaMasterHandler;

@ApiOperation(
value = "List a universe's master nodes",
response = MastersList.class,
Expand Down Expand Up @@ -78,6 +82,22 @@ public Result getMasterAddresses(UUID customerUUID, UUID universeUUID) {
return getServerAddresses(customerUUID, universeUUID, ServerType.MASTER);
}

@ApiOperation(
notes = "Available since YBA version 2024.2.0",
value = "Get the state of master load balancing ops",
response = MasterLBStateResponse.class)
@YbaApi(visibility = YbaApi.YbaApiVisibility.INTERNAL, sinceYBAVersion = "2024.2.0")
@AuthzPath({
@RequiredPermissionOnResource(
requiredPermission =
@PermissionAttribute(resourceType = ResourceType.UNIVERSE, action = Action.READ),
resourceLocation = @Resource(path = Util.UNIVERSES, sourceType = SourceType.ENDPOINT))
})
public Result getMasterLBState(UUID customerUUID, UUID universeUUID) {
MasterLBStateResponse resp = metaMasterHandler.getMasterLBState(customerUUID, universeUUID);
return PlatformResults.withData(resp);
}

@ApiOperation(
notes = "Available since YBA version 2.2.0.0.",
value = "List a YQL server's addresses",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Copyright 2024 YugaByte, Inc. and Contributors
*
* Licensed under the Polyform Free Trial License 1.0.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://github.com/YugaByte/yugabyte-db/blob/master/licenses/POLYFORM-FREE-TRIAL-LICENSE-1.0.0.txt
*/
package com.yugabyte.yw.controllers.apiModels;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;

@ApiModel(description = "Master tablet load balancer status")
public class MasterLBStateResponse {
@ApiModelProperty(
required = true,
value = "YbaApi Internal Whether master tablet load balancer is enabled")
public Boolean isEnabled;

@ApiModelProperty(
required = false,
value = "YbaApi Internal Whether master tablet load balancer is inactive")
public Boolean isIdle;

@ApiModelProperty(
required = false,
value =
"YbaApi Internal Estimate of time for which master tablet load balancer will be active")
public Long estTimeToBalanceSecs;
}
Loading

0 comments on commit 4a2657e

Please sign in to comment.