Azure Cosmos DB for PostgreSQL에서 배포 열 선택
적용 대상: Azure Cosmos DB for PostgreSQL(PostgreSQL에 대한 Citus 데이터베이스 확장 기반)
각 테이블의 배포 열을 선택하는 것이 가장 중요한 모델링 결정 중 하나입니다. Azure Cosmos DB for PostgreSQL은 행의 분포 열 값을 기준으로 분할된 데이터베이스에 행을 저장합니다.
올바르게 선택할 경우, 동일한 물리적 노드에서 관련 데이터를 함께 그룹화하여 쿼리를 빠르게 만들고 모든 SQL 기능에 대한 지원을 추가합니다. 잘못된 선택을 하면 시스템이 느리게 실행됩니다.
일반 팁
분산 테이블에 이상적인 배포 열을 선택하기 위한 네 가지 기준은 다음과 같습니다.
애플리케이션 워크로드의 핵심 부분인 열을 선택합니다.
이 열을 데이터 분할을 위한 "하트", "중앙 부분" 또는 "자연 차원"이라고 생각할 수 있습니다.
예:
- IoT 워크로드의
device_id
- 증권을 추적하는 금융 앱의 경우
security_id
- 사용자 분석의
user_id
- 다중 테넌트 SaaS 애플리케이션의 경우
tenant_id
- IoT 워크로드의
적절한 카디널리티와 통계적 분포가 균일한 열을 선택합니다.
열에는 많은 값이 있어야 하며 모든 분할된 데이터베이스 간에 철저하고 균등하게 분산되어야 합니다.
예:
- 1000개 이상의 카디널리티
- 큰 비율의 행에서 동일한 값이 있는 열을 선택하지 마세요(데이터 기울이기).
- SaaS 워크로드에서 하나의 테넌트가 나머지 테넌트보다 훨씬 크면 데이터 기울이기가 발생할 수 있습니다. 이 경우 테넌트 격리를 사용하여 테넌트 처리를 위한 전용 분할된 데이터베이스를 만들 수 있습니다.
기존 쿼리에 혜택을 주는 열을 선택합니다.
트랜잭션 또는 운영 워크로드의 경우(대부분의 쿼리에 몇 밀리초밖에 걸리지 않는 경우) 쿼리의 80% 이상에 대한
WHERE
절에서 필터로 표시되는 열을 선택합니다. 예를 들어SELECT * FROM events WHERE device_id=1
의device_id
열입니다.분석 워크로드(대부분의 쿼리에 1~2초가 소요됨)의 경우 작업자 노드 간에 쿼리를 병렬화할 수 있는 열을 선택합니다. 예를 들어 GROUP BY 절에서 자주 발생하거나 한 번에 여러 값을 쿼리하는 열입니다.
대부분의 큰 테이블에 있는 열을 선택합니다.
50GB 이상의 테이블을 배포해야 합니다. 모두에 대해 동일한 배포 열을 선택하면 작업자 노드에서 해당 열에 대한 데이터를 공동 배치할 수 있습니다. 공동 위치를 사용하면 JOIN 및 롤업을 효율적으로 실행하고 외래 키를 적용할 수 있습니다.
다른(작은) 테이블은 로컬 또는 참조 테이블일 수 있습니다. 더 작은 테이블이 분산 테이블과 조인해야 하는 경우 참조 테이블로 만듭니다.
사용 사례 예제
배포 열을 선택하는 일반적인 기준을 살펴보았습니다. 이제 일반적인 사용 사례에 적용되는 방법을 살펴보겠습니다.
다중 테넌트 앱
다중 테넌트 아키텍처는 계층적 데이터베이스 모델링의 형태를 사용하여 클러스터의 노드 간에 쿼리를 분산합니다. 데이터 계층 구조의 최상위를 ‘테넌트 ID’라고 하며 각 테이블의 열에 저장해야 합니다.
Azure Cosmos DB for PostgreSQL은 쿼리를 검사하여 관련된 테넌트 ID를 확인하고 일치하는 테이블 분할된 데이터베이스를 찾습니다. 하이퍼스케일(Citus)은 분할된 데이터베이스가 포함된 단일 작업자 노드로 쿼리를 라우팅합니다. 관련된 모든 데이터를 동일한 노드에 배치하여 쿼리를 실행하는 것을 공동 배치라고 합니다.
다음 다이어그램은 다중 테넌트 데이터 모델의 공동 배치를 보여 줍니다. 각각 account_id
로 분산된 두 개의 테이블(Accounts 및 Campaigns)이 포함되어 있습니다. 음영 처리된 상자는 분할된 데이터베이스를 나타냅니다. 녹색 분할된 데이터베이스는 하나의 작업자 노드에 함께 저장되고, 파란색 분할된 데이터베이스는 다른 작업자 노드에 저장됩니다. 두 테이블 모두 동일한 account_id로 제한된 경우 Accounts 및 Campaigns 간 조인 쿼리가 어떻게 필요한 모든 데이터를 하나의 노드에서 사용할 수 있는지 확인합니다.
사용자 고유의 스키마에 이 설계를 적용하려면 애플리케이션에서 테넌트를 구성하는 요소를 식별합니다. 일반적인 인스턴스로는 회사, 계정, 조직 또는 고객이 있습니다. 열 이름은 company_id
또는 customer_id
와 같습니다. 각 쿼리를 검사하고 동일한 테넌트 ID를 가진 행과 관련된 모든 테이블을 제한하는 추가 WHERE 절이 있는 경우에도 작동하는지 자문합니다. 다중 테넌트 모델의 쿼리 범위는 테넌트로 지정됩니다. 예를 들어 판매 또는 인벤토리 쿼리는 특정 매장 내에서 범위가 지정됩니다.
모범 사례
- 공통 tenant_id 열을 기준으로 테이블을 분산합니다. 예를 들어 테넌트가 회사인 SaaS 애플리케이션에서 tenant_id는 company_id일 가능성이 높습니다.
- 작은 교차 테넌트 테이블을 참조 테이블로 변환합니다. 여러 테넌트가 작은 정보 테이블을 공유하는 경우 참조 테이블로 배포합니다.
- 모든 애플리케이션 쿼리를 tenant_id로 필터링하도록 제한합니다. 각 쿼리는 한 번에 하나의 테넌트에 대한 정보를 요청해야 합니다.
이 종류의 애플리케이션을 빌드하는 방법의 예제는 다중 테넌트 자습서를 참조하세요.
실시간 앱
다중 테넌트 아키텍처는 계층 구조를 도입하고 데이터 공동 배치를 사용하여 테넌트별 쿼리를 라우팅합니다. 반면, 실시간 아키텍처는 뛰어난 병렬 처리를 위해 데이터의 특정 배포 속성에 따라 달라집니다.
실시간 모델에서는 배포 열의 조건으로 “엔터티 ID”를 사용합니다. 일반적인 엔터티는 사용자, 호스트 또는 디바이스입니다.
실시간 쿼리는 일반적으로 날짜 또는 범주별로 그룹화된 숫자 집계를 요청합니다. Azure Cosmos DB for PostgreSQL은 부분 결과를 위해 해당 쿼리를 각 분할된 데이터베이스로 전송하고 코디네이터 노드에서 최종 답변을 어셈블합니다. 가능한 한 많은 노드가 참여할 때, 그리고 과도하게 많은 작업을 수행해야 하는 단일 노드가 없을 때 쿼리가 가장 빠르게 실행됩니다.
모범 사례
- 카디널리티가 높은 열을 배포 열로 선택합니다. 상대적으로 New, Paid, Shipped 값을 포함하는 주문 테이블의 상태 필드는 배포 열로 선택하기에 적합하지 않습니다. 몇 개의 값만 사용되므로 데이터를 보관할 수 있는 분할된 데이터베이스 수와 처리할 수 있는 노드 수가 제한됩니다. 카디널리티가 높은 열 중에서 group-by 절에서 또는 조인 키로 자주 사용되는 열을 선택하는 것도 좋습니다.
- 균등 분포된 열을 선택합니다. 특정 공통 값에 편향된 열을 기준으로 테이블을 배포하는 경우 테이블의 데이터가 특정 분할된 데이터베이스에 누적되는 경향이 있습니다. 해당 분할된 데이터베이스를 보관하는 노드는 다른 노드보다 더 많은 작업을 수행하게 됩니다.
- 공통 열을 기준으로 팩트 및 차원 테이블을 배포합니다. 팩트 테이블에는 배포 키가 하나만 포함될 수 있습니다. 다른 키로 조인되는 테이블은 팩트 테이블과 공동 배치되지 않습니다. 조인 빈도와 조인되는 행의 크기에 따라 공동 배치할 차원을 하나 선택합니다.
- 일부 차원 테이블을 참조 테이블로 변경합니다. 팩트 테이블과 차원 테이블을 공동 배치할 수 없는 경우 차원 테이블의 복사본을 참조 테이블 형태로 모든 노드에 배포하여 쿼리 성능을 향상시킬 수 있습니다.
이 종류의 애플리케이션을 빌드하는 방법의 예제는 실시간 대시보드 자습서를 참조하세요.
시계열 데이터
시계열 워크로드에서 애플리케이션은 이전 정보를 보관하는 동시에 최근 정보를 쿼리합니다.
Azure Cosmos DB for PostgreSQL에서 시계열 정보를 모델링할 때 가장 일반적인 실수는 타임스탬프 자체를 배포 열로 사용하는 것입니다. 시간 기반의 해시 배포는 시간 범위를 분할된 데이터베이스에 함께 유지하는 대신 다양한 분할된 데이터베이스에 시간을 임의로 배포하는 것처럼 보입니다. 시간과 관련된 쿼리는 일반적으로 가장 최근 데이터와 같은 시간 범위를 참조합니다. 이 유형의 해시 배포는 네트워크 오버헤드를 초래합니다.
모범 사례
- 타임스탬프를 배포 열로 선택하지 않습니다. 다른 배포 열을 선택합니다. 다중 테넌트 앱에서 테넌트 ID를 사용하거나 실시간 앱에서 엔터티 ID를 사용합니다.
- PostgreSQL 테이블 분할을 시간에 사용합니다. 테이블 분할을 사용하여 시간순으로 정렬된 큰 데이터 테이블을 각 테이블에 서로 다른 시간 범위가 포함된 여러 개의 상속된 테이블로 나눌 수 있습니다. Postgres 분할 테이블을 배포하면 상속된 테이블을 위한 분할된 데이터베이스가 생성됩니다.