다음을 통해 공유


Azure Cosmos DB Spark 커넥터 - 처리량 제어

적용 대상: NoSQL

Spark 커넥터를 사용하면 Apache Spark를 사용하여 Azure Cosmos DB와 통신할 수 있습니다. 이 문서에서는 처리량 제어 기능의 작동 방식을 설명합니다. 처리량 제어 사용을 시작하려면 GitHub의 Spark 샘플을 확인하세요.

이 문서에서는 Azure Cosmos DB Spark 커넥터에서 전역 처리량 제어 그룹의 사용을 설명하지만 이 기능은 Java SDK에서도 사용할 수 있습니다. SDK에서 전역 및 로컬 처리량 제어 그룹을 사용하여 단일 클라이언트 연결 인스턴스의 컨텍스트에서 RU(요청 단위) 사용량을 제한할 수 있습니다. 예를 들어 이 접근 방식을 단일 마이크로 서비스 내의 다른 작업에 적용하거나 단일 데이터 로드 프로그램에 적용할 수 있습니다. 자세한 내용은 Java SDK에서 처리량 제어를 사용하는 방법을 참조하세요.

Warning

처리량 제어는 게이트웨이 모드에서 지원되지 않습니다. 현재 서버리스 Azure Cosmos DB 계정의 경우 백분율을 정의하는 데 targetThroughputThreshold을(를) 사용하려고 하면 오류가 발생합니다. spark.cosmos.throughputControl.targetThroughput을(를) 사용하여 대상 처리량/RU에 대한 절대 값만 제공할 수 있습니다.

처리량 제어가 중요한 이유는?

처리량 제어는 컨테이너에 대해 실행되는 애플리케이션의 성능 요구 사항을 격리하는 데 도움이 됩니다. 처리량 제어는 특정 Spark 클라이언트에서 사용할 수 있는 RU의 양을 제한합니다.

클라이언트 측 처리량 제어를 통해 이점을 얻을 수 있는 몇 가지 고급 시나리오는 다음과 같습니다.

  • 다양한 업 및 태스크의 우선 순위는 서로 다릅니다. 데이터 수집 또는 복사 작업으로 인해 일반 트랜잭션이 제한되지 않도록 해야 할 수 있습니다. 일부 작업 또는 태스크는 대기 시간에 민감하지 않으며 다른 작업보다 제한에 더 관대합니다.
  • 다른 사용자 또는 테넌트에 공정성/격리를 제공합니다. 애플리케이션에는 일반적으로 많은 사용자가 있습니다. 일부 사용자는 너무 많은 요청을 보내서 사용 가능한 모든 처리량을 사용하고 다른 사용자가 제한을 받을 수 있습니다.
  • 다른 Azure Cosmos DB 클라이언트 간의 처리량 부하 분산 일부 사용 사례에서는 모든 클라이언트가 처리량을 공정하게(동일하게) 공유하는지 확인하는 것이 중요합니다.

처리량 제어를 통해 필요에 따라 더 세분화된 수준의 RU 속도 제한을 사용할 수 있습니다.

처리량 제어가 작동하는 방식은?

Spark 커넥터에 대한 처리량 제어를 구성하려면 먼저 처리량 제어 메타데이터를 정의하는 컨테이너를 만듭니다. 파티션 키는 groupId(이)고 ttl은(는) 사용하도록 설정되어 있습니다. 여기서는 Spark SQL을 사용하여 이 컨테이너를 만들고 ThroughputControl(이)라고 명명합니다.

    %sql
    CREATE TABLE IF NOT EXISTS cosmosCatalog.`database-v4`.ThroughputControl 
    USING cosmos.oltp
    OPTIONS(spark.cosmos.database = 'database-v4')
    TBLPROPERTIES(partitionKeyPath = '/groupId', autoScaleMaxThroughput = '4000', indexingPolicy = 'AllProperties', defaultTtlInSeconds = '-1');

앞의 예제에서는 자동 크기 조정을 사용하여 컨테이너를 만듭니다. 표준 프로비전을 선호하는 경우 autoScaleMaxThroughput을(를) manualThroughput(으)로 바꿀 수 있습니다.

Important

처리량 제어 기능이 작동하려면 파티션 키는 /groupId(으)로 정의해야 하며 ttl을(를) 사용하도록 설정해야 합니다.

특정 애플리케이션의 Spark 구성 내에서 워크로드에 대한 매개 변수를 지정할 수 있습니다. 다음 예제에서는 처리량 제어를 enabled(으)로 설정합니다. 이 예제에서는 처리량 제어 그룹 name 매개 변수 및 targetThroughputThreshold 매개 변수를 정의합니다. 처리량 제어 그룹이 유지 관리되는 databasecontainer 매개 변수도 정의합니다.

    "spark.cosmos.throughputControl.enabled" -> "true",
    "spark.cosmos.throughputControl.name" -> "SourceContainerThroughputControl",
    "spark.cosmos.throughputControl.targetThroughputThreshold" -> "0.95", 
    "spark.cosmos.throughputControl.globalControl.database" -> "database-v4", 
    "spark.cosmos.throughputControl.globalControl.container" -> "ThroughputControl"

