Java クライアント ライブラリで gRPC を使用する

Datastore モードの Java クライアントは、トランスポート レイヤ オプションとして gRPC を提供します。gRPC 接続プールを使用すると、複数の接続に RPC を分散できるため、パフォーマンスを向上させることができます。

始める前に

インストール: google-cloud-datastore ライブラリの最新バージョンをインストールします。

gRPC トランスポート動作を有効にする方法

gRPC トランスポートの動作を有効にするには、クライアントのインスタンス化に setTransportOptions を追加します。

Java
DatastoreOptions datastoreOptions =
       DatastoreOptions.newBuilder()
               .setProjectId("my-project")
               .setDatabaseId("my-database")
               .setTransportOptions(GrpcTransportOptions.newBuilder().build())
               .build();

トランスポート オプションを明示的に GrpcTransportOptions に設定すると、サーバーへの呼び出しを行う際に HTTP ではなく gRPC を使用するようにクライアントが構成されます。

gRPC トランスポートの動作を無効にする

HTTP トランスポート動作に戻すことで、gRPC トランスポート動作を無効にできます。これを行うには、.setTransportOptions のコード行を削除するか、GrpcTransportOptionsHttpTransportOptions に置き換えます。アプリケーションを再ビルドして再起動する必要もあります。

Java
// Use this code to deactivate the gRPC transport behavior
// by reverting to the HTTP transport behavior.
DatastoreOptions datastoreOptions = DatastoreOptions.newBuilder()
            .setProjectId("my-project")
            .setDatabaseId("my-database")
            .build();

// You can also use this code to revert to the HTTP transport behavior
DatastoreOptions datastoreOptions =
            DatastoreOptions.newBuilder()
                    .setProjectId("my-project")
                    .setDatabaseId("my-database")
                    .setTransportOptions(HttpTransportOptions.newBuilder()
                            .setConnectTimeout(1000)
                            .build())
                    .build();

転送オプションを確認する

クライアントが使用する TransportOptions のタイプを確認するには、トランスポート オプションのタイプを調べます。

Java
// Compares datastore transport options type

boolean isGRPC = datastore.getOptions().getTransportOptions() instanceof GrpcTransportOptions;

boolean isHTTP = datastore.getOptions().getTransportOptions() instanceof HTTPTransportOptions;

接続プールの構成

接続プール(チャネルプールとも呼ばれます)は、接続レイテンシとパフォーマンスを向上させるためにクライアントが共有して再利用するデータベース接続のキャッシュです。アプリケーションのパフォーマンスを向上させるには、接続プールを構成します。

このセクションでは、最適な接続プールサイズを決定する方法と、Java クライアント ライブラリ内で接続プールサイズを構成する方法について説明します。

最適な接続プールサイズを決定する

デフォルトの接続プールサイズはほとんどのアプリケーションに適しているため、ほとんどの場合、変更する必要はありません。ただし、スループットが高い場合やリクエストがバッファリングされている場合は、接続プールサイズを変更することをおすすめします。

理想としては、トラフィック変動のために余裕を持たせ、接続プールを最大の飽和状態に必要な接続数のおよそ 2 倍にします。接続は最大 100 件の同時リクエストを処理できるため、接続あたり 10 ~ 50 件のリクエストが最適です。ミドルウェア レイヤでは、gRPC 接続あたりの同時ストリーム数の上限は 100 に制限され、この上限を構成することはできません。接続プール内の最適な接続数を計算するには、クライアントごとの推定 QPS と平均レイテンシの数値を使用して、次の操作を行います。

クライアント側の指標から次の情報を収集し、次の計算を行います。

  1. アプリケーションがワークロードを実行しているときのクライアントごとの秒間クエリ数(QPS)の最大数を決定します。
  2. ミリ秒での平均レイテンシ(単一のリクエストのレスポンス時間)を特定します。
  3. 1,000 を平均レイテンシ値で割って、1 秒あたりに順次送信できるリクエスト数を確認します。
  4. 秒単位の QPS を 1 秒あたりの連続リクエスト数で割ります。
  5. その結果をチャネルあたり 50 リクエストで割り、最小の最適な接続プール サイズを決定します。(計算結果が 2 未満の場合は、冗長性を確保するために少なくとも 2 つのチャネルを使用してください)。
  6. 同じ結果をチャネルごとに 10 リクエストで割り、最大の最適な接続プールサイズを決定します。

これらの手順を行うには、次の式を使用します。

(QPS sec ÷ (1,000 ÷ latency ms)) ÷ 50 streams = Minimum optimal number of
connections

(QPS sec ÷ (1,000 ÷ latency ms)) ÷ 10 streams = Maximum optimal number of
connections

たとえば、アプリケーションが通常 1 秒あたり 50,000 件のリクエストを送信し、平均レイテンシが 10 ミリ秒の場合、1,000 を 10 ミリ秒で割って、1 秒あたり 100 件のリクエストを順次送信できることを確認します。その数を 50,000 で割り、50,000 QPS の送信に必要な並列処理(500)を取得します。

各チャネルで同時に送信できるリクエストは最大 100 件で、ターゲット チャネルの使用率は 10 ~ 50 件の同時ストリームです。したがって、最小接続プール サイズを計算するには、500 を 50 で割り、10 を取得します。最大接続プールサイズを確認するには、500 を 10 で割り、50 を取得します。

つまり、この例の接続プール サイズは 10 ~ 50 接続になります。また、これらの変更を行った後にトラフィックをモニタリングし、必要に応じてプール内の接続数を調整することも重要です。

プールサイズを設定する

次のコードサンプルは、DatastoreOptions を使用してクライアント ライブラリで接続プールを構成する方法を示しています。

Java
InstantiatingGrpcChannelProvider channelProvider =
        DatastoreSettings.defaultGrpcTransportProviderBuilder()
                .setChannelPoolSettings(
                       ChannelPoolSettings.builder()
                                .setInitialChannelCount(MIN_VAL)
                                .setMaxChannelCount(MAX_VAL)
                                .build())
                .build();

DatastoreOptions options = DatastoreOptions.newBuilder()
         .setProjectId("my-project")
         .setChannelProvider(channelProvider)
         .setTransportOptions(GrpcTransportOptions.newBuilder().build())
         .build();

次のステップ

接続プールとパフォーマンスに関するベスト プラクティスの詳細については、以下をご覧ください。