Amazon S3 전송

Amazon S3용 BigQuery Data Transfer Service를 사용하면 Amazon S3에서 BigQuery로 반복되는 로드 작업을 자동으로 예약하고 관리할 수 있습니다.

시작하기 전에

Amazon S3 전송을 만들기 전에 다음을 수행합니다.

제한사항

Amazon S3 전송에는 다음과 같은 제한사항이 적용됩니다.

  • 현재 Amazon S3 URI의 버킷 부분을 매개변수화할 수 없습니다.
  • Amazon S3에서의 전송은 항상 대상 테이블에 데이터를 추가하는 WRITE_APPEND 환경설정으로 트리거됩니다. 자세한 내용은 로드 작업 구성에서 configuration.load.writeDisposition을 참조하세요.
  • Amazon S3 소스 데이터 형식에 따라 추가 제한사항이 있을 수 있습니다. 자세한 내용은 다음을 참조하세요.

  • 반복 전송 사이의 최소 간격은 24시간입니다. 반복 전송의 기본 간격은 24시간입니다.

필수 권한

Amazon S3 전송을 만들기 전에 다음을 수행합니다.

  • 전송을 만드는 사람에게 다음과 같은 BigQuery 필수 권한이 있는지 확인합니다.

    • 전송을 만들 bigquery.transfers.update 권한
    • 대상 데이터 세트에 대한 bigquery.datasets.getbigquery.datasets.update 권한

    사전 정의된 IAM 역할 bigquery.admin에는 bigquery.transfers.update, bigquery.datasets.update, bigquery.datasets.get 권한이 있습니다. BigQuery Data Transfer Service의 IAM 역할에 대한 자세한 내용은 액세스 제어 참조를 확인하세요.

  • Amazon S3의 문서를 참조하여 전송을 사용 설정하는 데 필요한 권한을 구성했는지 확인합니다. Amazon S3 소스 데이터에 최소한 AWS 관리 정책 AmazonS3ReadOnlyAccess가 적용되어야 합니다.

Amazon S3 데이터 전송 설정

Amazon S3 데이터 전송을 만들려면 다음 단계를 따르세요.