앞의 예제에서 targetThroughputThreshold 매개 변수는 0.95로 정의되었습니다. 클라이언트가 컨테이너에 할당된 처리량의 95%(+/- 5-10%) 이상을 사용할 때 속도 제한이 발생하고 요청이 재시도됩니다. 이 구성은 다음 예제와 같이 처리량 컨테이너에 문서로 저장됩니다.

    {
        "id": "ZGF0YWJhc2UtdjQvY3VzdG9tZXIvU291cmNlQ29udGFpbmVyVGhyb3VnaHB1dENvbnRyb2w.info",
        "groupId": "database-v4/customer/SourceContainerThroughputControl.config",
        "targetThroughput": "",
        "targetThroughputThreshold": "0.95",
        "isDefault": true,
        "_rid": "EHcYAPolTiABAAAAAAAAAA==",
        "_self": "dbs/EHcYAA==/colls/EHcYAPolTiA=/docs/EHcYAPolTiABAAAAAAAAAA==/",
        "_etag": "\"2101ea83-0000-1100-0000-627503dd0000\"",
        "_attachments": "attachments/",
        "_ts": 1651835869
    }

처리량 제어는 각 작업의 RU 사전 계산을 수행하지 않습니다. 대신 응답 헤더를 기반으로 작업 RU 사용량을 추적합니다. 따라서 처리량 제어는 근사치를 기반으로 하며 특정 시간에 그룹에 사용할 수 있는 처리량의 양을 보장하지 않습니다.

이러한 이유로 구성된 RU가 너무 낮아 단일 작업에서 모두 사용할 수 있는 경우, 처리량 제어에서 RU가 구성된 제한을 초과하는 것을 방지할 수 없습니다. 처리량 제어는 구성된 제한이 특정 제어 그룹의 클라이언트가 실행할 수 있는 단일 작업보다 높은 경우에 가장 잘 작동합니다.

쿼리 또는 변경 피드를 통해 읽을 때 spark.cosmos.read.maxItemCount의 페이지 크기(기본값 1000)를 적당한 크기로 구성해야 합니다. 이러한 방식으로 클라이언트 처리량 제어를 더 높은 빈도로 다시 계산하고 특정 시간에 더 정확하게 반영할 수 있습니다. 대량을 사용하는 쓰기 작업에 처리량 제어를 사용하는 경우 단일 요청에서 실행되는 문서 수는 제한 속도에 따라 자동으로 조정되어 처리량 제어가 최대한 빨리 시작될 수 있습니다.

Warning

매개 변수 targetThroughputThreshold은(는) 변경이 불가합니다. 대상 처리량 임계값을 변경하면 새 처리량 제어 그룹이 만들어집니다. (버전 4.10.0 이상을 사용하는 경우 이름이 같을 수 있습니다.) 모두 새 임계값을 즉시 사용하려면 그룹을 사용하는 모든 Spark 작업을 다시 시작해야 합니다. 그렇지 않으면 다음에 다시 시작 후 새 임계값을 선택합니다.

처리량 제어 그룹을 사용하는 각 Spark 클라이언트에 대해 ThroughputControl 컨테이너에 몇 초의 ttl(으)로 레코드가 만들어집니다. 따라서 Spark 클라이언트가 더 이상 적극적으로 실행되지 않으면 문서가 빠르게 사라집니다. 예를 들면 다음과 같습니다.

    {
        "id": "Zhjdieidjojdook3osk3okso3ksp3ospojsp92939j3299p3oj93pjp93jsps939pkp9ks39kp9339skp",
        "groupId": "database-v4/customer/SourceContainerThroughputControl.config",
        "_etag": "\"1782728-w98999w-ww9998w9-99990000\"",
        "ttl": 10,
        "initializeTime": "2022-06-26T02:24:40.054Z",
        "loadFactor": 0.97636377638898,
        "allocatedThroughput": 484.89444487847,
        "_rid": "EHcYAPolTiABAAAAAAAAAA==",
        "_self": "dbs/EHcYAA==/colls/EHcYAPolTiA=/docs/EHcYAPolTiABAAAAAAAAAA==/",
        "_etag": "\"2101ea83-0000-1100-0000-627503dd0000\"",
        "_attachments": "attachments/",
        "_ts": 1651835869
    }

각 클라이언트 레코드에서 loadFactor 특성은 처리량 제어 그룹의 다른 클라이언트를 기준으로 특정 클라이언트의 부하를 나타냅니다. allocatedThroughput 특성은 현재 이 클라이언트에 할당된 RU 수를 보여줍니다. Spark 커넥터는 부하에 따라 각 클라이언트에 대해 할당된 처리량을 조정합니다. 이러한 방식으로 각 클라이언트는 부하에 비례하는 사용 가능한 처리량을 공유하게 됩니다. 모든 클라이언트는 속한 처리량 제어 그룹에 할당된 총량보다 더 많이 사용하지 않습니다.