BigQuery 기본 구조와 비용 관리: dataset·partition·bytes processed

반응형

BigQuery 비용 관리는 query를 실행한 뒤 청구서를 확인하는 일이 아니다. project.dataset.table 구조와 location을 먼저 정하고, 필요한 column과 partition만 읽으며, 실행 전에 estimated bytes와 maximum bytes billed를 확인하는 흐름이 기본이다.

BigQuery는 어떤 서비스인가

Google Cloud의 BigQuery overview는 BigQuery를 fully managed, AI-ready data platform으로 설명한다. serverless architecture이므로 사용자가 query worker VM을 직접 provision하거나 patch하지 않아도 된다. 다만 serverless가 schema, IAM, data quality, query cost, workload capacity까지 자동으로 운영해 준다는 뜻은 아니다.

BigQuery는 대규모 analytical query와 aggregation에 맞는 columnar data platform이다. GoogleSQL로 BigQuery에 저장된 data뿐 아니라 external table과 federated query를 통해 다른 위치의 data도 조회할 수 있다. 반대로 millisecond 단위의 point transaction과 잦은 row update가 중심이라면 transactional database가 더 적합할 수 있다.

project·dataset·table은 어떻게 이어지나

BigQuery resource를 가장 짧게 표현하면 다음과 같다.

Google Cloud project
└── BigQuery dataset
    ├── table
    ├── view
    ├── routine
    └── model

GoogleSQL에서 table은 보통 다음처럼 fully qualified name으로 참조한다.

`my_project.analytics.orders`
  • project: billing, IAM, quota와 job 실행의 상위 경계
  • dataset: table·view·routine 등을 묶고 location과 일부 access policy를 정하는 container
  • table: row와 column schema를 가진 data resource
  • job: query, load, copy, export 같은 작업의 실행 단위

dataset 공식 문서는 dataset이 특정 project 안에 있으며 table과 view를 조직하고 access를 제어하는 top-level container라고 설명한다. dataset을 만들 때 지정한 location은 이후 data 이동과 join 가능 범위에 영향을 주므로 이름만 정하고 넘길 설정이 아니다.

비용은 무엇에 붙나

BigQuery pricing은 비용을 크게 compute와 storage로 나눈다. 그 밖에도 streaming read·write, BI Engine, BigQuery ML, data transfer 같은 기능별 비용이 발생할 수 있다.

compute에는 두 가지 대표 model이 있다.

model 과금 기준 확인할 항목
on-demand query가 처리한 bytes 선택한 column, partition pruning, cache, maximum bytes billed
capacity 사용한 slot-hour와 edition reservation, autoscaling, workload concurrency

on-demand에서 LIMIT 10을 붙였다고 non-clustered table의 scan 비용이 10 row로 줄지는 않는다. 반환 row 수와 읽은 column bytes는 다른 값이다. SELECT *를 습관적으로 쓰지 않고 필요한 column을 명시해야 하는 이유다.

가격 숫자는 region, edition, 통화, 시점에 따라 바뀔 수 있다. 글에 고정 단가를 복사하기보다 실행 시점의 공식 pricing page와 billing account를 확인한다.

partition과 clustering은 무엇이 다른가

partition은 table을 date, timestamp, datetime 또는 integer range 기준의 segment로 나눈다. query filter가 partition column을 올바르게 제한하면 BigQuery가 불필요한 partition을 건너뛰는 partition pruning을 수행한다.

clustering은 지정한 column의 값에 따라 storage block을 정리한다. filter가 clustering column을 사용하면 관련 block만 scan할 가능성이 커진다. 둘은 경쟁 기능이 아니라 함께 사용할 수 있다.

기준 partition clustering
나누는 단위 명시적인 partition adaptively sized storage block
대표 선택 자주 거르는 date·timestamp 자주 filter·aggregate하는 고유값 많은 column
비용 예측 pruning 후 실행 전 비교적 명확 실제 block pruning으로 실행 전 estimate가 upper bound일 수 있음
관리 기능 partition expiration·partition 단위 작업 block 배치 자동 관리

