Skip to content

Commit 26fe0f9

Browse files
authored
feat(datastore): Update default channel pool configs to handle initial bursts and scalability (#12883)
Changes: - Update the initial channel count in the channel pool config to be 5 (was 1) - Set the max RPCs per channel to be 100 (was `Integer.MAX_VALUE`) - Increase the channel pool resize delta to 5 (was 2) - Fix the datastore options to be properly plumbed through the settings This will set the initial allowed QPS to be 500 instead of 100. This should allow for Datastore to better handle an initial burst of requests and scale quicker if needed. Since the delta also applies to downsizing, channel count will shrink as needed if there is low QPS so memory can be freed.
1 parent 4568284 commit 26fe0f9

3 files changed

Lines changed: 34 additions & 31 deletions

File tree

java-datastore/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreOptions.java

Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@
1818

1919
import static com.google.cloud.datastore.Validator.validateNamespace;
2020

21-
import com.google.api.core.ApiFunction;
2221
import com.google.api.core.BetaApi;
22+
import com.google.api.core.ObsoleteApi;
2323
import com.google.api.gax.grpc.ChannelPoolSettings;
2424
import com.google.api.gax.grpc.InstantiatingGrpcChannelProvider;
2525
import com.google.api.gax.rpc.TransportChannelProvider;
@@ -37,7 +37,6 @@
3737
import com.google.cloud.http.HttpTransportOptions;
3838
import com.google.common.base.MoreObjects;
3939
import com.google.common.collect.ImmutableSet;
40-
import io.grpc.ManagedChannelBuilder;
4140
import java.io.IOException;
4241
import java.lang.reflect.Method;
4342
import java.util.Objects;
@@ -54,9 +53,18 @@ public class DatastoreOptions extends ServiceOptions<Datastore, DatastoreOptions
5453
private static final String DEFAULT_DATABASE_ID = "";
5554
public static final String PROJECT_ID_ENV_VAR = "DATASTORE_PROJECT_ID";
5655
public static final String LOCAL_HOST_ENV_VAR = "DATASTORE_EMULATOR_HOST";
57-
public static final int INIT_CHANNEL_COUNT = 1;
56+
public static final int INIT_CHANNEL_COUNT = 5;
57+
static final int CHANNEL_POOL_DEFAULT_RESIZE_DELTA = 5;
58+
// Configure this default to be 100 to match the typical default `MAX_CONCURRENT_STREAMS`.
59+
// Larger values *may* experience possible client-side queueing as excess streams cannot be
60+
// multiplexed onto a full Http2 connection.
61+
static final int CHANNEL_POOL_MAX_RPCS_PER_CHANNEL = 100;
5862
public static final int MIN_CHANNEL_COUNT = 1;
59-
public static final int MAX_CHANNEL_COUNT = 4;
63+
64+
// This is a default max channel constant value set to handle the default initial channel
65+
// count and resize delta.
66+
@ObsoleteApi("This constant is obsolete and will be removed in a future version")
67+
public static final int MAX_CHANNEL_COUNT = 10;
6068

6169
private transient TransportChannelProvider channelProvider = null;
6270

@@ -233,33 +241,29 @@ private DatastoreOptions(Builder builder) {
233241
"Only gRPC transport allows setting of channel provider or credentials provider");
234242
} else if (getTransportOptions() instanceof GrpcTransportOptions) {
235243
if (builder.channelProvider == null) {
236-
/*
237-
The default gRPC connection pool is configured with a minimum of 1 channel.
238-
The maximum channel count automatically defaults to 200 (Defined in gax-grpc).
239-
*/
244+
// Set the default gRPC connection pool to be configured with a minimum of 1 channel.
245+
// The maximum channel count automatically defaults to 200 (as defined in gax-grpc).
246+
// Datastore sets the initial channel pool count to be 5 channels to allow better handle
247+
// large loads of requests and the resize delta to be 5 to scale quicker. In cases of low
248+
// load, the channel count will scale down as needed and memory will be freed. The default
249+
// configuration is set to try and handle ~500 QPS and will scale up and down as needed.
240250
ChannelPoolSettings datastoreChannelPoolSettings =
241251
ChannelPoolSettings.builder()
242252
.setInitialChannelCount(INIT_CHANNEL_COUNT)
243253
.setMinChannelCount(MIN_CHANNEL_COUNT)
254+
.setMaxRpcsPerChannel(CHANNEL_POOL_MAX_RPCS_PER_CHANNEL)
255+
.setMaxResizeDelta(CHANNEL_POOL_DEFAULT_RESIZE_DELTA)
244256
.build();
245257

246-
ApiFunction<ManagedChannelBuilder, ManagedChannelBuilder> channelConfigurator =
247-
this.traceUtil.getChannelConfigurator();
248-
if (channelConfigurator == null) {
249-
this.channelProvider =
250-
GrpcTransportOptions.setUpChannelProvider(
251-
DatastoreSettings.defaultGrpcTransportProviderBuilder()
252-
.setChannelPoolSettings(datastoreChannelPoolSettings),
253-
this);
254-
} else {
258+
InstantiatingGrpcChannelProvider.Builder channelProviderBuilder =
259+
DatastoreSettings.defaultGrpcTransportProviderBuilder()
260+
.setChannelPoolSettings(datastoreChannelPoolSettings)
261+
.setEndpoint(getHost());
262+
if (traceUtil.getChannelConfigurator() != null) {
255263
// Intercept the grpc channel calls to add telemetry info.
256-
this.channelProvider =
257-
GrpcTransportOptions.setUpChannelProvider(
258-
DatastoreSettings.defaultGrpcTransportProviderBuilder()
259-
.setChannelPoolSettings(datastoreChannelPoolSettings)
260-
.setChannelConfigurator(channelConfigurator),
261-
this);
264+
channelProviderBuilder.setChannelConfigurator(traceUtil.getChannelConfigurator());
262265
}
266+
this.channelProvider = channelProviderBuilder.build();
263267
} else {
264268
this.channelProvider = builder.channelProvider;
265269
}

java-datastore/google-cloud-datastore/src/main/java/com/google/cloud/datastore/spi/v1/GrpcDatastoreRpc.java

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
import com.google.api.core.InternalApi;
2525
import com.google.api.gax.core.BackgroundResource;
2626
import com.google.api.gax.core.GaxProperties;
27-
import com.google.api.gax.grpc.ChannelPoolSettings;
2827
import com.google.api.gax.grpc.GrpcCallContext;
2928
import com.google.api.gax.grpc.GrpcTransportChannel;
3029
import com.google.api.gax.rpc.ClientContext;
@@ -80,14 +79,11 @@ public GrpcDatastoreRpc(DatastoreOptions datastoreOptions) throws IOException {
8079
DatastoreStubSettings.newBuilder(clientContext)
8180
.applyToAllUnaryMethods(retrySettingSetter(datastoreOptions));
8281
if (!isEmulator(datastoreOptions)) {
82+
// Use the TransportChannelProvider configured in DatastoreOptions. For gRPC transport, this
83+
// will
84+
// be configured with a default ChannelPool configuration
8385
datastoreStubSettingsBuilder.setTransportChannelProvider(
84-
DatastoreSettings.defaultGrpcTransportProviderBuilder()
85-
.setChannelPoolSettings(
86-
ChannelPoolSettings.builder()
87-
.setInitialChannelCount(DatastoreOptions.INIT_CHANNEL_COUNT)
88-
.setMinChannelCount(DatastoreOptions.MIN_CHANNEL_COUNT)
89-
.build())
90-
.build());
86+
datastoreOptions.getTransportChannelProvider());
9187
}
9288

9389
datastoreStub = GrpcDatastoreStub.create(datastoreStubSettingsBuilder.build());

java-datastore/google-cloud-datastore/src/test/java/com/google/cloud/datastore/DatastoreOptionsTest.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,9 @@ public void testGrpcDefaultChannelConfigurations() {
187187
assertEquals(channelPoolSettings.getInitialChannelCount(), DatastoreOptions.INIT_CHANNEL_COUNT);
188188
assertEquals(channelPoolSettings.getMinChannelCount(), DatastoreOptions.MIN_CHANNEL_COUNT);
189189
assertEquals(channelPoolSettings.getMaxChannelCount(), DEFAULT_MAX_CHANNEL_COUNT);
190+
assertEquals(
191+
channelPoolSettings.getMaxRpcsPerChannel(),
192+
DatastoreOptions.CHANNEL_POOL_MAX_RPCS_PER_CHANNEL);
190193
}
191194

192195
@Test

0 commit comments

Comments
 (0)