BigQuery로 데이터 로드를 몇 배 가속화하는 방법

BigQuery에 데이터를 로드할 때 압축을 하면 로드 시간이 늘어날 수 있습니다.
이 기사에서는 압축의 유무에 의해 어느 정도의 시간차가 나오는지를 소개합니다.

검증 방법





S3에 배치한 파일을 EC2의 embbulk에 의해 BigQuery로 전송합니다.
이 때 사용한 EC2 인스턴스는 c5.xlarge이며 aws와 GCP 간의 통신은 전용선이 아닌 인터넷 회선을 이용하고 있습니다.

전송할 파일 만들기



전송할 파일을 S3에 배치합니다.
다음 YAML을 embbulk에서 실행하면 gz 압축된 csv 파일이 S3에 배치됩니다.
파일 크기는 1.8GB입니다.
exec:
  min_output_tasks: 1
  max_threads: 1
in:
  type: random
  rows: 10000000
  schema:
    col1: integer
    col2: integer
    col3: integer
    col4: integer
    col5: integer
    col6: string
    col7: string
    col8: string
    col9: string
    col10: string
filters:
  - type: speedometer
out:
  type: s3
  sequence_format: ''
  bucket: <bucket-name>
  path_prefix: dummy
  file_ext: .csv.gz
  formatter:
    type: csv
    delimiter: ','
    newline: CRLF
    charset: UTF-8
    quote_policy: ALL
  encoders:
  - type: gzip

S3→BigQuery로 전송



S3 파일을 BigQuery로 전송하려면 다음 YAML 파일을 사용합니다.
out의 compression을 GZIP , NONE로 할지에 따라 전송 시간이 어떻게 바뀌는지를 검증했습니다.
in:
  type: s3
  bucket: <s3 bucket name>
  path_prefix: dummy.csv.gz
  region: ap-northeast-1
  auth_method: instance
  decoders:
  - {type: gzip}
  parser:
    charset: UTF-8
    newline: CRLF
    type: csv
    delimiter: ','
    quote: '"'
    escape: '"'
    trim_if_not_quoted: false
    skip_header_lines: 1
    null_string: ''
    allow_extra_columns: false
    allow_optional_columns: false
    columns:
    - {name: col1, type: long}
    - {name: col2, type: long}
    - {name: col3, type: long}
    - {name: col4, type: long}
    - {name: col5, type: long}
    - {name: col6, type: string}
    - {name: col7, type: string}
    - {name: col8, type: string}
    - {name: col9, type: string}
    - {name: col10, type: string}
out:
  type: bigquery
  mode: replace
  auth_method: json_key
  json_keyfile: <path to JSON key file>
  dataset: <dataset name>
  table: dummy
  auto_create_dataset: false
  auto_create_table: false
  gcs_bucket: <gcs bucket name>
  auto_create_gcs_bucket: false
  open_timeout_sec: 300
  send_timeout_sec: 300
  read_timeout_sec: 300
  retries: 5
  compression: GZIP # ここのフラグをGZIPにするかNONEにするかで転送時間の差を比較する
  source_format: NEWLINE_DELIMITED_JSON
  job_status_max_polling_time: 36000
  default_timezone: "Asia/Tokyo"

결과와 고찰



압축 유무에 의한 전송 시간의 변화를 아래 표에 나타냅니다.


압축 있음
압축 없음


24:15
4:14


무려, 압축의 유무로 약 6배의 차이가 나왔습니다!

왜 이런 차이가 나왔는지 생각하고 싶습니다.
그 때문에, 이 전송 처리 중에서도 특히 시간이 걸리고 있는 처리를 3개 다루어, 각각의 처리 시간을 비교해 보기로 합니다.
특히 시간이 걸리는 처리는 다음 세 가지입니다.
  • S3 파일을 EC2 인스턴스의 로컬 스토리지에 배치
  • 위의 파일을 GCS에 업로드
  • GCS에 배치 된 파일을 BigQuery에로드



  • 이러한 처리 시간이 압축의 유무에 따라 어떻게 변화하는지를 아래 표에 나타냅니다.
    이러한 데이터는 embulk 로그에 출력되는 타임스탬프에서 구했습니다.



    압축 있음
    압축 없음



    3:15
    1:54


    0:34
    0:56


    20:26
    1:24


    ①에 대해서는 파일을 압축하는 처리의 부하가 없어졌기 때문에, 압축 없음이 고속으로 되어 있습니다.
    ②는 압축 유무에 따라 파일 사이즈가 바뀌기 때문에 네트워크 전송 시간이 변화했기 때문입니다.
    그리고 이번 전송 시간 고속화에 가장 기여하고 있는 것은 ③입니다.
    ③에만 주목하면 무려 15배의 고속화가 이루어지고 있습니다.
    이 이유는 다음 문서에 기록되어 있습니다.


    For other data formats such as CSV and JSON, BigQuery can load uncompressed files significantly faster than compressed files because uncompressed files can be read in parallel. Because uncompressed files are larger, using them can lead to bandwidth limitations and higher Cloud Storage in Cloud Storage prior to being loaded into BigQuery. You should also note that line ordering is not guaranteed for compressed or uncompressed files. It's important to weigh these tradeoffs depending on your use case.

    분명히 압축이 없으면 파일을 병렬로 읽을 수 있습니다.
    이 효과에 의해 압축 없음의 경우는 고속으로 데이터 전송을 할 수 있었습니다.
    그러나, 네트워크 대역에 주는 부하는 압축 없는 쪽이 크기 때문에, 혼잡이 발생하지 않도록 주의할 필요가 있을 것 같습니다.

    요약



    BigQuery에 데이터를 로드할 때 압축 여부에 따라 처리 시간에 큰 차이가 발생했습니다.
    네트워크 부하에 미치는 영향이 크지 않다면 압축 없이 데이터 전송하는 것도 충분히 고려하고 싶을 것입니다.

    좋은 웹페이지 즐겨찾기