partition을 너무 잘게 쪼개면 작은 partition이 많아져 metadata overhead가 커질 수 있다. partitioned table 문서는 partition이 매우 작거나 지나치게 많다면 clustering을 고려하라고 안내한다.

비용을 줄이는 query는 어떻게 쓰나

다음 예시는 orders table이 order_date로 partition되어 있고 customer_id로 clustering되었다고 가정한다.

SELECT
  customer_id,
  SUM(amount) AS total_amount
FROM `my_project.analytics.orders`
WHERE order_date >= DATE '2026-07-01'
  AND order_date < DATE '2026-08-01'
  AND customer_id IN ('c-101', 'c-205')
GROUP BY customer_id
ORDER BY total_amount DESC;

이 query의 비용 관점 핵심은 세 가지다.

  1. SELECT * 대신 필요한 두 column만 읽는다.
  2. partition column에 직접 range predicate를 적용한다.
  3. clustering column filter로 scan block을 줄일 여지를 만든다.

date range를 [start, end) 형태로 쓰면 month 마지막 날과 time component 경계를 다루기 쉽다. 실제 column이 TIMESTAMP라면 business timezone을 어느 단계에서 DATE로 바꿀지도 schema 설계 때 정해야 한다.

실행 전에 비용을 막는 장치

query editor의 bytes estimate나 dry run으로 처리 예상량을 확인한다. 그다음 on-demand query에는 maximum bytes billed를 설정해 예상보다 큰 scan을 실행 전에 실패시킬 수 있다.

bq query \
  --use_legacy_sql=false \
  --dry_run \
  'SELECT customer_id FROM `my_project.analytics.orders`'

bq query \
  --use_legacy_sql=false \
  --maximum_bytes_billed=1073741824 \
  'SELECT customer_id FROM `my_project.analytics.orders`'

첫 명령은 query를 실행하지 않고 bytes estimate를 확인한다. 두 번째 명령은 estimate가 1 GiB limit을 넘으면 실행하지 않는다. clustered table은 사전 estimate가 실제 billed bytes보다 클 수 있어 보수적으로 실패할 수 있다는 점도 고려한다. BigQuery cost best practices는 on-demand model에서 maximum bytes billed 사용을 권장한다.

실시간 분석이라는 표현에서 빠지는 것

BigQuery가 새 data를 자동으로 실시간 수집하는 것은 아니다. freshness는 ingestion path와 query layer를 나눠 봐야 한다.

  • producer가 언제 event를 만든다.
  • streaming write, load job, transfer 중 무엇으로 언제 들어온다.
  • deduplication과 late event를 어떻게 처리한다.
  • materialized view나 dashboard cache가 언제 refresh된다.
  • consumer가 어느 시점의 data를 허용한다.

query engine이 빠르더라도 batch load가 하루 한 번이면 dashboard data도 하루 단위로 늦을 수 있다. “real-time” 대신 end-to-end freshness SLO를 분과 초 단위로 정의하는 편이 정확하다.

도입 전에 확인할 운영 항목

  1. analytical workload와 transactional workload를 분리한다.
  2. dataset location과 data residency 요구를 먼저 정한다.
  3. dataset·table IAM과 service account 권한을 최소화한다.
  4. partition·clustering 후보는 실제 filter pattern으로 고른다.
  5. dry run, maximum bytes billed, project-level cost control을 적용한다.
  6. query bytes, slot usage, latency, freshness, failed job을 함께 관측한다.
  7. storage·compute 외 streaming, BI Engine, ML, transfer 비용을 별도로 확인한다.

key-value·transaction 중심 설계와 비교하려면 Amazon DynamoDB 핵심 구조, row-oriented database의 lookup cost는 복합 index 설계 기준에서 이어서 볼 수 있다.

정리

BigQuery는 infrastructure server를 직접 관리하지 않고 analytical data를 GoogleSQL로 처리하는 fully managed platform이다. 운영의 핵심은 project.dataset.table resource 경계, dataset location, IAM, ingestion freshness와 pricing model을 함께 설계하는 것이다. on-demand 비용은 필요한 column·partition만 읽고 dry run과 maximum bytes billed를 적용해 실행 전에 제어한다.

참고 자료

반응형
KEEP READING
카테고리 전체 보기 →

댓글