다음을 통해 공유


Azure Cosmos DB의 분할 및 수평적 크기 조정

적용 대상: NoSQL MongoDB Cassandra Gremlin 테이블

Azure Cosmos DB에서는 애플리케이션의 성능 요구 사항을 충족하기 위해 분할을 사용하여 데이터베이스의 개별 컨테이너 크기를 조정합니다. 컨테이너의 항목은 논리 파티션이라는 별개의 하위 집합으로 나뉩니다. 논리 파티션은 컨테이너의 각 항목과 연결된 파티션 키의 값을 기반으로 형성됩니다. 논리 파티션의 모든 항목은 동일한 파티션 키 값을 갖습니다.

예를 들어 컨테이너는 항목을 포함합니다. 각 항목에는 UserID 속성에 대한 고유한 값이 있습니다. UserID가 컨테이너에 있는 항목의 파티션 키 역할을 하고 1,000개의 고유한 UserID 값이 있다면 컨테이너에 대해 1,000개의 논리 파티션이 생성됩니다.

항목의 논리 파티션을 결정하는 파티션 키 외에도 컨테이너의 각 항목에는 논리 파티션 내에서 고유한 항목 ID가 있습니다. 파티션 키와 항목 ID를 결합하면 항목의 인덱스가 생성되며 이를 통해 항목을 고유하게 식별할 수 있습니다. 파티션 키를 선택하는 것은 애플리케이션 성능에 영향을 주는 중요한 결정입니다.

이 문서에서는 논리 파티션 및 실제 파티션 간의 관계를 설명합니다. 또한 분할에 대한 모범 사례를 설명하고 Azure Cosmos DB에서 수평적 크기 조정이 작동하는 방식에 대한 자세한 보기를 제공합니다. 파티션 키를 선택하기 위해 이러한 내부 세부 정보를 이해할 필요는 없지만 Azure Cosmos DB 작동 방식을 명확하게 이해할 수 있도록 해당 세부 정보를 다루고 있습니다.

논리 파티션

논리 파티션은 파티션 키가 동일한 항목 세트로 구성됩니다. 예를 들어 식품 영양에 대한 데이터가 포함된 컨테이너의 모든 항목에는 foodGroup 속성이 포함됩니다. foodGroup을 컨테이너에 대한 파티션 키로 사용할 수 있습니다. foodGroup에 대해 Beef Products, Baked ProductsSausages and Luncheon Meats 등의 특정 값을 갖는 항목 그룹은 고유한 논리 파티션을 형성합니다.

또한 논리 파티션은 데이터베이스 트랜잭션의 범위를 정의합니다. 스냅샷 격리가 있는 트랜잭션을 사용하여 논리 파티션 내의 항목을 업데이트할 수 있습니다. 컨테이너에 새 항목이 추가되면 시스템에서 새 논리 파티션이 투명하게 만들어집니다. 기본 데이터를 삭제하는 경우 논리 파티션 삭제에 대해 걱정할 필요는 없습니다.

컨테이너의 논리 파티션 수에는 제한이 없습니다. 각 논리적 파티션에는 최대 20GB의 데이터를 저장할 수 있습니다. 양호한 파티션 키 선택 항목에는 다양한 값을 사용할 수 있습니다. 예를 들어 모든 항목에 foodGroup 속성이 포함된 컨테이너에서 Beef Products 논리 파티션 내의 데이터는 최대 20GB까지 증가할 수 있습니다. 다양한 값을 사용할 수 있는 파티션 키를 선택하면 컨테이너 크기를 조정할 수 있습니다.

Azure Monitor 경고를 사용하여 논리 파티션 크기가 20GB에 근접하는지 모니터링할 수 있습니다.

실제 파티션

컨테이너 크기는 실제 파티션에서 데이터와 처리량을 분산시켜 조정합니다. 내부적으로 하나 이상의 논리 파티션이 하나의 실제 파티션에 매핑됩니다. 일반적으로 작은 컨테이너에는 많은 논리 파티션이 있지만 실제 파티션은 하나만 필요합니다. 논리적 파티션과 달리 물리적 파티션은 시스템의 내부 구현이며 전적으로 Azure Cosmos DB에서 관리합니다.

