Configure conjuntos de ligações

Algumas bibliotecas cliente do Cloud Bigtable permitem-lhe configurar o número de canais gRPC no conjunto de ligações de um cliente, também conhecido como conjunto de canais. Na maioria dos casos, a configuração predefinida está correta e não é necessário alterá-la.

Os conjuntos de ligações são redimensionados automaticamente conforme necessário quando usa a biblioteca de cliente do Cloud Bigtable para Java versão 2.23.0 ou posterior e quando usa o cliente HBase do Cloud Bigtable para Java versão 2.9.1 ou posterior.

Esta página descreve como determinar o tamanho ideal do conjunto de ligações para a sua aplicação e apresenta fragmentos de código que mostram como configurar os conjuntos de ligações.

Antes de ler esta página, leia a vista geral dos conjuntos de ligações do Bigtable para saber como funcionam e se deve alterar os seus.

As seguintes bibliotecas cliente oferecem o agrupamento de ligações e permitem-lhe configurar o número de agrupamentos:

Determine o melhor tamanho do conjunto de ligações

Idealmente, para deixar espaço para flutuações de tráfego, um conjunto de ligações tem cerca do dobro do número de ligações necessárias para a saturação máxima. Uma vez que uma ligação pode processar um máximo de 100 pedidos simultâneos, o ideal é ter entre 10 e 50 pedidos pendentes por ligação. Este conceito é descrito com mais detalhe em Pools de ligações.

Monitorize o tráfego após fazer alterações e ajuste o número de ligações no seu conjunto, se necessário.

Os passos seguintes ajudam a calcular o número ideal de ligações no conjunto de canais através de métricas do lado do cliente, como as disponíveis no OpenCensus.

  1. A partir das métricas do lado do cliente, recolha as seguintes informações:
    1. O número máximo de consultas por segundo (CPS) por cliente quando a sua aplicação está a executar uma carga de trabalho típica.
    2. A latência média (o tempo de resposta para um único pedido) em ms.
  2. Determine o número de pedidos que pode enviar em série por segundo dividindo 1000 pelo valor de latência médio.
  3. Divida o CPS em segundos pelo número de pedidos em série por segundo.
  4. Divida o resultado por 50 pedidos por canal para determinar o tamanho mínimo ideal do conjunto de canais. (Se o cálculo for inferior a 2, use, mesmo assim, pelo menos 2 canais para garantir a redundância.)
  5. Divida o mesmo resultado por 10 pedidos por canal para determinar o tamanho máximo ideal do conjunto de canais.

Estes passos são expressos nas seguintes equações:

  • (QPS por segundo ÷ (1000 ÷ latência em ms)) ÷ 50 streams = Número mínimo ideal de ligações

  • (QPS por segundo ÷ (1000 ÷ latência em ms)) ÷ 10 streams = Número máximo ideal de ligações

Exemplo

A sua aplicação envia normalmente 50 000 pedidos por segundo e a latência média é de 10 ms. Divida 1000 por 10 ms para determinar que pode enviar 100 pedidos em série por segundo. Divida esse número por 50 000 para obter o paralelismo necessário para enviar 50 000 QPS: 500. Cada canal pode ter, no máximo, 100 pedidos em simultâneo, e a utilização do canal de destino está entre 10 e 50 streams em simultâneo. Por conseguinte, para calcular o mínimo, divida 500 por 50 para obter 10. Para encontrar o máximo, divida 500 por 10 para obter 50. Isto significa que, para este exemplo, o tamanho do conjunto de canais deve estar entre 10 e 50 ligações.

Defina o tamanho do conjunto

Os seguintes exemplos de código demonstram como configurar o número de conjuntos nas bibliotecas de cliente que lhe permitem definir o tamanho do conjunto.

Go

import (
	"context"
	"fmt"
	"io"

	"cloud.google.com/go/bigtable"
	"google.golang.org/api/option"
)

