데이터베이스 작업 시 최적화는 애플리케이션 성능과 효율성 측면에서 매우 중요합니다. 마찬가지로 Azure Cosmos DB에서도 최적화는 효율성을 극대화하고 비용을 최소화하며 애플리케이션이 효과적으로 확장되도록 보장하는 데 필수적입니다. 아래는 Azure Cosmos DB에서 성능을 최적화하기 위한 몇 가지 모범 사례와 코딩 예제입니다.
1. 올바른 파티션 키 선택
적절한 파티션 키를 선택하는 것은 Cosmos DB와 같은 분산 데이터베이스에 매우 중요합니다. 좋은 파티션 키는 데이터가 파티션 간에 고르게 분포되도록 하여 핫스팟을 줄이고 성능을 향상시킵니다.
파티션 키 선택은 간단하지만 Azure Cosmos DB 설계 시 매우 중요합니다.일단 우리가 파티션 키를 선택하면, 이를 제자리에서 변경하는 것은 불가능합니다.
모범 사례
- 고유 값이 많은 높은 카디널리티를 가진 파티션 키를 선택하세요.
- 읽기 및 쓰기가 고르게 분포되도록 하세요.
- 관련 데이터를 함께 유지하여 교차 파티션 쿼리를 최소화하세요.
예제: 최적의 파티션 키로 컨테이너 생성
var database = await cosmosClient.CreateDatabaseIfNotExistsAsync("YourDatabase");
var containerProperties = new ContainerProperties
{
Id = "myContainer",
PartitionKeyPath = "/customerId" // Partition key selected to ensure balanced distribution
};
// 400 RU/s 프로비저닝된 처리량으로 컨테이너 생성
var container = await database.CreateContainerIfNotExistsAsync(containerProperties, throughput: 400);
2. 적절한색인사용
Azure Cosmos DB에서는 모든 속성에 대해 기본적으로 색인이 적용되며, 이는 유익할 수 있지만 저장 및 RU/s 비용이 증가할 수 있습니다. 쿼리 성능을 향상시키고 비용을 최소화하려면 색인 정책을 사용자 정의하는 것이 좋습니다. Cosmos DB는 범위 색인, 공간 색인 및 복합 색인 세 가지 유형의 색인을 지원합니다. 적절한 유형을 현명하게 사용하십시오.
최상의 실천 방법
- 색인에서 불필요한 필드를 제외합니다.
- 다중 필드 쿼리에 대해 복합 색인을 사용합니다.
예: 사용자 지정 색인 정책
{
"indexingPolicy": {
"automatic": true,
"indexingMode": "consistent", // Can use 'none' or 'lazy' to reduce write costs
"includedPaths": [
{
"path": "/orderDate/?", // Only index specific fields like orderDate
"indexes": [
{
"kind": "Range",
"dataType": "Number"
}
]
}
],
"excludedPaths": [
{
"path": "/largeDataField/*" // Exclude large fields not used in queries
}
]
}
}
최적화된 쿼리를 위한 복합 색인 추가 예
{
"indexingPolicy": {
"compositeIndexes": [
[
{ "path": "/lastName", "order": "ascending" },
{ "path": "/firstName", "order": "ascending" }
]
]
}
}
색인 유형에 대해 더 읽어보려면 여기를 확인하십시오.
3. 쿼리 최적화
Azure Cosmos DB에서 효율적인 쿼리는 요청 단위(RU/s)를 최소화하고 성능을 향상시키는 데 중요합니다. RU/s 비용은 쿼리의 복잡성과 크기에 따라 달라집니다.
대량 실행자를 활용하면 작업 당 소비되는 RU를 줄여 비용을 더욱 절감할 수 있습니다. 이 최적화를 통해 RU 사용량을 효과적으로 관리하고 전체 Cosmos DB 비용을 낮출 수 있습니다.
모범 사례
SELECT
쿼리를 사용하십시오 제한된 양으로, 필요한 속성만 검색하십시오.- 쿼리에서 파티션 키를 제공하여 교차 파티션 쿼리를 피하십시오.
- 쿼리 비용을 줄이기 위해 인덱스 필드에 필터를 사용하십시오.
예: 고객 기록 가져오기
var query = new QueryDefinition("SELECT c.firstName, c.lastName FROM Customers c WHERE c.customerId = @customerId")
.WithParameter("@customerId", "12345");
var iterator = container.GetItemQueryIterator<Customer>(query, requestOptions: new QueryRequestOptions
{
PartitionKey = new PartitionKey("12345") // Provide partition key to avoid cross-partition query
});
while (iterator.HasMoreResults)
{
var response = await iterator.ReadNextAsync();
foreach (var customer in response)
{
Console.WriteLine($"{customer.firstName} {customer.lastName}");
}
}
4. 일관성 수준 조정
일관성 수준은 속도 관련 보장을 충족하기 위해 설계된 특정 운영 모드를 정의합니다. 다섯 가지 일관성 수준(강력, 제한된 신선도, 세션, 일관된 접두사 및 최종)가 Cosmos DB에서 사용할 수 있습니다. 각 일관성 수준은 지연 시간, 가용성 및 처리량에 영향을 미칩니다.
모범 사례
- 대부분의 시나리오에 대해 성능과 데이터 일관성을 균형 있게 유지하기 위해 세션 일관성을 사용하십시오.
- 강력한 일관성 은 데이터 일관성을 보장하지만 RU/s 및 지연 시간을 증가시킵니다.
예: 일관성 수준 설정
var cosmosClient = new CosmosClient(
"",
"",
new CosmosClientOptions
{
// 균형 잡힌 성능을 위해 일관성을 "세션"으로 설정합니다
ConsistencyLevel = ConsistencyLevel.Session
});
일관성 수준에 대해 더 알아보세요 여기에서.
5. Provisioned Throughput (RU/s)와 Auto-Scale을 현명하게 사용하세요
처리량을 프로비저닝하는 것은 Azure Cosmos DB에서 비용 효율성과 최적 성능을 달성하는 데 중요한 요소입니다. 이 서비스는 처리량을 두 가지 방식으로 구성할 수 있습니다:
- 고정 RU/s: 초당 요청 단위(Request Units) 수준이 미리 정의된 고정 수준으로, 일관된 성능 요구 사항을 갖는 워크로드에 적합합니다.
- 자동 확장: 워크로드 변동에 따라 자동으로 처리량을 조정하는 동적 옵션으로, 확장성을 제공하면서 활동이 적은 기간에 과다하게 프로비저닝을 피합니다.
적절한 처리량 모델을 선택하여 성능 요구와 비용 관리를 효과적으로 조화시킵니다.
권장사항
- 예측 가능한 워크로드의 경우 처리량을 수동으로 프로비저닝하세요.
- 예측할 수 없거나 버스트 형태의 워크로드의 경우 자동 확장을 사용하세요.
예시: 자동 확장으로 처리량 프로비저닝예시: 안정적인 워크로드에 대한 고정 RU/s 수동 설정
var throughputProperties = ThroughputProperties.CreateAutoscaleThroughput(maxThroughput: 4000); // Autoscale up to 4000 RU/s
var container = await database.CreateContainerIfNotExistsAsync(new ContainerProperties
{
Id = "autoscaleContainer",
PartitionKeyPath = "/userId"
}, throughputProperties);
var container = await database.CreateContainerIfNotExistsAsync(new ContainerProperties
{
Id = "manualThroughputContainer",
PartitionKeyPath = "/departmentId"
}, throughput: 1000); // Fixed 1000 RU/s
6. 효율적인 실시간 처리를 위한 변경 피드 활용
변경 피드는 데이터베이스의 변화를 자동으로 캡처하여 실시간 이벤트 기반 처리를 가능하게 하며, 폴링의 필요성을 없애줍니다. 이는 쿼리 오버헤드를 줄이고 효율성을 향상시킵니다.
모범 사례
- 실시간 데이터 변경 사항을 처리해야 하는 시나리오(예: 실시간 분석, 알림, 경고 등)에 변경 피드를 사용하세요.
예: 변경 피드에서 읽기
var iterator = container.GetChangeFeedIterator(
ChangeFeedStartFrom.Beginning(),
ChangeFeedMode.Incremental);
while (iterator.HasMoreResults)
{
var changes = await iterator.ReadNextAsync();
foreach (var change in changes)
{
Console.WriteLine($"Detected change: {change.Id}");
// 변경 사항 처리(예: 이벤트 트리거, 캐시 업데이트)
}
}
7. 자동 데이터 만료를 위한 TTL(Time-to-Live) 활용
로그나 세션 데이터와 같이 한정된 시간 동안만 관련 있는 데이터가 있다면, Azure Cosmos DB에서 TTL(Time-to-Live)을 활성화하여 저장 비용을 관리할 수 있습니다. TTL은 지정된 보존 기간 이후 만료된 데이터를 자동으로 삭제하여 수동 데이터 정리의 필요성을 없앱니다. 이 접근 방식은 저장된 데이터의 양을 줄일 뿐만 아니라, 구식이거나 불필요한 정보를 제거하여 데이터베이스의 비용 효율성을 최적화합니다.
모범 사례
- 저장 비용을 줄이기 위해 데이터가 자동으로 만료되어야 하는 컨테이너에 TTL을 설정하세요.
예: 만료되는 데이터에 대한 TTL 설정
{
"id": "sessionDataContainer",
"partitionKey": { "paths": ["/sessionId"] },
"defaultTtl": 3600 // 1 hour (3600 seconds)
}
코스모스 DB에서, 설정할 수 있는 최대 생존 시간(TTL) 값은 365일(1년)입니다. 이는 TTL을 구성하는 방식에 따라 데이터가 생성 또는 마지막 수정 후 1년 이내에 만료되면 자동으로 삭제될 수 있음을 의미합니다.
8. 교차 파티션 쿼리 피하기
교차 파티션 쿼리는 RU/s와 지연 시간을 크게 증가시킬 수 있습니다. 이를 피하려면:
모범 사례
- 항상 쿼리에 파티션 키를 포함하세요.
- 교차 파티션 접근을 최소화하도록 파티션 전략을 설계하세요.
예: 교차 파티션 쿼리를 피하기 위한 파티션 키로 쿼리하기
var query = new QueryDefinition("SELECT * FROM Orders o WHERE o.customerId = @customerId")
.WithParameter("@customerId", "12345");
var resultSetIterator = container.GetItemQueryIterator<Order>(query, requestOptions: new QueryRequestOptions
{
PartitionKey = new PartitionKey("12345")
});
while (resultSetIterator.HasMoreResults)
{
var response = await resultSetIterator.ReadNextAsync();
foreach (var order in response)
{
Console.WriteLine($"Order ID: {order.Id}");
}
}
결론
이 팁은 개발 중 매우 효과적입니다. 효과적인 파티셔닝 전략을 구현하고, 인덱싱 정책을 사용자 정의하고, 쿼리를 최적화하고, 일관성 수준을 조정하며, 적절한 처리량 프로비저닝 모델을 선택함으로써 Azure Cosmos DB 배포의 성능과 효율성을 크게 향상시킬 수 있습니다. 이러한 최적화는 확장성을 높일 뿐만 아니라 비용 관리에도 도움을 주면서 고성능 데이터베이스 경험을 제공합니다.
Source:
https://dzone.com/articles/optimizing-performance-in-azure-cosmos-db