컨테이너의 물리적 파티션 수는 다음과 같은 특성에 따라 달라집니다.

  • 프로비전된 처리량(각 개별 실제 파티션은 초당 최대 10,000개의 요청 단위의 처리량을 제공할 수 있습니다). 실제 파티션에 대한 10,000RU/s 제한은 각 논리 파티션이 하나의 실제 파티션에만 매핑되므로 논리 파티션에도 10,000RU/s 제한이 있음을 의미합니다.

  • 총 데이터 스토리지(각 개별 물리적 파티션에는 최대 50GB의 데이터를 저장할 수 있음)

참고 항목

실제 파티션은 시스템의 내부 구현이며 완전히 Azure Cosmos DB에서 관리합니다. 솔루션을 개발할 때는 실제 파티션을 제어할 수 없으므로 실제 파티션에 집중하지 않도록 하세요. 대신, 파티션 키에 집중하세요. 논리 파티션 간에 처리량 소비를 균등하게 분산하는 파티션 키를 선택하면 실제 파티션의 처리량 소비에서 균형을 유지할 수 있습니다.

컨테이너의 충 물리적 파티션 수에는 제한이 없습니다. 프로비전된 처리량 또는 데이터 크기가 증가하면 Azure Cosmos DB는 자동으로 기존 파티션을 분할하여 새 물리적 파티션을 만듭니다. 물리적 파티션 분할은 애플리케이션의 가용성에 영향을 주지 않습니다. 실제 파티션이 분할된 후에도 단일 논리 파티션 내의 모든 데이터는 여전히 동일한 실제 파티션에 저장되어 있습니다. 실제 파티션을 분할하면 단순히 실제 파티션에 대한 논리 파티션의 새로운 매핑이 생성됩니다.

컨테이너에 대해 프로비전된 처리량은 실제 파티션 간에 균등하게 분할됩니다. 요청을 고르게 분배하지 않는 파티션 키 디자인은 너무 많은 요청을 "핫"하게 되는 파티션의 작은 하위 집합으로 보낼 수 있습니다. 핫 파티션은 프로비저닝된 처리량의 비효율적인 사용으로 이어져 속도 제한 및 비용이 증가할 수 있습니다.

예를 들어 파티션 키로 경로 /foodGroup이 지정된 컨테이너를 생각해 보겠습니다. 컨테이너에 원하는 수의 물리적 파티션을 포함할 수 있지만 이 예제에서는 세 개의 파티션이 있다고 가정합니다. 하나의 물리적 파티션에 여러 개의 파티션 키가 포함될 수 있습니다. 예를 들어, 가장 큰 물리적 파티션은 크기를 기준으로 상위 3개의 논리적 파티션(Beef Products, Vegetable and Vegetable ProductsSoups, Sauces, and Gravies)을 포함할 수 있습니다.

초당 18,000개 요청(RU/s)의 처리량을 할당하는 경우 세 개의 물리적 파티션은 각각 프로비전된 총 처리량의 1/3을 활용할 수 있습니다. 선택한 실제 파티션 내에서 논리 파티션 키, Beef Products, Vegetable and Vegetable ProductsSoups, Sauces, and Gravies는 전체적으로 실제 파티션의 초당 6,000개의 프로비전된 RU를 활용할 수 있습니다. 프로비전된 처리량은 컨테이너의 물리적 파티션 간에 균등하게 분할되므로 소비되는 처리량을 균등하게 분산하는 파티션 키를 선택하는 것이 중요합니다. 자세한 내용은 올바른 논리적 파티션 키 선택을 참조하세요.

논리 파티션 관리

Azure Cosmos DB는 컨테이너의 확장성 및 성능 요구 사항을 효율적으로 충족하기 위해 실제 파티션에 논리 파티션을 배치하는 작업을 투명하게 자동으로 관리합니다. 애플리케이션의 처리량 및 스토리지 요구 사항이 증가하면 Azure Cosmos DB는 논리 파티션을 이동하여 자동으로 부하를 많은 수의 실제 파티션에 분산합니다. 실제 파티션에 대해 자세히 알아볼 수 있습니다.