Console

  1. Cloud Console에서 BigQuery 페이지로 이동합니다.

    BigQuery 페이지로 이동

  2. 전송을 클릭합니다.

  3. 전송 만들기를 클릭합니다.

  4. 전송 만들기 페이지에서 다음을 수행합니다.

    • 소스 유형 섹션의 소스에서 Amazon S3을 선택합니다.

      전송 소스

    • 전송 구성 이름 섹션의 표시 이름에 전송 이름(예: My Transfer)을 입력합니다. 전송 이름은 나중에 수정해야 할 경우에 대비해 전송을 식별할 수 있는 값이면 됩니다.

      전송 이름

    • 일정 옵션 섹션의 일정에서 기본값(지금 시작)을 유지하거나 설정 시간에 시작을 클릭합니다.

      • 반복 빈도에서 전송을 실행할 빈도 옵션을 선택합니다. 옵션은 다음과 같습니다.

        • 매일(기본값)
        • 매주
        • 매월
        • 커스텀
        • 요청 시

        매일 이외의 옵션을 선택하면 추가 옵션이 제공됩니다. 예를 들어 매주를 선택하면 요일을 선택할 수 있는 옵션이 나타납니다.

      • 시작일 및 실행 시간에 전송을 시작할 날짜 및 시간을 입력합니다. 지금 시작을 선택하면 이 옵션은 사용 중지됩니다.

        전송 일정

    • 대상 설정 섹션의 대상 데이터세트에서 데이터를 저장하기 위해 만든 데이터세트를 선택합니다.

      전송 데이터세트

    • 데이터 소스 세부정보 섹션에서 다음을 수행합니다.

      • 대상 테이블에 BigQuery에 데이터를 저장하기 위해 만든 테이블의 이름을 입력합니다. 대상 테이블 이름은 매개변수로 지정할 수 있습니다.
      • Amazon S3 URI의 경우 URI를 s3://mybucket/myfolder/... 형식으로 입력합니다. URI는 매개변수로도 지정할 수 있습니다.
      • 액세스 키 ID에 액세스 키 ID를 입력합니다.
      • 보안 비밀 액세스 키에 보안 비밀 액세스 키를 입력합니다.
      • 파일 형식에서 데이터 형식을 줄바꿈으로 구분된 JSON, CSV, Avro, Parquet, ORC 중에서 선택합니다.

        S3 소스 세부정보

    • 전송 옵션 - 모든 형식 섹션에서 다음을 수행합니다.

      • 허용되는 오류 개수에 무시할 수 있는 최대 오류 레코드 수를 정수 값으로 입력합니다.
      • (선택사항) 십진수 타겟 유형에 소스 십진수 값을 변환할 수 있는 가능한 SQL 데이터 유형의 쉼표로 구분된 목록을 입력합니다. 변환에 적합한 SQL 데이터 유형은 다음 조건에 따라 달라집니다.
        • 변환에 사용되는 데이터 유형은 다음 목록에서 소스 데이터의 정밀도 및 규모를 지원하는 첫 번째 데이터 유형이 됩니다. 순서는 NUMERIC, BIGNUMERIC, STRING입니다.
        • 나열된 데이터 유형이 정밀도 및 규모를 지원하지 않는 경우 지정된 목록에서 가장 넓은 범위를 지원하는 데이터 유형이 선택됩니다. 소스 데이터를 읽을 때 값이 지원되는 범위를 초과하면 오류가 발생합니다.
        • 데이터 유형 STRING은 모든 정밀도 및 규모 값을 지원합니다.
        • 이 필드를 비워두면 데이터 유형은 기본적으로 ORC의 경우 'NUMERIC,STRING', 다른 파일 형식의 경우 'NUMERIC'으로 설정됩니다.
        • 이 필드에 중복된 데이터 유형이 있으면 안 됩니다.
        • 이 필드에 나열하는 데이터 유형의 순서는 무시됩니다.

      전송 옵션 모든 형식

    • 파일 형식으로 CSV 또는 JSON을 선택한 경우, JSON, CSV 섹션에서 알 수 없는 값 무시를 선택하면 스키마와 일치하지 않는 값이 포함된 행이 허용됩니다. 알 수 없는 값이 무시됩니다. CSV 파일의 경우, 이 옵션을 선택하면 줄 끝 부분의 추가 값이 무시됩니다.

      알 수 없는 값 무시

    • 파일 형식으로 CSV를 선택한 경우, CSV 섹션에 데이터 로드와 관련된 추가 CSV 옵션을 입력합니다.

      CSV 옵션

    • (선택사항) 알림 옵션 섹션에서 다음을 수행합니다.

      • 전환을 클릭해서 이메일 알림을 사용 설정합니다. 이 옵션을 사용 설정하면 전송 실행이 실패할 때 전송 관리자에게 이메일 알림이 발송됩니다.
      • Cloud Pub/Sub 주제 선택에서 주제 이름을 선택하거나 주제 만들기를 클릭하여 주제를 만듭니다. 이 옵션은 전송에 대한 Pub/Sub 실행 알림을 구성합니다.
  5. 저장을 클릭합니다.

bq

bq mk 명령어를 입력하고 전송 생성 플래그 --transfer_config를 지정합니다.

bq mk \
--transfer_config \
--project_id=project_id \
--data_source=data_source \
--display_name=name \
--target_dataset=dataset \
--params='parameters'