func configureConnectionPool(w io.Writer, projectID, instanceID string) error {
	// projectID := "my-project-id"
	// instanceID := "my-instance-id"
	ctx := context.Background()

	// Set up Bigtable data operations client.
	poolSize := 10
	client, err := bigtable.NewClient(ctx, projectID, instanceID, option.WithGRPCConnectionPool(poolSize))
	defer client.Close()

	if err != nil {
		return fmt.Errorf("bigtable.NewClient: %w", err)
	}

	fmt.Fprintf(w, "Connected with pool size of %d", poolSize)

	return nil
}

HBase

Este exemplo aplica-se apenas a versões da biblioteca de cliente anteriores a 2.9.1, quando foi introduzido o redimensionamento automático.



import static com.google.cloud.bigtable.hbase.BigtableOptionsFactory.BIGTABLE_DATA_CHANNEL_COUNT_KEY;

import com.google.cloud.bigtable.hbase.BigtableConfiguration;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.client.Connection;

public class ConfigureConnectionPool {

  public static void configureConnectionPool(String projectId, String instanceId) {
    // String projectId = "my-project-id";
    // String instanceId = "my-instance-id";
    Configuration config = BigtableConfiguration.configure(projectId, instanceId);
    config.setInt(BIGTABLE_DATA_CHANNEL_COUNT_KEY, 10);
    try (Connection connection = BigtableConfiguration.connect(config)) {
      int poolSize = connection.getConfiguration().getInt(BIGTABLE_DATA_CHANNEL_COUNT_KEY, 0);

      System.out.println(String.format("Connected with pool size of %d", poolSize));
    } catch (Exception e) {
      System.out.println("Error during ConfigureConnectionPool: \n" + e.toString());
    }
  }
}

Java

Este exemplo aplica-se apenas a versões da biblioteca de cliente anteriores a 2.23.0, quando foi introduzida a mudança de tamanho automática.


import com.google.api.gax.grpc.InstantiatingGrpcChannelProvider;
import com.google.cloud.bigtable.data.v2.BigtableDataClient;
import com.google.cloud.bigtable.data.v2.BigtableDataSettings;
import com.google.cloud.bigtable.data.v2.stub.EnhancedBigtableStubSettings;
import java.io.IOException;

public class ConfigureConnectionPool {

  public static void configureConnectionPool(String projectId, String instanceId) {
    // String projectId = "my-project-id";
    // String instanceId = "my-instance-id";

    BigtableDataSettings.Builder settingsBuilder =
        BigtableDataSettings.newBuilder().setProjectId(projectId).setInstanceId(instanceId);

    settingsBuilder
        .stubSettings()
        .setTransportChannelProvider(
            EnhancedBigtableStubSettings.defaultGrpcTransportProviderBuilder()
                .setPoolSize(10)
                .build());

    BigtableDataSettings settings = settingsBuilder.build();
    try (BigtableDataClient dataClient = BigtableDataClient.create(settings)) {
      InstantiatingGrpcChannelProvider provider =
          (InstantiatingGrpcChannelProvider)
              settings.getStubSettings().getTransportChannelProvider();

      int poolSize = provider.toBuilder().getPoolSize();

      System.out.println(String.format("Connected with pool size of %d", poolSize));
    } catch (IOException e) {
      System.out.println("Error during ConfigureConnectionPool: \n" + e.toString());
    }
  }
}

C++

namespace cbt = ::google::cloud::bigtable;
namespace gc = ::google::cloud;
[](std::string const& project_id, std::string const& instance_id,
   std::string const& table_id) {
  auto constexpr kPoolSize = 10;
  auto options = gc::Options{}.set<gc::GrpcNumChannelsOption>(kPoolSize);
  cbt::Table table(cbt::MakeDataConnection(options),
                   cbt::TableResource(project_id, instance_id, table_id));
  std::cout << "Connected with channel pool size of " << kPoolSize << "\n";
}