Azure Cosmos DB는 해시 기반 분할을 사용하여 논리 파티션을 실제 파티션 간에 분산합니다. Azure Cosmos DB는 항목의 파티션 키 값을 해시합니다. 해시된 결과에 따라 논리 파티션이 결정됩니다. 그런 다음, Azure Cosmos DB는 실제 파티션에 걸쳐 균등하게 파티션 키 해시의 주요 공간을 할당합니다.

저장 프로시저 또는 트리거의 트랜잭션은 단일 논리 파티션의 항목에만 허용됩니다.

복제본 세트

각 실제 파티션은 복제본 세트로도 불리는 일련의 복제본으로 구성됩니다. 각 복제본은 데이터베이스 엔진의 인스턴스를 호스팅합니다. 복제본 세트는 물리적 파티션 내의 데이터 저장소를 내구성과 가용성이 높고 일관되게 만듭니다. 실제 파티션을 구성하는 각 복제본은 파티션의 스토리지 할당량을 상속합니다. 실제 파티션의 모든 복제본은 실제 파티션에 할당된 처리량을 전체적으로 지원합니다. Azure Cosmos DB는 복제본 세트를 자동으로 관리합니다.

일반적으로 소규모 컨테이너에는 단일 물리적 파티션만 필요하지만 여전히 최소 4개의 복제본이 있습니다.

다음 이미지에서는 논리 파티션이 전역적으로 배포된 실제 파티션에 매핑되는 방법을 보여 줍니다. 이미지의 파티션 세트는 여러 지역에서 동일한 논리 파티션 키를 관리하는 실제 파티션 그룹을 나타냅니다.

Azure Cosmos DB 분할을 보여 주는 이미지

파티션 키 선택

파티션 키에는 파티션 키 경로파티션 키 값의 두 가지 구성 요소가 있습니다. 예를 들어 { "userId" : "Andrew", "worksFor": "Microsoft" } 항목이 있는데 파티션 키로 "userId"를 선택하면 다음과 같은 두 가지 파티션 키 구성 요소가 있습니다.

  • 파티션 키 경로(예: "/userId"). 파티션 키 경로에는 영숫자 및 밑줄(_) 문자가 허용됩니다. 또한 표준 경로 표기법(/)을 사용하면 중첩된 개체를 사용할 수도 있습니다.

  • 파티션 키 값(예: "Andrew"). 파티션 키 값은 문자열 또는 숫자 형식일 수 있습니다.

파티션 키의 처리량, 스토리지 및 길이에 대한 제한 사항을 자세히 알아보려면 Azure Cosmos DB 서비스 할당량 문서를 참조하세요.

Azure Cosmos DB에서 파티션 키를 선택하는 것은 간단하지만 중요한 디자인 선택 사항입니다. 파티션 키를 선택하고 나면 해당 키를 변경할 수 없습니다. 파티션 키를 변경해야 하는 경우에는 필요한 새 파티션 키를 사용하여 새 컨테이너로 데이터를 이동해야 합니다. (컨테이너 복사 작업은 이 프로세스에 도움이 됩니다.)

모든 컨테이너에 대해 파티션 키는 다음과 같아야 합니다.

  • 값이 변경되지 않는 속성이어야 합니다. 속성이 파티션 키인 경우 해당 속성의 값을 업데이트할 수 없습니다.

  • String 값만 포함해야 합니다. 또는 숫자가 IEEE 754 binary64에 따라 배정밀도 숫자의 경계를 벗어날 가능성이 있는 경우 이상적으로는 숫자를 String으로 변환해야 합니다. Json 사양은 상호 운용성 문제로 인해 일반적으로 이 경계 밖의 숫자를 사용하는 것이 좋지 않은 방법인 이유를 설명합니다. 이러한 문제는 파티션 키 열과 특히 관련이 있습니다. 파티션 키 열은 변경할 수 없고 나중에 변경하려면 데이터 마이그레이션이 필요하기 때문입니다.

  • 카디널리티가 높습니다. 즉, 속성에는 다양한 값을 사용할 수 있어야 합니다.

  • 모든 논리 파티션에 RU(요청 단위) 사용량과 데이터 스토리지를 균등하게 분산합니다. 이 분산을 통해 실제 파티션에서 균등한 RU 사용량과 스토리지 배포가 가능합니다.

  • 값은 일반적으로 2048바이트 이하이거나 큰 파티션 키가 사용되지 않은 경우 101바이트입니다. 자세한 내용은 큰 파티션 키를 참조하세요.

