본문 바로가기

data engineering/data warehouse

Google Bigquery -3 (최적화 기법 - 파티셔닝, 클러스터링, 캐싱, 쿼리 튜닝)

https://nani-log.tistory.com/168

 

Google Bigquery -2 (아키텍처)

https://nani-log.tistory.com/167 Google Bigquery -1 (설계적 특성 - OLAP, Columnar, MPP, Serverless)https://nani-log.tistory.com/161 Amazon Redshift -1 (설계적 특성 - OLAP, Columnar, MPP, Provisioning)Amazon Redshift는 직접 하둡 클러스

nani-log.tistory.com

 

앞서 Bigquery는 서버리스로 제공되기 때문에 인프라에 관련한 고민은 구글에 맡겨두고 데이터 웨어하우스를 구축할 수 있다는 장점이 있어 사용자 입장에선 쿼리 비용(슬롯 사용량)과 스토리지 비용에 집중해 관리하면 된다고 언급했었다

 

이번 포스트에선 쿼리와 스토리지 비용을 최적화하는 기법인 파티셔닝, 클러스터링, 캐싱, 쿼리 최적화를 살펴볼 예정이다

 

파티셔닝

 

테이블 내에서 파티셔닝을 통해 여러 파티션을 정의할 수 있다. Bigquery에서는 수집 시간의 날짜, DATE 컬럼, TIMESTAMP 컬럼의 날짜, 정수로 파티션 키를 지정할 수 있다. 파티션 키를 지정한 테이블은 위 그림에서 오른쪽 네개의 테이블을 보면 확인할 수 있다. 그림에서는 파티션이 Order_Date 컬럼으로 지정되어 일자별로 나뉜다

 

파티션을 지정했을 때의 장점은 다음과 같다

  • 파티션 단위로 데이터를 적재할 수 있다
  • 파티션 단위로 쿼리가 가능해, 쿼리 탐색 범위를 줄이고 쿼리 속도가 빨라진다. Bigquery는 쿼리가 데이터를 탐색하는 만큼 비용을 부과하기 때문에 비용 또한 감소한다
  • 특히 조인 및 집계에서 필요한 데이터만을 가져올 수 있기에 빛을 발한다

 

파티션을 지정했을 때 단점 또한 존재한다

  • 복잡성이 증가한다. 적절한 파티션 키를 선택하는 것이 중요하고, 파티션 프루닝이 잘 적용되려면 쿼리 작성시 파티션 필터를 항상 신경써야 한다
  • 파티션 키를 적절히 설정하지 않으면, 일부 파티션에 데이터가 집중되는 skew(데이터 불균형) 현상이 발생한다

 

클러스터링

클러스터링은 특정 컬럼을 클러스터링 키로 지정해 데이터 배열을 조정할 수 있다. 클러스터링 컬럼으로 설정할 수 있는 데이터 유형은 STRING, INT64, NUMERIC, BIGNUMERIC, DATE, DATETIME, TIMESTAMP, BOOL, GEOGRAPHY가 있고 최대 4개까지 선정할 수 있다. 첫번째 컬럼이 가장 우선 순위가 높기 때문에 쿼리의 필터 조건과 키 지정 순서가 동일해야 효과가 극대화된다

 

또한 클러스터링된 테이블에서 쿼리 비용의 감소는 실행된 후에 확인할 수 있다

 

클러스터링을 지정했을 때의 장점은 다음과 같다

  • 특정 컬럼을 기준으로 필터링하는 경우가 많을때 클러스터링 키를 해당 컬럼으로 설정해두면 필요한 데이터만 스캔할 수 있어 비용도 줄이고 쿼리 응답 속도도 빨라진다(블록 프루닝)

 

클러스터링을 지정했을 때 단점 또한 존재한다

  • 쿼리 패턴을 이해하고 적절한 클러스터링 키를 선택해야 하기에 관리의 복잡성이 증가한다
  • 클러스터링된 테이블에 데이터를 삽입하면, 기존 데이터에 맞게 정렬되어야하기 때문에 성능 저하가 발생한다
  • 주기적으로 재클러스터링 작업을 수행해야 한다(자동으로 재클러스터링을 수행하긴 한다)
  • 특정 값에 데이터가 집중되면, 클러스터링의 이점이 감소할 수 있다

 