각 항목의 의미는 다음과 같습니다.

  • project_id: 선택사항. Google Cloud 프로젝트 ID 특정 프로젝트를 지정하는 --project_id가 입력되지 않으면 기본 프로젝트가 사용됩니다.
  • data_source: 필수. 데이터 소스 — amazon_s3.
  • display_name: 필수. 전송 구성의 표시 이름입니다. 전송 이름은 나중에 수정해야 할 경우에 전송을 쉽게 식별할 수 있는 값이면 됩니다.
  • dataset: 필수. 전송 구성의 대상 데이터 세트입니다.
  • parameters: 필수. JSON 형식으로 생성된 전송 구성의 매개변수입니다. 예를 들면 --params='{"param":"param_value"}'입니다. 다음은 Amazon S3 전송을 위한 매개변수입니다.

    • destination_table_name_template: 필수. 대상 테이블의 이름입니다.
    • data_path: 필수. 다음 형식의 Amazon S3 URI입니다.

      s3://mybucket/myfolder/...

      URI는 매개변수로도 지정할 수 있습니다.

    • access_key_id: 필수. 액세스 키 ID입니다.

    • secret_access_key: 필수. 보안 비밀 액세스 키입니다.

    • file_format: 선택사항. 전송할 파일 유형(CSV, JSON, AVRO, PARQUET 또는 ORC)을 나타냅니다. 기본값은 CSV입니다.

    • max_bad_records: 선택사항. 허용되는 불량 레코드 수입니다. 기본값은 0입니다.

    • decimal_target_types: 선택사항. 소스 십진수 값을 변환할 수 있는 가능한 SQL 데이터 유형의 쉼표로 구분된 목록입니다. 이 필드가 제공되지 않으면 데이터 유형은 기본적으로 ORC의 경우 'NUMERIC,STRING', 다른 파일 형식의 경우 'NUMERIC'으로 설정됩니다.

    • ignore_unknown_values: 선택사항이며 file_formatJSON 또는 CSV가 아닌 경우 무시됩니다. 데이터에서 알 수 없는 값을 무시할지 여부입니다.

    • field_delimiter: 선택사항이며 file_formatCSV인 경우에만 적용됩니다. 필드를 구분하는 문자입니다. 기본값은 쉼표입니다.

    • skip_leading_rows: 선택사항이며 file_formatCSV인 경우에만 적용됩니다. 가져오지 않으려는 헤더 행 수를 나타냅니다. 기본값은 0입니다.

    • allow_quoted_newlines: 선택사항이며 file_formatCSV인 경우에만 적용됩니다. 따옴표가 있는 필드 안에서 줄바꿈을 허용할지 여부를 나타냅니다.

    • allow_jagged_rows: 선택사항이며 file_formatCSV인 경우에만 적용됩니다. 뒤에 오는 선택적인 열이 누락된 행을 허용할지 여부를 나타냅니다. 누락된 값은 NULL로 채워집니다.

예를 들어 다음 명령어는 data_paths3://mybucket/myfile/*.csv, 대상 데이터 세트 mydataset, file_format CSV를 사용하여 이름이 My Transfer인 Amazon S3 전송을 만듭니다. 이 예시에는 CSV file_format과 연관된 선택적 매개변수의 기본값이 아닌 값이 포함되어 있습니다.

기본 프로젝트에 전송이 생성됩니다.

bq mk --transfer_config \
--target_dataset=mydataset \
--display_name='My Transfer' \
--params='{"data_path":"s3://mybucket/myfile/*.csv",
"destination_table_name_template":"MyTable",
"file_format":"CSV",
"max_bad_records":"1",
"ignore_unknown_values":"true",
"field_delimiter":"|",
"skip_leading_rows":"1",
"allow_quoted_newlines":"true",
"allow_jagged_rows":"false",
"delete_source_files":"true"}' \
--data_source=amazon_s3

명령어를 실행한 후 다음과 같은 메시지가 수신됩니다.

[URL omitted] Please copy and paste the above URL into your web browser and follow the instructions to retrieve an authentication code.

안내에 따라 인증 코드를 명령줄에 붙여넣습니다.

API

projects.locations.transferConfigs.create 메서드를 사용하고 TransferConfig 리소스의 인스턴스를 지정합니다.

자바

import com.google.api.gax.rpc.ApiException;
import com.google.cloud.bigquery.datatransfer.v1.CreateTransferConfigRequest;
import com.google.cloud.bigquery.datatransfer.v1.DataTransferServiceClient;
import com.google.cloud.bigquery.datatransfer.v1.ProjectName;
import com.google.cloud.bigquery.datatransfer.v1.TransferConfig;
import com.google.protobuf.Struct;
import com.google.protobuf.Value;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