Azure Cosmos DB에서 다중 항목 ACID 트랜잭션이 필요한 경우에는 저장 프로시저 또는 트리거를 사용해야 합니다. 모든 JavaScript 기반 저장 프로시저와 트리거는 단일 논리 파티션으로 범위가 한정됩니다.

참고 항목

실제 파티션이 하나만 있는 경우 모든 쿼리가 동일한 실제 파티션을 대상으로 하므로 파티션 키의 값은 관련이 없을 수 있습니다.

파티션 키 유형

분할 전략 사용 시기 장점 단점
일반 파티션 키 (예: CustomerId, OrderId) - 파티션 키의 카디널리티가 높고 쿼리 패턴(예: CustomerId로 필터링)과 일치하는 경우에 사용합니다.
- 쿼리가 주로 단일 고객의 데이터를 대상으로 하는 워크로드에 적합합니다(예: 고객에 대한 모든 주문 검색).
- 관리가 간단합니다.
- 액세스 패턴이 파티션 키와 일치하는 경우 효율적인 쿼리(예: CustomerId별 모든 주문 쿼리).
- 액세스 패턴이 일관된 경우 파티션 간 쿼리를 방지합니다.
- 일부 값(예: 트래픽이 많은 고객 몇 명)이 다른 값보다 훨씬 더 많은 데이터를 생성하는 경우 핫 파티션의 위험
- 특정 키에 대한 데이터 볼륨이 빠르게 증가하는 경우 논리 파티션당 20GB 제한에 도달할 수 있습니다.
가상 파티션 키 (예: CustomerId + OrderDate) - 카디널리티가 높고 쿼리 패턴과 일치하는 단일 필드가 없을 때 사용합니다.
- 데이터가 실제 파티션에 균등하게 분산되어야 하는 쓰기 작업이 많은 워크로드에 적합합니다(예: 같은 날짜에 많은 주문이 배치됨).
- 파티션 간에 데이터를 균등하게 분산하여 핫 파티션을 줄이는 데 도움이 됩니다(예: CustomerId 및 OrderDate의 주문 분산).
- 여러 파티션에 쓰기를 분산하여 처리량을 향상합니다.
- 하나의 필드(예: CustomerId에만 해당)로만 필터링하는 쿼리는 파티션 간 쿼리를 생성할 수 있습니다.
- 파티션 간 쿼리는 더 높은 RU 사용(존재하는 모든 실제 파티션에 대해 2-3RU/s의 추가 요금)을 발생시키고 대기 시간을 추가할 수 있습니다.
HPK(계층적 파티션 키) (예: CustomerId/OrderId, StoreId/ProductId) - 대규모 데이터 세트를 지원하기 위해 다단계 분할이 필요한 경우에 사용합니다.
- 쿼리가 계층 구조의 첫 번째 및 두 번째 수준에서 필터링하는 경우에 이상적입니다.
- 여러 수준의 분할을 만들어 20GB 제한을 방지하는 데 도움이 됩니다.
- 계층 수준(예: CustomerID별 필터링, OrderID별 필터링) 둘 다에서 효율적인 쿼리
- 최상위 수준을 대상으로 하는 쿼리에 대한 파티션 간 쿼리를 최소화합니다(예: 특정 CustomerID에서 모든 데이터 검색).
- 첫 번째 수준 키의 카디널리티가 높고 대부분의 쿼리에 포함되도록 신중하게 계획해야 합니다.
- 일반 파티션 키보다 관리가 더 복잡합니다.
- 쿼리가 계층 구조에 맞지 않는 경우(예: CustomerID가 첫 번째 수준일 때 OrderID로만 필터링) 쿼리 성능이 저하됩니다.

