다음을 통해 공유


Azure DocumentDB의 수평 확장성을 위한 분할

Azure DocumentDB는 데이터 및 트래픽을 가로로 분산하는 분할을 지원합니다. 컬렉션 내의 문서는 논리적 샤드라는 청크로 나뉩니다.

분할은 컬렉션의 문서 구조에서 지정된 분할 키를 사용하여 각 컬렉션에 대해 개별적으로 정의됩니다. 그런 다음 데이터는 논리 파티션에 해당하는 각 청크로 나누어집니다. 분할 키 속성의 각 고유 값에 대한 문서는 동일한 논리 분할된 데이터베이스에 상주합니다.

분할된 컬렉션에 삽입된 각 문서에 대해 분할된 데이터베이스 키 속성의 값은 지정된 논리 분할된 데이터베이스를 계산하기 위해 해시됩니다. 논리 분할된 데이터베이스를 배치하고 클러스터 내의 모든 논리 분할된 데이터베이스를 배포하는 작업은 사용자로부터 추상화되고 서비스에서 완전히 관리됩니다.

논리적 분할

분할 키에 대해 동일한 값을 포함하는 모든 문서는 동일한 논리 분할된 데이터베이스에 속합니다.

예를 들어 아래 문서 구조를 사용하여 Employees라는 컬렉션을 살펴보겠습니다.

이 표에서는 분할 키 값을 논리 파티션에 매핑하는 방법을 보여 줍니다.

문서 ID 샤드 키 값 논리적 분할
"12345" "스티브 스미스" 샤드 1
"23456" "Jane Doe" 샤드 2
"34567" "스티브 스미스" 샤드 1
"45678" "마이클 스미스" 샤드 3
"56789" "Jane Doe" 샤드 2
  • 컬렉션에 대한 논리 분할된 데이터베이스 수에는 제한이 없습니다. 컬렉션에는 각 문서의 분할 키 속성에 대한 고유한 값을 가진 문서만큼 논리적 분할된 데이터베이스가 있을 수 있습니다.

  • 단일 논리 샤드의 크기에도 제한이 없습니다.

  • 또한 서비스는 트랜잭션을 논리 샤드의 범위로 제한하지 않습니다. Azure DocumentDB는 여러 논리 분할된 데이터베이스 및 클러스터의 여러 실제 분할된 데이터베이스에서 적용할 수 있는 읽기 및 쓰기 트랜잭션을 지원합니다.

물리적 분할

기본 컴퓨터 및 디스크로 구성된 물리적 샤드들은 데이터 유지 및 데이터베이스 트랜잭션을 수행하는 역할을 담당합니다. 논리 분할된 데이터베이스와 달리 서비스는 덮개 아래에 있는 실제 분할된 데이터베이스를 관리합니다.

실제 분할된 데이터베이스 수는 클러스터를 만들 때 정의되며 시간이 지남에 따라 데이터베이스 크기가 증가하면 늘릴 수 있습니다. 단일 분할된 데이터베이스 클러스터에는 클러스터의 스토리지 및 데이터베이스 트랜잭션을 전적으로 담당하는 하나의 실제 분할된 데이터베이스(노드)가 있습니다. 다중 샤드 클러스터는 클러스터의 물리적 샤드에 데이터 및 트랜잭션 볼륨을 분산합니다.

논리 분할된 데이터베이스를 실제 분할된 데이터베이스에 매핑

새 논리 분할된 데이터베이스가 추가되면 클러스터는 논리적 분할된 데이터베이스와 실제 분할된 데이터베이스의 매핑을 원활하게 업데이트합니다. 마찬가지로, 각 실제 분할된 데이터베이스에 대한 주소 공간 할당은 새 실제 분할된 데이터베이스가 클러스터에 추가되면 변경되며, 그 후에는 논리 분할된 데이터베이스가 클러스터 전체에서 균형을 다시 조정합니다.

