Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: cluster autoscaling #1092

Merged
merged 13 commits into from Dec 7, 2021
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -24,13 +24,15 @@
import com.google.bigtable.admin.v2.DeleteAppProfileRequest;
import com.google.bigtable.admin.v2.GetAppProfileRequest;
import com.google.bigtable.admin.v2.ListAppProfilesRequest;
import com.google.bigtable.admin.v2.PartialUpdateClusterRequest;
import com.google.cloud.Policy;
import com.google.cloud.Policy.DefaultMarshaller;
import com.google.cloud.bigtable.admin.v2.BaseBigtableInstanceAdminClient.ListAppProfilesPage;
import com.google.cloud.bigtable.admin.v2.BaseBigtableInstanceAdminClient.ListAppProfilesPagedResponse;
import com.google.cloud.bigtable.admin.v2.internal.NameUtil;
import com.google.cloud.bigtable.admin.v2.models.AppProfile;
import com.google.cloud.bigtable.admin.v2.models.Cluster;
import com.google.cloud.bigtable.admin.v2.models.ClusterAutoscalingConfig;
import com.google.cloud.bigtable.admin.v2.models.CreateAppProfileRequest;
import com.google.cloud.bigtable.admin.v2.models.CreateClusterRequest;
import com.google.cloud.bigtable.admin.v2.models.CreateInstanceRequest;
Expand All @@ -49,6 +51,7 @@
import com.google.iam.v1.TestIamPermissionsRequest;
import com.google.iam.v1.TestIamPermissionsResponse;
import com.google.protobuf.Empty;
import com.google.protobuf.util.FieldMaskUtil;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
Expand Down Expand Up @@ -660,8 +663,10 @@ public List<Cluster> apply(com.google.bigtable.admin.v2.ListClustersResponse pro
}

/**
* Modifies the cluster's node count. Please note that only clusters that belong to a production
* instance can be resized.
* Modifies the cluster's node count for manual scaling. If autoscaling is already enabled, manual
* scaling will be silently ignored. If you wish to disable autoscaling and enable manual scaling,
* please use {@link BigtableInstanceAdminClient#disableClusterAutoscaling(String, String, int)}
* instead. Please note that only clusters that belong to a production instance can be resized.
*
* <p>Sample code:
*
Expand All @@ -676,8 +681,11 @@ public Cluster resizeCluster(String instanceId, String clusterId, int numServeNo
}

/**
* Asynchronously modifies the cluster's node count. Please note that only clusters that belong to
* a production instance can be resized.
* Asynchronously modifies the cluster's node count for manual scaling. If autoscaling is already
* enabled, manual scaling will be silently ignored. If you wish to disable autoscaling and enable
* manual scaling, please use {@link BigtableInstanceAdminClient#disableClusterAutoscaling(String,
* String, int)} instead. Please note that only clusters that belong to a production instance can
* be resized.
*
* <pre>{@code
* ApiFuture<Cluster> clusterFuture = client.resizeCluster("my-instance", "my-cluster", 30);
Expand Down Expand Up @@ -707,6 +715,108 @@ public Cluster apply(com.google.bigtable.admin.v2.Cluster proto) {
MoreExecutors.directExecutor());
}

/**
* Modifies the cluster's autoscaling config. This will enable autoscaling and disable manual
* scaling if the cluster is manually scaled. Please note that only clusters that belong to a
* production instance can enable autoscaling.
*
* <p>Sample code:
*
* <pre>{@code
* ClusterAutoscalingConfig clusterAutoscalingConfig =
* ClusterAutoscalingConfig.of("my-instance", "my-cluster")
* .setMinNodes(1)
* .setMaxNodes(4)
* .setCpuUtilizationTargetPercent(40);
* Cluster cluster = client.updateClusterAutoscalingConfig(clusterAutoscalingConfig);
* }</pre>
*/
public Cluster updateClusterAutoscalingConfig(ClusterAutoscalingConfig clusterAutoscalingConfig) {
return ApiExceptions.callAndTranslateApiException(
updateClusterAutoscalingConfigAsync(clusterAutoscalingConfig));
}