읽기 작업이 많은 컨테이너에 대한 파티션 키

대부분의 컨테이너에서 파티션 키를 선택할 때 위의 기준만 고려하면 됩니다. 그러나 읽기 작업이 많은 컨테이너의 경우 쿼리에 필터로 자주 나타나는 파티션 키를 선택하는 것이 좋습니다. 필터 조건자에 파티션 키를 포함하여 쿼리를 관련 물리 파티션에만 효율적으로 라우팅할 수 있습니다.

대부분의 워크로드 요청이 쿼리이고 대부분의 쿼리에 동일한 속성에 대한 같음 필터가 있는 경우 이 속성은 좋은 파티션 키 선택이 될 수 있습니다. 예를 들어 UserID를 필터링하는 쿼리를 자주 실행하는 경우 UserID를 파티션 키로 선택하면 파티션 간 쿼리 수가 줄어듭니다.

그러나 컨테이너가 작은 경우 파티션 간 쿼리의 성능을 걱정해야 할 정도로 물리적 파티션이 충분하지 않을 수 있습니다. Azure Cosmos DB에서 대부분의 작은 컨테이너는 하나 또는 두 개의 실제 파티션만 필요합니다.

컨테이너가 몇 개의 실제 파티션으로 확장될 수 있는 경우 파티션 간 쿼리를 최소화하는 파티션 키를 선택해야 합니다. 다음 중 하나에 해당하는 경우 컨테이너에 몇 개 이상의 물리적 파티션이 필요합니다.

  • 컨테이너에서 30,000개 이상의 RU가 프로비저닝된 경우

  • 컨테이너가 100GB 이상의 데이터를 저장하는 경우

항목 ID를 파티션 키로 사용

참고 항목

이 섹션은 주로 API for NoSQL에 적용됩니다. API for Gremlin 등의 다른 API는 파티션 키로 고유 식별자를 지원하지 않습니다.

컨테이너에 가능한 값의 범위가 넓은 속성이 있는 경우 훌륭한 파티션 키 선택일 수 있습니다. 이러한 속성의 가능한 한 가지 예는 항목 ID입니다. 읽기 작업이 많은 작은 컨테이너 또는 크기에 관계 없이 쓰기 작업이 많은 컨테이너의 경우, 기본적으로 항목 ID(/id)는 파티션 키에 적합합니다.

컨테이너의 모든 항목에 시스템 속성 항목 ID가 있습니다. 항목의 논리적 ID를 나타내는 다른 속성이 있을 수 있습니다. 또한 대부분의 경우 이러한 ID는 항목 ID와 동일한 이유로 훌륭한 파티션 키 선택입니다.

항목 ID는 다음과 같은 이유로 적합한 파티션 키입니다.

  • 가능한 값이 광범위합니다(항목당 하나의 고유 항목 ID).
  • 항목별 고유 항목 ID가 있기 때문에 항목 ID는 RU 소비와 데이터 스토리지를 균등하게 조정하는 데 큰 역할을 합니다.
  • 항목 ID를 알고 있는 경우 항상 항목의 파티션 키를 알 수 있으므로 효율적인 시점 읽기를 쉽게 수행할 수 있습니다.

항목 ID를 파티션 키로 선택하는 경우 고려해야 할 몇 가지 사항은 다음과 같습니다.

  • 항목 ID가 파티션 키인 경우 전체 컨테이너에서 고유 식별자로 사용됩니다. 중복 항목 ID가 있는 항목은 만들 수 없습니다.
  • 물리적 파티션이 많은 읽기 작업이 많은 컨테이너가 있는 경우 항목 ID가 있는 같음 필터가 있는 경우 쿼리가 더 효율적입니다.
  • 여러 논리적 파티션을 대상으로 저장 프로시저나 트리거를 실행할 수는 없습니다.