논리 및 물리적 분할된 데이터베이스를 매핑하는 데 사용되는 해시 범위는 클러스터의 실제 분할된 데이터베이스에 균등하게 분산됩니다. 각 물리적 분할은 해시 범위의 균등하게 크기가 조정된 버킷을 소유합니다. 작성된 모든 문서에 대해, 분할 키 속성의 값이 해시되고 그 해시 값에 따라 문서가 기본 물리적 샤드에 할당됩니다. 내부적으로 여러 논리 샤드는 단일 물리 샤드에 연결됩니다. 또한 논리 분할된 데이터베이스는 실제 분할된 데이터베이스 간에 분할되지 않으며 논리 분할된 데이터베이스에 대한 모든 문서는 하나의 실제 분할된 데이터베이스에만 매핑됩니다.

두 개의 실제 분할된 데이터베이스가 있는 클러스터를 사용하는 이전 예제에서 이 표에서는 물리적 분할된 데이터베이스에 대한 문서의 샘플 매핑을 보여 줍니다.

문서 ID 샤드 키 값 논리적 분할 물리적 샤드
"12345" "스티브 스미스" 샤드 1 물리적 분할 1
"23456" "Jane Doe" 샤드 2 물리적 분할 2
"34567" "스티브 스미스" 샤드 1 물리적 샤드 1
"45678" "마이클 스미스" 샤드 3 물리적 샤드 1
"56789" "Jane Doe" 샤드 2 물리적 샤드 2

물리적 샤드의 용량

클러스터가 프로비전될 때 선택되는 클러스터 계층은 물리적 샤드의 CPU 및 메모리 용량을 결정합니다. 마찬가지로 스토리지 SKU는 물리적 샤드의 스토리지 및 IOPS 용량을 결정합니다. 더 큰 클러스터 계층은 더 많은 컴퓨팅 성능과 더 큰 메모리를 제공하는 반면, 더 큰 스토리지 디스크는 더 많은 스토리지 및 IOPS를 제공합니다. 읽기 작업이 많은 워크로드는 더 큰 클러스터 계층의 이점을 활용하지만, 쓰기 작업이 많은 워크로드는 더 큰 스토리지 SKU의 이점을 누릴 수 있습니다. 애플리케이션의 변화하는 요구 사항에 따라 클러스터를 만든 후 클러스터 계층을 확장 및 축소할 수 있습니다.

다중 분할된 데이터베이스 클러스터에서 각 실제 분할된 데이터베이스의 용량은 동일합니다. 클러스터 계층 또는 스토리지 SKU를 확장해도 실제 샤드에 대한 논리 샤드의 배치는 변경되지 않습니다. 강화 작업 후에는 실제 분할된 데이터베이스 수가 동일하게 유지되므로 클러스터의 데이터 균형을 다시 조정할 필요가 없습니다.

실제 분할된 데이터베이스의 컴퓨팅, 메모리, 스토리지 및 IOPS 용량은 논리 분할된 데이터베이스에 사용할 수 있는 리소스를 결정합니다. 스토리지 및 요청 볼륨의 균일한 배포가 없는 분할 키는 클러스터 내에서 균일하지 않은 스토리지 및 처리량 소비를 유발할 수 있습니다. 핫 파티션으로 인해 실제 분할된 데이터베이스가 고르지 않게 활용되어 예측할 수 없는 처리량 및 성능이 발생할 수 있습니다. 따라서 분할된 클러스터는 시간이 지남에 따라 애플리케이션 요구 사항이 변경됨에 따라 성능이 일관되게 유지되도록 신중한 계획을 미리 계획해야 합니다.

레플리카 세트

각 물리적 분할은 복제 세트라고도 불리는 일련의 복제본으로 구성됩니다. 각 복제본은 데이터베이스 엔진의 인스턴스를 호스팅합니다. 복제 세트는 물리적 샤드의 데이터 저장소를 내구성 있고, 고가용성 및 데이터 일관성을 유지하는 시스템으로 만듭니다. 실제 분할된 데이터베이스를 구성하는 각 복제본은 실제 분할된 데이터베이스의 스토리지 및 컴퓨팅 용량을 상속합니다. Azure DocumentDB는 복제본 집합을 자동으로 관리합니다.