// Sample to create amazon s3 transfer config.
public class CreateAmazonS3Transfer {

  public static void main(String[] args) throws IOException {
    // TODO(developer): Replace these variables before running the sample.
    final String projectId = "MY_PROJECT_ID";
    String datasetId = "MY_DATASET_ID";
    String tableId = "MY_TABLE_ID";
    // Amazon S3 Bucket Uri with read role permission
    String sourceUri = "s3://your-bucket-name/*";
    String awsAccessKeyId = "MY_AWS_ACCESS_KEY_ID";
    String awsSecretAccessId = "AWS_SECRET_ACCESS_ID";
    String sourceFormat = "CSV";
    String fieldDelimiter = ",";
    String skipLeadingRows = "1";
    Map<String, Value> params = new HashMap<>();
    params.put(
        "destination_table_name_template", Value.newBuilder().setStringValue(tableId).build());
    params.put("data_path", Value.newBuilder().setStringValue(sourceUri).build());
    params.put("access_key_id", Value.newBuilder().setStringValue(awsAccessKeyId).build());
    params.put("secret_access_key", Value.newBuilder().setStringValue(awsSecretAccessId).build());
    params.put("source_format", Value.newBuilder().setStringValue(sourceFormat).build());
    params.put("field_delimiter", Value.newBuilder().setStringValue(fieldDelimiter).build());
    params.put("skip_leading_rows", Value.newBuilder().setStringValue(skipLeadingRows).build());
    TransferConfig transferConfig =
        TransferConfig.newBuilder()
            .setDestinationDatasetId(datasetId)
            .setDisplayName("Your Aws S3 Config Name")
            .setDataSourceId("amazon_s3")
            .setParams(Struct.newBuilder().putAllFields(params).build())
            .setSchedule("every 24 hours")
            .build();
    createAmazonS3Transfer(projectId, transferConfig);
  }

  public static void createAmazonS3Transfer(String projectId, TransferConfig transferConfig)
      throws IOException {
    try (DataTransferServiceClient client = DataTransferServiceClient.create()) {
      ProjectName parent = ProjectName.of(projectId);
      CreateTransferConfigRequest request =
          CreateTransferConfigRequest.newBuilder()
              .setParent(parent.toString())
              .setTransferConfig(transferConfig)
              .build();
      TransferConfig config = client.createTransferConfig(request);
      System.out.println("Amazon s3 transfer created successfully :" + config.getName());
    } catch (ApiException ex) {
      System.out.print("Amazon s3 transfer was not created." + ex.toString());
    }
  }
}

데이터 쿼리

BigQuery로 전송되는 데이터는 내부 데이터화 시간별로 파티션을 나눈 테이블에 기록됩니다. 자세한 내용은 파티션을 나눈 테이블 소개를 참조하세요.

자동 생성된 뷰를 사용하지 않고 직접 테이블을 쿼리하는 경우에는 쿼리에서 _PARTITIONTIME 유사 열을 사용해야 합니다. 자세한 내용은 파티션을 나눈 테이블 쿼리를 참조하세요.

프리픽스 일치와 와일드 카드 일치의 영향 비교

Amazon S3 API는 프리픽스 일치를 지원하지만 와일드 카드 일치는 지원하지 않습니다. 프리픽스와 일치하는 모든 Amazon S3 파일은 Google Cloud로 전송됩니다. 그러나 전송 구성에서 Amazon S3 URI와 일치하는 항목만 실제로 BigQuery에로드됩니다. 따라서 전송되었지만 BigQuery에 로드되지 않은 파일에 초과분의 Amazon S3 이그레스 비용이 발생할 수 있습니다.

다음 데이터 경로를 예시로 들어보겠습니다.

s3://bucket/folder/*/subfolder/*.csv

그리고 소스 위치에 다음 파일이 있다고 가정합니다.

