BigQuery의 공간 클러스터링 - 권장사항

Michael Entin
Software Engineer
Remy Welch
Data Engineer
* 본 아티클의 원문은 2022년 9월 27일 Google Cloud 블로그(영문)에 게재되었습니다.
대부분의 데이터 분석가는 더 빠르고 저렴한 비용으로 데이터를 쿼리하기 위해 데이터를 클러스터로 구성한다는 개념에 익숙합니다. 사용자 행동은 데이터 세트를 클러스터링하는 방식을 결정합니다. 예를 들어 사용자가 지리공간 데이터(즉 위치 데이터)를 분석하거나 시각화하려는 경우 지리공간 열에 클러스터링하는 것이 가장 효율적입니다. 이러한 방식을 공간 클러스터링이라고 하며 이 블로그에서는 공간 클러스터링을 BigQuery에서 구현하기 위한 권장사항을 공유합니다(힌트 — BigQuery에 맡기세요).
BigQuery는 페타바이트 규모의 데이터 웨어하우스로, 많은 지리공간 기능과 함수를 갖추고 있습니다. 다음 섹션에서는 BigQuery가 S2 색인 시스템을 사용하여 공간 클러스터링을 즉시 수행하는 방법을 설명합니다. 또한 H3 및 지오해시(geohash)와 같은 다른 공간 색인을 사용하는 방법을 알아보고 다양한 방식의 비용 절감 효과도 비교할 것입니다.
BigQuery가 내부적으로 공간 클러스터링을 수행하는 방법
클러스터링은 유사한 값을 가진 데이터 블록을 스토리지에 함께 배치하므로 쿼리 시 데이터를 더 쉽게 검색할 수 있습니다. 또한 클러스터링이 데이터 블록을 정렬하기 때문에 필요한 블록만 스캔하면 되므로 비용과 처리 시간이 줄어듭니다. 지리공간적인 측면에서 이는 특정 지역을 쿼리할 때 전 지구가 아니라 해당 지역 내부 또는 인근의 행만 스캔함을 의미합니다.
GEOGRAPHY 열에 테이블을 클러스터링하면 위에서 설명한 모든 최적화가 BigQuery에서 자동으로 진행됩니다. 테이블을 만들 때 CLUSTER BY [GEOGRAPHY]를 입력하기만 하면 됩니다. ST_DISJOINT를 제외하고 조건자 함수(예: ST_Intersects, ST_DWithin)만 클러스터링을 활용합니다. BigQuery는 다양한 필드에서 파티션 나누기와 클러스터링을 지원하지만, 지리공간 필드에서는 클러스터링만 지원된다는 점에 주의해야 합니다. 이는 BigQuery가 공간을 분할하는 방식에 관계없이 도형이 클 수 있고 여러 파티션에 걸쳐 나타날 수도 있기 때문입니다. 마지막으로 클러스터 크기는 100MB~1GB이므로 100MB보다 작은 테이블에서 클러스터링하면 아무런 이점이 없습니다.
GEOGRAPHY로 클러스터링된 테이블에 쓰기 작업을 수행할 때 BigQuery는 공간적으로 압축된 블록으로 데이터를 분할합니다. BigQuery는 각 블록 공간 영역 데이터를 포함하는 S2 커버링이라는 메타데이터를 계산합니다. 공간 조건자를 사용하여 지리로 클러스터링된 테이블을 쿼리할 때 BigQuery는 커버링을 읽고 특정 커버링이 필터를 충족할 수 있는지 평가합니다. 그 후 BigQuery는 필터를 충족할 수 없는 블록을 프루닝합니다. 사용자에게는 나머지 블록의 데이터에 대해서만 요금이 부과됩니다. 데이터를 겹치지 않는 지역으로 나누는 것은 불가능한 경우가 많기 때문에 S2 커버링이 겹칠 수 있습니다.
기본적으로 BigQuery는 S2 인덱스를 사용하여 도형을 64비트 정수로 매핑한 다음 기존 정수 기반 클러스터링 메커니즘을 사용하여 해당 정수를 클러스터링합니다. 과거에는 고객이 BigQuery에서 S2 인덱싱 시스템을 수동으로 구현했습니다. BigQuery에서 S2를 통한 공간 클러스터링을 기본 지원하기 전까지는 이런 방식을 사용해야 했습니다. BigQuery의 네이티브 클러스터링 사용으로 성능이 크게 향상되었습니다. 자체 S2 색인을 관리할 필요가 없어져 단순성도 확보할 수 있었고요.
대체 공간 색인
공간 클러스터링은 공간 색인 시스템 또는 계층 구조를 활용하여 저장된 데이터를 정리합니다. 모든 공간 색인의 목적은 지구라고 일컫는 이 구체를 숫자로 표현하여 점, 다각형 또는 선과 같은 기하학적 객체로 위치를 정의할 수 있도록 하는 것입니다. 현재 수십 개의 공간 색인이 존재하며 대부분의 데이터베이스는 고유한 방식으로 이를 구현합니다. BigQuery는 기본적으로 클러스터링에 S2 셀을 사용하지만 H3, 지오해시 또는 쿼드키(quadkey)와 같은 다른 색인을 수동으로 구현할 수 있습니다. 아래 예시에서는 다음과 같은 공간 색인을 활용합니다.
S2: S2 시스템은 지리공간 데이터를 3차원 구체 위의 셀로 표시합니다. 이 방식은 Google 지도에서 사용됩니다.
육각형보다 효율적인 사각형을 사용합니다.
H3 또는 지오해시보다 정밀도가 높습니다.
H3: H3 시스템은 겹치는 육각형 그리드에 지리공간 데이터를 표시합니다.
육각형은 시각적으로 더 매력적입니다.
컨볼루션과 평활 알고리즘은 S2보다 더 효율적입니다.
지오해시(geohash) - 지오해시는 곡선 그리드에 지리공간 데이터를 표시하는 공개 도메인 시스템입니다.
지오해시 ID의 길이는 공간 정밀도를 결정합니다.
공간 지역성이 상당히 부족하여 클러스터링이 제대로 작동하지 않습니다.
BQ의 공간 클러스터링 — S2 및 지오해시 비교
대부분의 분석 사례에서 BigQuery에 내장된 공간 클러스터링을 사용하면 최소한의 노력으로 최고의 성능을 낼 수 있습니다. 하지만 데이터가 다른 속성에 따라 쿼리되는 경우(예: 지오해시 박스) 커스텀 색인이 필요합니다. 공간 색인을 쿼리하는 방법은 아래 예시에서 볼 수 있듯 성능에 영향을 미칩니다.
예시
먼저 경도와 위도를 임의로 지정한 포인트가 있는 테이블을 만듭니다. BigQuery 함수 st_geohash를 사용하여 각 포인트에 지오해시 ID를 생성합니다.
st_geogpoint
함수를 사용하여 경도와 위도를 변환합니다.
st_geogpoint 함수를 사용하여 경도와 위도를 GEOGRAPHY로 변환합니다. GEOGRAPHY는 BigQuery의 기본 지리공간 유형이며 색인으로 S2 셀을 사용합니다. 약 3,000포인트로 구성된 컬렉션을 선택합니다. 약 25MB가 소요될 것입니다. 클러스터링되지 않은 테이블에서 동일한 쿼리를 실행하는 경우 5.77GB(전체 테이블 크기)가 소요됩니다.
이제 지오해시 ID로 쿼리합니다. 공간 클러스터링을 활용하는 BigQuery의 기능은 BQ SAT 솔버가 데이터 클러스터의 프루닝 가능 여부를 증명할 수 있는지에 달려 있습니다. 아래 쿼리는 모두 지리공간 클러스터링을 활용하며 340MB만 소요됩니다. 'gh' 필드(즉 지오해시 ID)로 테이블을 클러스터링한다면 이러한 쿼리에는 위 쿼리와 동일하게 약 25MB가 소요됩니다.
아래 쿼리는 테이블 전체 스캔에 해당하는 5.77GB가 소요되어 효율성이 훨씬 떨어집니다. BigQuery는 클러스터의 최솟값과 최댓값을 기준으로 이 조건의 실패를 증명할 수 없으므로 전체 테이블을 스캔해야 합니다.
예시에서 볼 수 있듯 가장 비용이 적게 드는 쿼리 옵션은 쿼리 방법과 일치하는 색인을 사용하는 것입니다. 지리적으로 쿼리할 때는 네이티브 S2 색인, 지오해시로 쿼리할 때는 문자열 색인을 사용합니다. 지오해시를 사용할 땐 BigQuery가 전체 테이블을 스캔하지 않도록 left() 또는 right() 함수를 사용해서는 안 됩니다.
H3를 사용한 BQ의 공간 클러스터링
BigQuery에서 H3를 공간 색인으로 사용해야 하는 상황이 발생할 수도 있습니다. 클러스터링의 성능상 이점을 활용할 수는 있지만 지오해시와 마찬가지로 특정 패턴을 피하는 것이 중요합니다.
레벨 15에서 H3 셀 ID에 따라 색인된 지리 포인트로 이뤄진 대규모 테이블이 있다고 가정해 보겠습니다. 이는 H3_index
(참고: 이러한 함수는 BigQuery용 Carto Spatial Extension을 통해 지원됩니다)로 클러스터링한 것입니다. 저해상도 셀(예: 레벨 7)에 속하는 모든 포인트를 찾고자 하는 경우 다음과 같은 쿼리를 작성할 수 있습니다.
H3_ToParent
는 고해상도 색인에서 상위 셀 ID를 계산하는 커스텀 함수입니다. H3 색인으로 클러스터링했으므로 더 낮은 비용이 발생하리라고 예상했을 수 있지만 이 쿼리는 전체 테이블을 스캔합니다. 이러한 현상이 발생하는 이유는 H3_ToParent
가 비트 연산을 포함하고 BigQuery 쿼리 분석기로 쿼리 결과가 클러스터 경계와 연관된 방식을 파악하기에는 너무 복잡하기 때문입니다. 대신 다음 예시와 같이 지리가 색인된 수준에서 BigQuery에 H3 셀 ID 범위를 제공해야 합니다.
H3_CellRangeStart
와 H3_CellRangeEnd
는 저해상도 상위 ID를 고해상도 셀의 적절한 시작과 종료 ID에 매핑하는 커스텀 함수입니다. 이제 BigQuery는 관련 클러스터를 파악하여 비용을 줄이고 쿼리 성능을 개선할 수 있습니다.
다음 단계
공간 클러스터링은 복잡한 주제로, 구현하는 데 전문 지식이 필요합니다. BigQuery의 네이티브 공간 클러스터링을 사용하면 대부분의 작업을 쉽게 처리할 수 있습니다. BigQuery에서 지리공간 데이터를 활용하면 대규모 데이터 세트에서도 천체 쿼리와 같은 매우 높은 수준의 공간 분석까지 수행할 수 있습니다. BigQuery를 지리공간 애플리케이션의 백엔드로도 사용할 수 있습니다. 고객이 자산의 기후 위험을 탐색할 수 있는 애플리케이션이 한 예입니다. 공간 클러스터링을 사용하고 클러스터를 올바르게 쿼리하면 최저 비용으로 최고의 성능을 달성할 수 있습니다.
감사의 말: 이 게시글에 도움을 주신 에릭 엥글과 트래비스 웹에게 감사드립니다.