파티션과 클러스터링 모두 카디널리티가 높은(고유한 값이 많은) 컬럼을 선택하는 것이 중요하다. 데이터가 거대한 반면에 너무 적은 수의 고유값이 존재하면 특정 파티션이나 블록으로 skew될 가능성이 높다

 

또한 쿼리 패턴을 잘 파악하는 것이 중요하다. 결국 조인, 집계, 필터 등에서 자주 쓰이는 컬럼을 설정해야 프루닝의 성능이 극대화될 것이다

 

 

캐싱

Bigquery는 모든 쿼리 결과를 캐시에 저장해 재사용한다. 캐싱에는 다음과 같은 특징이 있다

  • 캐싱된 테이블은 24시간 유지되며, 데이터나 쿼리가 변경되면 캐시가 무효화된다
  • 사용자 및 프로젝트별로 유지 관리되고, 다른 사용자 프로젝트에서 사용하려면 필요한 권한을 부여해야 한다
  • 결과 테이블은 스토리지 비용이 발생하지 않지만 영구 테이블에 쿼리 결과를 쓰면 데이터 저장 요금이 청구된다

 

쿼리 결과가 캐싱되었다면, 사용자가 쿼리를 실행했을때 부분 쿼리에 대해 캐싱된 결과를 사용할 수도 있고 전체 쿼리에 대해 캐싱된 결과를 사용할 수도 있다. 특히 대시보드나 반복적인 분석 쿼리에 효과적이다

 

 

쿼리 튜닝

Bigquery에서는 다음과 같은 요금이 발생한다

  • 테이블에 데이터를 보관하는 크기와 보관 시기
  • 스트리밍 삽입
  • 실행한 쿼리가 스캔하는 데이터 크기

'실행한 쿼리가 스캔하는 데이터 크기'의 비용이 만만치 않다는 것을 주의해야 한다. Bigquery를 사용하는 사용자들은 쿼리의 비용을 최소화하기 위해 노력해야 한다. 쿼리를 튜닝하는 방법은 다음과 같다

 

1. 비용/성능 튜닝 공통

  • SELECT * 을 사용하지 않는다
  • 파티션/클러스터화 테이블을 사용한다
  • 가능하다면 캐시를 활성화한다
  • 표준 SQL을 사용한다

 

2. 비용 튜닝

  • 미리보기를 통해 쿼리 비용을 예상한다
  • 사전에 쿼리 크기를 확인해 요금을 예상한다
  • 쿼리 비용을 제한하기 위해 프로젝트/쿼리별 청구 가능한 최대 크기를 설정해둔다

 

3. 성능 튜닝

  • 서브쿼리를 많이 사용하면 쿼리 실행시마다 요금이 부과되기 때문에 서브쿼리를 일시적인 테이블로 만들어 두는 것이 좋다
  • order by를 사용하면 처리를 실행하는 병렬 처리 노드가 한정되어 성능이 저하된다
  • 데이터 유형 중, STRUCT/ARRAY형을 사용해 개별 테이블로 데이터를 보관하면 쿼리 성능을 높일 수 있다

 

 

정리

구글은 사용자의 요청을 효율적으로 처리할 수 있을지 고민한다. 사용자는 Bigquery에 데이터 저장할 때부터 쿼리를 실행할때까지 파티션, 클러스터링, 쿼리 튜닝 등을 통해 비용을 줄이고 성능을 높이려는 고민을 한다. 결국 구글이 제공하는 것과 사용자의 노력이 합쳐져 Bigquery의 높은 성능과 비용 효율성을 달성할 수 있다

 

Bigquery를 사용하는 사용자 입장에선 각각의 최적화가 잘 이뤄지고 있는지 데이터를 모델링하고 쿼리를 최적화하는 것이 정말 중요할 것 같다

 

 

 

[참고]

https://cloud.google.com/bigquery/docs?hl=ko

이야기로 배우는 구글 빅쿼리