s3://bucket/folder/any/subfolder/file1.csv
s3://bucket/folder/file2.csv

그러면 프리픽스가 s3://bucket/folder/인 모든 Amazon S3 파일이 Google Cloud로 전송됩니다. 이 예시에서는 file1.csvfile2.csv가 모두 전송됩니다.

하지만 s3://bucket/folder/*/subfolder/*.csv와 일치하는 파일만 실제로 BigQuery에 로드됩니다. 이 예시에서는 file1.csv만 BigQuery에 로드됩니다.

문제해결

다음은 일반적인 오류 및 권장되는 해결방법에 대한 정보입니다.

Amazon S3 PERMISSION_DENIED 오류

오류 권장 작업
입력한 AWS 액세스 키 ID가 Google 기록에 없습니다. 액세스 키가 존재하고 ID가 올바른지 확인합니다.
Google이 계산한 요청 서명이 제공된 서명과 일치하지 않습니다. 키와 서명 방법을 확인하세요. 전송 구성에 올바른 해당 보안 비밀 액세스 키가 있는지 확인합니다.
소스 S3 버킷의 위치를 가져올 수 없습니다. 추가 세부정보: 액세스 거부됨

소스 S3 버킷의 위치를 가져올 수 없습니다. 추가 세부정보: HTTP/1.1 403 금지됨

S3 오류 메시지: 액세스 거부됨
AWS IAM 사용자에게 다음을 수행할 권한이 있는지 확인합니다.
  • Amazon S3 버킷을 나열합니다.
  • 버킷의 위치를 가져옵니다.
  • 버킷의 객체를 읽습니다.
서버가 객체 업로드를 초기화할 수 없습니다. InvalidObjectState: 작업이 객체의 스토리지 클래스에 유효하지 않습니다.

소스 S3 버킷의 위치를 가져올 수 없습니다. 추가 세부정보: 이 객체에 대한 모든 액세스가 비활성화되었습니다.
Amazon Glacier에 보관처리된 객체를 모두 복원합니다. Amazon Glacier에 보관처리된 Amazon S3의 객체는 복원되기 전에는 액세스할 수 없습니다.
이 객체에 대한 모든 액세스가 비활성화되었습니다. 전송 구성의 Amazon S3 URI가 올바른지 확인합니다.

Amazon S3 전송 제한 오류

오류 권장 작업
전송 중인 파일 수가 10,000개 제한을 초과합니다. Amazon S3 URI에서 와일드 카드의 수를 1개로 줄일 수 있는지 확인합니다. 이렇게 할 수 있으면 전송 실행당 최대 파일 수가 더 많아지므로 새로운 전송 구성으로 다시 시도합니다.

전송 구성을 각각 소스 데이터의 일부를 전송하는 여러 전송 구성으로 분할할 수 있는지 확인합니다.
전송 중인 파일 크기가 16,492,674,416,640 바이트 제한을 초과합니다. 전송 구성을 각각 소스 데이터의 일부를 전송하는 여러 전송 구성으로 분할할 수 있는지 확인합니다.

일반적인 문제

오류 권장 작업
파일이 Amazon S3에서 전송되었지만 BigQuery로 로드되지 않습니다. 전송 로그는 다음과 유사할 수 있습니다.

Amazon S3에서 Google Cloud로 데이터 이동이 완료되었습니다. <NNN> 객체를 이동했습니다.
Amazon S3 URI와 일치하는 새 파일이 없습니다.
전송 구성의 Amazon S3 URI가 올바른지 확인합니다.

전송 구성이 공통의 프리픽스가 있는 모든 파일을 로드하기 위한 것이라면 Amazon S3 URI가 와일드 카드로 끝나는지 확인하세요.
예를 들어 s3://my-bucket/my-folder/의 모든 파일을 로드하려면 전송 구성의 Amazon S3 URI가 s3://my-bucket/my-folder/가 아니라 s3://my-bucket/my-folder/*여야 합니다.
기타 문제 전송 구성 문제 해결을 참조하세요.

다음 단계