Azure Cosmos DB for MongoDB vCore의 수평 스케일링을 위한 분할
Azure Cosmos DB for MongoDB vCore는 데이터와 트래픽을 수평적으로 분산하는 분할을 지원합니다. 컬렉션 내의 문서는 논리적 분할이라고 불리는 청크로 나뉩니다.
분할은 컬렉션의 문서 구조에서 지정된 분할 키를 사용하여 각 컬렉션에 대해 개별적으로 정의됩니다. 그런 다음 데이터는 청크로 버킷 구성되며 각 청크가 논리 파티션에 해당합니다. 분할 키 속성의 각 고유 값에 대한 문서는 동일한 논리적 분할에 상주합니다.
분할된 컬렉션에 삽입된 각 문서에 대해 분할 키 속성 값이 해시되어 지정된 논리적 분할을 계산합니다. 논리적 분할을 배치하고 클러스터 내의 모든 논리적 분할을 배포하는 부담을 사용자가 질 필요가 없으며 서비스에서 완전히 관리됩니다.
논리적 분할
분할 키에 대해 동일한 값을 포함하는 모든 문서는 동일한 논리적 분할에 속합니다.
예를 들어 아래 문서 구조가 있는 Employees라는 컬렉션을 살펴보겠습니다.
이 표는 분할 키 값과 논리 파티션의 매핑을 보여줍니다.
문서 ID | 분할 키 값 | 논리적 분할 |
---|---|---|
"12345" | "Steve Smith" | 분할 1 |
"23456" | "Jane Doe" | 분할 2 |
"34567" | "Steve Smith" | 분할 1 |
"45678" | "Michael Smith" | 분할 3 |
"56789" | "Jane Doe" | 분할 2 |
컬렉션의 논리적 분할 수에는 제한이 없습니다. 컬렉션에는 각 문서의 분할 키 속성에 대한 고유한 값을 가진 문서만큼의 논리적 분할이 있을 수 있습니다.
단일 논리적 분할의 크기에도 제한이 없습니다.
또한 서비스는 트랜잭션을 논리적 분할의 범위로 제한하지 않습니다. Azure Cosmos DB for MongoDB용 vCore 기반 서비스는 클러스터의 여러 논리적 분할 및 여러 물리적 분할에 적용할 수 있는 읽기 및 쓰기 트랜잭션을 지원합니다.
물리적 분할
물리적 분할은 데이터 유지 및 데이터베이스 트랜잭션 수행을 담당하는 기본 컴퓨터 및 디스크입니다. 논리적 분할과 달리 서비스가 보이지 않는 물리적 분할을 관리합니다.
물리적 분할 수는 클러스터를 만들 때 정의됩니다. 단일 분할 클러스터에는 클러스터의 스토리지 및 데이터베이스 트랜잭션을 전적으로 담당하는 하나의 물리적 분할이 있습니다. 다중 분할 클러스터는 클러스터의 물리적 분할에 데이터 및 트랜잭션 볼륨을 분산합니다.
논리적 분할을 물리적 분할에 매핑
새 논리적 분할이 추가되면 클러스터는 논리적 분할과 물리적 분할의 매핑을 원활하게 업데이트합니다. 마찬가지로 새 물리적 분할이 클러스터에 추가되면 각 물리적 분할에 대한 주소 공간 할당이 변경되며, 그 후에는 논리적 분할의 균형이 클러스터 전체에서 다시 조정됩니다.
논리적 분할과 물리적 분할을 매핑하는 데 사용되는 해시 범위는 클러스터의 물리적 분할에 균등하게 분산됩니다. 각 물리적 분할은 해시 범위의 균등하게 크기가 조정된 버킷을 소유합니다. 작성된 모든 문서에 대해 분할 키 속성의 값이 해시되고 해시 값에 따라 문서와 기본 물리적 분할의 매핑이 결정됩니다. 내부적으로 여러 논리적 분할은 단일 물리적 분할에 매핑됩니다. 또한 논리적 분할은 물리적 분할 간에 나눠지지 않으며 논리적 분할에 대한 모든 문서는 하나의 물리적 분할에만 매핑됩니다.
두 개의 물리적 분할이 있는 클러스터를 사용하는 이전 예를 기반으로 하는 이 표에서는 물리적 분할에 대한 문서 매핑 샘플을 보여줍니다.
문서 ID | 분할 키 값 | 논리적 분할 | 물리적 분할 |
---|---|---|---|
"12345" | "Steve Smith" | 분할 1 | 물리적 분할 1 |
"23456" | "Jane Doe" | 분할 2 | 물리적 분할 2 |
"34567" | "Steve Smith" | 분할 1 | 물리적 분할 1 |
"45678" | "Michael Smith" | 분할 3 | 물리적 분할 1 |
"56789" | "Jane Doe" | 분할 2 | 물리적 분할 2 |
물리적 분할의 용량
클러스터가 프로비전될 때 선택되는 클러스터 계층에 따라 물리적 분할의 CPU 및 메모리 용량이 결정됩니다. 마찬가지로 스토리지 SKU에 따라 물리적 분할의 스토리지 및 IOPS 용량이 결정됩니다. 더 큰 클러스터 계층은 더 많은 컴퓨팅 파워와 더 큰 메모리를 제공하는 한편, 더 큰 스토리지 디스크는 더 많은 스토리지 및 IOPS를 제공합니다. 읽기 작업이 많은 워크로드는 더 큰 클러스터 계층을 사용함으로써 이점을 얻을 수 있는 반면, 쓰기 작업이 많은 워크로드는 더 큰 스토리지 SKU를 사용함으로써 이점을 얻을 수 있습니다. 변화하는 애플리케이션 요구 사항에 따라 클러스터를 만든 후 클러스터 계층을 스케일 업 및 스케일 다운할 수 있습니다.
다중 분할 클러스터에서 각 물리적 분할의 용량은 동일합니다. 클러스터 계층 또는 스토리지 SKU를 스케일 업해도 물리적 분할에 대한 논리적 분할의 배치는 변경되지 않습니다. 스케일 업 작업 후에는 물리적 분할 수가 동일하게 유지되므로 클러스터의 데이터 균형을 다시 조정할 필요가 없습니다.
물리적 분할의 컴퓨팅, 메모리, 스토리지, IOPS 용량에 따라 논리적 분할에 사용할 수 있는 리소스가 결정됩니다. 스토리지 및 요청 볼륨이 균일하게 분산되지 않은 분할 키로 인해 클러스터 내에서 스토리지 및 처리량 소비가 균일하지 않을 수 있습니다. 핫 파티션으로 인해 물리적 분할이 고르지 않게 활용되어 처리량과 성능을 예측할 수 없게 될 수 있습니다. 따라서 분할된 클러스터는 시간이 지남에 따라 애플리케이션 요구 사항이 변경되어도 성능이 일관되게 유지되도록 미리 신중하게 계획해야 합니다.
복제본 세트
각 물리적 분할은 복제 세트라고도 불리는 일련의 복제본으로 구성됩니다. 각 복제본은 데이터베이스 엔진의 인스턴스를 호스팅합니다. 복제 세트는 물리적 분할 내의 데이터 저장소가 내구성, 높은 가용성, 일관성을 갖추도록 만듭니다. 물리적 분할을 구성하는 각 복제본은 물리적 분할의 스토리지 및 컴퓨팅 용량을 상속합니다. Azure Cosmos DB for MongoDB vCore는 복제 세트를 자동으로 관리합니다.
데이터 분할 모범 사례
컬렉션의 스토리지 및 트랜잭션 볼륨이 단일 물리적 분할의 용량을 초과할 수 있는 상황이 아니라면 Azure Cosmos DB for MongoDB vCore의 분할이 필요하지 않습니다. 예를 들어 서비스가 분할당 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"})
admin 명령을 사용하여 컬렉션을 분할할 수도 있습니다.
use cosmicworks;
db.adminCommand({
"shardCollection": "cosmicworks.employee",
"key": {"firstName": "hashed"}
})
컬렉션이 스토리지 볼륨에서 크게 증가한 후에 분할 키를 변경하는 것은 바람직하지 않지만, reshardCollection 명령을 사용하여 분할 키를 변경할 수 있습니다.
use cosmicworks;
sh.reshardCollection("cosmicworks.employee", {"lastName": "hashed"})
admin 명령을 사용하여 컬렉션을 다시 분할할 수도 있습니다.
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
})