데이터 분할 모범 사례

  • 컬렉션의 스토리지와 트랜잭션 볼륨이 단일 물리적 샤드의 용량을 초과하지 않는다면 Azure DocumentDB의 샤딩은 필요 없다. 예를 들어, 이 서비스는 샤드당 32TB의 디스크 용량을 제공합니다. 컬렉션에 32TB 이상이 필요한 경우 분할해야 합니다.

  • 여러 물리적 샤드가 있는 클러스터에서 모든 컬렉션을 샤딩할 필요는 없습니다. 분할된 컬렉션과 분할되지 않은 컬렉션은 동일한 클러스터에서 공존할 수 있습니다. 이 서비스는 클러스터 내에서 컬렉션을 최적으로 분산하여 클러스터의 컴퓨팅 및 스토리지 리소스를 최대한 균등하게 활용합니다.

  • 읽기가 많은 애플리케이션의 경우 가장 빈번한 쿼리 패턴에 따라 샤드 키를 선택해야 합니다. 컬렉션에서 가장 자주 사용되는 쿼리 필터를 샤드 키로 선택하여 검색을 단일 물리 샤드로 제한함으로써 데이터베이스 트랜잭션을 최적화해야 합니다.

  • 쓰기 성능을 읽기보다 선호하는 쓰기 집중 애플리케이션의 경우, 데이터를 물리적 샤드에 균등하게 분산하기 위해 샤드 키를 선택해야 합니다. 카디널리티가 가장 높은 분할 키는 최대한 균일하게 분산할 수 있는 최고의 기회를 제공합니다.

  • 최적의 성능을 위해 논리 분할된 데이터베이스의 스토리지 크기는 4TB 미만이어야 합니다.

  • 최적의 성능을 위해 논리 분할된 데이터베이스는 클러스터의 실제 분할된 데이터베이스에 걸쳐 스토리지 및 요청 볼륨에 균등하게 분산되어야 합니다.

컬렉션을 분할하는 방법

'cosmicworks' 데이터베이스 및 'employee' 컬렉션 내에서 다음 문서를 고려합니다.

{
    "firstName": "Steve",
    "lastName": "Smith",
    "companyName": "Microsoft",
    "division": "Azure",
    "subDivision": "Data & AI",
    "timeInOrgInYears": 7
}

다음 샘플에서는 firstName 속성의 cosmicworks 데이터베이스 내에서 직원 컬렉션을 분할합니다.

use cosmicworks;
sh.shardCollection("cosmicworks.employee", {"firstName": "hashed"})

또한 관리 명령을 사용하여 컬렉션을 분할할 수 있습니다.

use cosmicworks;
db.adminCommand({
  "shardCollection": "cosmicworks.employee",
  "key": {"firstName": "hashed"}
})

스토리지 볼륨에서 컬렉션이 크게 확장된 후에 분할된 데이터베이스 키를 변경하는 것은 좋지 않지만 reshardCollection 명령을 사용하여 분할된 데이터베이스 키를 변경할 수 있습니다.

use cosmicworks;
sh.reshardCollection("cosmicworks.employee", {"lastName": "hashed"})

또한 관리 명령을 사용하여 컬렉션을 다시 분할할 수 있습니다.

use cosmicworks;
db.adminCommand({
  "reshardCollection": "cosmicworks.employee",
  "key": {"lastName": "hashed"}
})

최선의 방법으로는 분할 키 속성에 인덱스를 생성하는 것입니다.

use cosmicworks;
db.runCommand({
  createIndexes: "employee",
  indexes: [{"key":{"firstName":1}, "name":"firstName_1", "enableLargeIndexKeys": true}],
  blocking: true
})

다음 단계