Usar o gRPC com a biblioteca de cliente Java

O cliente Java para o modo Datastore oferece o gRPC como uma opção de camada de transporte. Usar o pool de conexões gRPC permite distribuir RPCs por várias conexões, o que pode melhorar o desempenho.

Antes de começar

Instale a versão mais recente da biblioteca google-cloud-datastore.

Como ativar o comportamento de transporte do gRPC

Para ativar o comportamento de transporte gRPC, adicione setTransportOptions à instanciação do cliente:

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

Definir as opções de transporte explicitamente como GrpcTransportOptions configura o cliente para usar gRPC em vez de HTTP ao fazer chamadas para o servidor.

Desativar o comportamento de transporte do gRPC

É possível desativar o comportamento de transporte gRPC revertendo para o comportamento de transporte HTTP. Para fazer isso, remova a linha de código .setTransportOptions ou substitua GrpcTransportOptions por HttpTransportOptions. Você também precisa recriar e reiniciar o aplicativo.

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();

Verificar opções de transporte

Para verificar qual tipo de TransportOptions o cliente usa, examine o tipo de opções de transporte:

Java
// Compares datastore transport options type

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

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

Configuração do pool de conexões

Um pool de conexões, também conhecido como pool de canais, é um cache de conexões de banco de dados que o cliente compartilha e reutiliza para melhorar a latência e o desempenho da conexão. Para melhorar o desempenho do aplicativo, configure o pool de conexões.

Esta seção ajuda você a determinar o tamanho ideal do pool de conexões e demonstra como configurá-lo na biblioteca de cliente Java.

Determinar o melhor tamanho de pool de conexões

O tamanho padrão do pool de conexões é adequado para a maioria dos aplicativos e, na maioria dos casos, não é necessário mudá-lo. No entanto, talvez seja necessário mudar o tamanho do pool de conexões devido ao alto throughput ou a solicitações em buffer.

Para deixar espaço para flutuações de tráfego, o ideal é que um pool de conexões tenha por volta de duas vezes o número de conexões necessárias para a saturação máxima. Como uma conexão pode processar no máximo 100 solicitações simultâneas, recomendamos que você tenha entre 10 e 50 solicitações pendentes por conexão. A camada de middleware aplica o limite de 100 streams simultâneos por conexão do gRPC, e esse limite não é configurável. Para calcular o número ideal de conexões no seu pool de conexões usando um QPS estimado por cliente e números de latência média, faça o seguinte:

Com as métricas do lado do cliente, colete as seguintes informações e faça os cálculos abaixo:

  1. Determine o número máximo de consultas por segundo (QPS) por cliente quando o aplicativo executa uma carga de trabalho.
  2. Determine a latência média (o tempo de resposta para uma única solicitação) em ms.
  3. Determine o número de solicitações que podem ser enviadas em série por segundo dividindo 1.000 pelo valor médio da latência.
  4. Divida o QPS em segundos pelo número de solicitações seriais por segundo.
  5. Divida o resultado por 50 solicitações por canal para determinar o tamanho mínimo ideal do pool de conexões. Se o cálculo for menor que 2, use pelo menos dois canais mesmo assim, para garantir redundância.
  6. Divida o mesmo resultado por 10 solicitações por canal para determinar o tamanho máximo ideal do pool de conexões.

Para realizar essas etapas, use as seguintes equações:

(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

Por exemplo, se o aplicativo costuma enviar 50.000 solicitações por segundo e a latência média é de 10 ms, divida 1.000 por 10 ms para determinar que é possível enviar 100 solicitações em série por segundo. Divida esse número por 50.000 para chegar ao paralelismo necessário para enviar 50.000 QPS: 500.

Cada canal pode ter no máximo 100 solicitações simultâneas, e a utilização do seu canal de destino está entre 10 e 50 streams simultâneos. Portanto, para calcular o tamanho mínimo do pool de conexões, divida 500 por 50 para chegar a 10. Para encontrar o tamanho máximo do pool de conexões, divida 500 por 10 para chegar a 50.

Isso significa que o tamanho do pool de conexões para este exemplo está entre 10 e 50 conexões. Também é importante monitorar o tráfego depois de fazer essas mudanças e ajustar o número de conexões no pool, conforme necessário.

Definir o tamanho do pool

O exemplo de código a seguir demonstra como configurar o pool de conexões nas bibliotecas de cliente usando 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();

A seguir

Para mais informações sobre pools de conexões e práticas recomendadas de desempenho, consulte: