연결 풀 구성

일부 Cloud Bigtable 클라이언트 라이브러리를 사용하면 채널 풀이라고도 하는 클라이언트 연결 풀에서 gRPC 채널 수를 구성할 수 있습니다. 대부분의 경우 기본 구성이 올바르며 변경할 필요가 없습니다.

연결 풀은 Java 버전 2.23.0 이상에 대해 Cloud Bigtable 클라이언트 라이브러리를 사용할 때 그리고 Java 버전 2.9.1 이상에 대해 Cloud Bigtable HBase 클라이언트를 사용할 때 필요에 따라 자동으로 크기가 조정됩니다.

이 페이지에서는 애플리케이션에 가장 적합한 연결 풀 크기를 결정하는 방법을 설명하고 연결 풀을 구성하는 방법을 보여주는 코드 스니펫을 제공합니다.

이 페이지를 읽기 전에 Bigtable 연결 풀 개요를 읽고 작동 방식과 변경 여부를 알아보세요.

다음 클라이언트 라이브러리는 연결 풀링을 제공하며 이를 통해 풀 수를 구성할 수 있습니다.

최적의 연결 풀 크기 결정

트래픽 변동에 대해 여지를 남겨 두기 위해 연결 풀은 포화도를 최대화하기 위해 필요한 연결 수의 약 2배를 차지하는 것이 가장 좋습니다. 연결 하나에서 동시 요청을 최대 100개까지 처리할 수 있으므로 대기 요청은 연결당 10~50개가 가장 좋습니다. 이 개념은 연결 풀에 자세히 설명되어 있습니다.

변경 후 트래픽을 모니터링하고 필요한 경우 풀의 연결 수를 조정합니다.

다음 단계는 OpenCensus에서 제공하는 것과 같은 클라이언트 측 측정항목을 사용하여 채널 풀의 최적 연결 수를 계산하는 데 유용합니다.

  1. 클라이언트 측 측정항목에서 다음 정보를 수집합니다.
    1. 애플리케이션에서 일반 워크로드를 실행하는 경우 클라이언트별 최대 초당 쿼리 수(QPS)입니다.
    2. 밀리초(ms) 단위의 평균 지연 시간(단일 요청의 응답 시간)입니다.
  2. 1,000을 평균 지연 시간 값으로 나누어 순차적으로 전송할 수 있는 초당 요청 수를 결정합니다.
  3. QPS(초 단위)를 초당 직렬 요청 수로 나눕니다.
  4. 최소 최적 채널 풀 크기를 결정하려면 결과를 채널당 요청 50개로 나눕니다. (계산이 2보다 작으면 채널을 2개 이상 사용하여 중복성을 보장합니다.)
  5. 최대 최적 채널 풀 크기를 결정하려면 동일한 결과를 채널당 요청 10개로 나눕니다.

이러한 단계는 다음 방정식으로 표현됩니다.

  • (QPS초 ÷ (1,000 ÷ 지연 시간 밀리초)) ÷ 스트림 50개 = 최소 최적 연결 수

  • (QPS 초 ÷ (1,000 ÷ 지연 시간 밀리초)) ÷ 스트림 10개 = 최대 최적 연결 수

일반적으로 애플리케이션에서 요청을 초당 50,000개 전송하며 평균 지연 시간은 10밀리초입니다. 1,000을 10밀리초로 나눠 초당 100개의 요청을 순차적으로 보낼 수 있는지 확인합니다. QPS 50,000개를 전송하는 데 필요한 동시 로드를 구하려면 해당 숫자를 50,000으로 나눕니다. 그러면 500이 됩니다. 각 채널에는 요청이 동시에 최대 100개까지 있을 수 있으며 대상 채널 사용률은 동시 스트림 10~50개입니다. 따라서 최솟값을 계산하려면 500을 50으로 나눠 10을 구합니다. 최댓값을 찾으려면 500을 10으로 나눠 50을 구합니다. 즉, 이 예시의 채널 풀 크기는 연결 10~50개여야 합니다.

풀 크기 설정

다음 코드 샘플은 풀 크기를 설정할 수 있도록 클라이언트 라이브러리에서 풀 수를 구성하는 방법을 보여줍니다.

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

이 샘플은 자동 크기 조정이 사용된 경우 2.9.1 이전의 클라이언트 라이브러리 버전에만 적용됩니다.



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

이 샘플은 자동 크기 조정이 사용된 경우 2.23.0 이전의 클라이언트 라이브러리 버전에만 적용됩니다.


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";
}