/**
* Asynchronously modifies the cluster's autoscaling config. This will enable autoscaling and
* disable manual scaling if the cluster is manually scaled. Please note that only clusters that
* belong to a production instance can enable autoscaling.
*
* <p>Sample code:
*
* <pre>{@code
* ClusterAutoscalingConfig clusterAutoscalingConfig =
* ClusterAutoscalingConfig.of(targetInstanceId, targetClusterId)
* .setMinNodes(1)
* .setMaxNodes(4)
* .setCpuUtilizationTargetPercent(40);
*
* ApiFuture<Cluster> clusterApiFuture = client.updateClusterAutoscalingConfigAsync(clusterAutoscalingConfig);
* Cluster cluster = clusterApiFuture.get();
* }</pre>
*/
public ApiFuture<Cluster> updateClusterAutoscalingConfigAsync(
ClusterAutoscalingConfig clusterAutoscalingConfig) {
PartialUpdateClusterRequest proto = clusterAutoscalingConfig.toProto(projectId);

return ApiFutures.transform(
stub.partialUpdateClusterOperationCallable().futureCall(proto),
Cluster::fromProto,
MoreExecutors.directExecutor());
}

/**
* Disables autoscaling and enables manual scaling by setting a static node count for the cluster.
* Please note that only clusters that belong to a production instance can be resized.
*
* <p>Sample code:
*
* <pre>{@code
* Cluster cluster = client.disableClusterAutoscaling("my-instance", "my-cluster", 3);
* }</pre>
*/
public Cluster disableClusterAutoscaling(String instanceId, String clusterId, int staticSize) {
return ApiExceptions.callAndTranslateApiException(
disableClusterAutoscalingAsync(instanceId, clusterId, staticSize));
}

/**
* Asynchronously disables autoscaling and enables manual scaling by setting a static node count
* for the cluster. Please note that only clusters that belong to a production instance can be
* resized.
*
* <p>Sample code:
*
* <pre>{@code
* ApiFuture<Cluster> clusterApiFuture = client.disableClusterAutoscalingAsync("my-instance", "my-cluster", 3);
* Cluster cluster = clusterApiFuture.get();
* }</pre>
*/
public ApiFuture<Cluster> disableClusterAutoscalingAsync(
String instanceId, String clusterId, int staticSize) {
String name = NameUtil.formatClusterName(projectId, instanceId, clusterId);

com.google.bigtable.admin.v2.Cluster request =
com.google.bigtable.admin.v2.Cluster.newBuilder()
.setName(name)
.setServeNodes(staticSize)
.setClusterConfig(
com.google.bigtable.admin.v2.Cluster.ClusterConfig.getDefaultInstance())
.build();

PartialUpdateClusterRequest partialUpdateClusterRequest =
PartialUpdateClusterRequest.newBuilder()
.setUpdateMask(
FieldMaskUtil.fromStringList(
com.google.bigtable.admin.v2.Cluster.class,
Lists.newArrayList("cluster_config.cluster_autoscaling_config", "serve_nodes")))
.setCluster(request)
.build();
return ApiFutures.transform(
stub.partialUpdateClusterOperationCallable().futureCall(partialUpdateClusterRequest),
Cluster::fromProto,
MoreExecutors.directExecutor());
}

/**
* Deletes the specified cluster. Please note that an instance must have at least 1 cluster. To
* remove the last cluster, please use {@link BigtableInstanceAdminClient#deleteInstance(String)}.
Expand Down
Expand Up @@ -148,6 +148,36 @@ public int getServeNodes() {
return stateProto.getServeNodes();
}

/** Get the minimum number of nodes to scale down to. */
public int getAutoscalingMinServeNodes() {
return stateProto
.getClusterConfig()
.getClusterAutoscalingConfig()
.getAutoscalingLimits()
.getMinServeNodes();
}

/** Get the maximum number of nodes to scale up to. */
public int getAutoscalingMaxServeNodes() {
return stateProto
.getClusterConfig()
.getClusterAutoscalingConfig()
.getAutoscalingLimits()
.getMaxServeNodes();
}

/**
* Get the cpu utilization that the Autoscaler should be trying to achieve. This number is on a
* scale from 0 (no utilization) to 100 (total utilization).
*/
public int getAutoscalingCpuPercentageTarget() {
return stateProto
.getClusterConfig()
.getClusterAutoscalingConfig()
.getAutoscalingTargets()
.getCpuUtilizationPercent();
}

/**
* The type of storage used by this cluster to serve its parent instance's tables, unless
* explicitly overridden.
Expand Down