다음을 통해 공유


Azure Synapse Analytics용 Spark Common Data Model 커넥터

Spark CDM 커넥터(Spark Common Data Model 커넥터)는 Azure Synapse Analytics의 형식 판독기/기록기입니다. 이를 사용하여 Spark 프로그램은 Spark DataFrames를 통해 Common Data Model 폴더에 있는 Common Data Model 엔터티를 읽고 쓸 수 있습니다.

Common Data Model 1.2를 사용하여 Common Data Model 문서를 정의하는 방법에 대한 자세한 내용은 Common Data Model의 정의 및 사용 방법에 대한 이 문서를 참조하세요.

기능

개괄적으로 커넥터는 다음을 지원합니다.

  • 3.1, 3.2 및 3.3.
  • Common Data Model 폴더의 엔터티에 들어 있는 데이터를 Spark 데이터 프레임으로 읽기
  • Common Data Model 엔터티 정의를 기반으로 Spark DataFrame에서 Common Data Model 폴더의 엔터티에 쓰기
  • Spark DataFrame에서 DataFrame 스키마를 기반으로 Common Data Model 폴더의 엔터티에 쓰기

또한 이 커넥터는 다음을 지원합니다.

  • HNS(계층 구조 네임스페이스)를 사용하도록 설정된 Azure Data Lake Storage의 Common Data Model 폴더를 읽고 읽습니다.
  • manifest 또는 model.json 파일에서 설명하는 Common Data Model 폴더에서 읽습니다.
  • 매니페스트 파일에서 설명하는 Common Data Model 폴더에 쓰기
  • 열 머리글을 사용하거나 사용하지 않는 또는 사용자가 선택할 수 있는 구분 기호 문자를 사용하는 CSV 형식의 데이터
  • 중첩된 Parquet를 포함하여 Apache Parquet 형식의 데이터
  • 읽기 시 하위 매니페스트, 쓰기 시 엔터티 범위 하위 매니페스트의 선택적 사용
  • 사용자가 수정할 수 있는 파티션 패턴을 통해 데이터 쓰기
  • Azure Synapse Analytics에서 관리 ID 및 자격 증명 사용
  • config.json 파일에 설명된 Common Data Model 어댑터 정의를 통해 가져오기에 사용되는 Common Data Model 별칭 위치를 확인합니다.

제한 사항

커넥터는 다음 기능 및 시나리오를 지원하지 않습니다.

  • 병렬 쓰기 이 구성은 권장되지 않습니다. 스토리지 계층에는 잠금 메커니즘이 없습니다.
  • 엔터티를 읽은 후 엔터티 메타데이터에 프로그래밍 방식으로 액세스합니다.
  • 엔터티를 기록할 때 프로그래밍 방식으로 액세스하여 메타데이터를 설정하거나 재정의합니다.
  • 스키마 드리프트 - 기록되는 데이터 프레임의 데이터에 엔터티 정의에 없는 추가 특성이 포함됩니다.
  • 스키마 진화 - 엔터티 파티션이 다른 버전의 엔터티 정의를 참조합니다. com.microsoft.cdm.BuildInfo.version을 실행하여 버전을 확인할 수 있습니다.
  • model.json에 대한 지원을 기록합니다.
  • Parquet에 Time 데이터를 씁니다. 현재 커넥터는 CSV 파일의 DateTime 값이 아닌 Common Data Model Time 값으로 해석되도록 타임스탬프 열 재정의를 지원합니다.
  • Parquet Map 형식, 기본 형식의 배열, 배열 형식의 배열입니다. Common Data Model은 현재 지원하지 않으므로 Spark CDM 커넥터도 지원하지 않습니다.

샘플

커넥터 사용을 시작하려면 샘플 코드 및 공통 데이터 모델 파일을 확인합니다.

데이터 읽기

커넥터에서 데이터를 읽을 때 Common Data Model 폴더의 메타데이터를 사용하여 매니페스트에서 참조된 대로 지정된 엔터티에 대해 확인된 엔터티 정의를 기반으로 데이터 프레임을 만듭니다. 커넥터는 엔터티 특성 이름을 DataFrame 열 이름으로 사용합니다. 특성 데이터 형식을 열 데이터 형식에 매핑합니다. 데이터 프레임이 로드되면 데이터 프레임은 매니페스트에서 식별된 엔터티 파티션에서 채워집니다.

커넥터는 지정된 매니페스트 및 첫 번째 수준 하위 매니페스트에서 지정된 엔터티를 찾습니다. 필요한 엔터티가 두 번째 수준 이하의 하위 매니페스트에 있거나 이름이 같은 여러 엔터티가 서로 다른 하위 매니페스트에 있는 경우 사용자는 루트 매니페스트가 아닌 필수 엔터티가 포함된 하위 매니페스트 엔터티를 지정해야 합니다.

엔터티 파티션은 형식이 혼합되어 있을 수 있습니다(예: CSV 및 Parquet). 매니페스트에서 식별된 모든 엔터티 데이터 파일은 형식에 관계없이 하나의 데이터 세트로 결합되고 데이터 프레임에 로드됩니다.

커넥터는 CSV 데이터를 읽을 때 기본적으로 Spark failfast 옵션을 사용합니다. 열 수가 엔터티의 특성 수와 같지 않으면 커넥터는 오류를 반환합니다.

또는 0.19를 기준으로 커넥터는 허용 모드(CSV 파일에만 해당)를 지원합니다. 허용 모드를 사용하는 경우 CSV 행의 열 수가 엔터티 스키마보다 적으면 커넥터에서 누락된 열에 대해 null 값을 할당합니다. CSV 행의 열 수가 엔터티 스키마보다 많으면 엔터티 스키마 열 수를 초과하는 열이 스키마 열 수로 잘립니다. 사용법은 다음과 같습니다.

.option("mode", "permissive") or .option("mode", "failfast")

데이터 쓰기

커넥터가 Common Data Model 폴더에 쓸 때 엔터티가 해당 폴더에 아직 없는 경우 커넥터는 새 엔터티 및 정의를 만듭니다. 엔터티 및 정의를 Common Data Model 폴더에 추가하고 매니페스트에서 참조합니다.

커넥터는 다음 두 가지 쓰기 모드를 지원합니다.

  • 명시적 쓰기: 물리적 엔터티 정의는 사용자가 지정한 논리적 Common Data Model 엔터티 정의를 기반으로 합니다.

    커넥터는 지정된 논리 엔터티 정의를 읽고 확인하여 Common Data Model 폴더에 사용되는 물리적 엔터티 정의를 만듭니다. 직접 또는 간접적으로 참조되는 Common Data Model 정의 파일의 import 문에 별칭이 포함된 경우 이러한 별칭을 Common Data Model 어댑터 및 스토리지 위치에 매핑하는 config.json 파일을 제공해야 합니다.

    • DataFrame 스키마가 참조된 엔터티 정의와 일치하지 않으면 커넥터에서 오류를 반환합니다. Common Data Model의 특성을 통한 소수점 데이터, 정밀도, 확장 집합을 포함하여 데이터 프레임의 열 데이터 형식이 엔터티의 특성 데이터 형식과 일치하는지 확인합니다.
    • DataFrame이 엔터티 정의와 일치하지 않으면 커넥터에서 오류를 반환합니다.
    • 데이터 프레임이 일치하는 경우:
      • 매니페스트에 엔터티가 이미 있는 경우 커넥터는 제공된 엔터티 정의를 확인하고 Common Data Model 폴더의 정의에 대해 유효성을 검사합니다. 정의가 일치하지 않으면 커넥터에서 오류를 반환합니다. 그렇지 않으면 커넥터가 데이터를 쓰고 매니페스트의 파티션 정보를 업데이트합니다.
      • 엔터티가 Common Data Model 폴더에 없는 경우 커넥터는 확인된 엔터티 정의 복사본을 Common Data Model 폴더의 매니페스트에 씁니다. 커넥터는 데이터를 쓰고 매니페스트의 파티션 정보를 업데이트합니다.
  • 암시적 쓰기: 엔터티 정의가 데이터 프레임 구조에서 파생됩니다.

    • 엔터티가 Common Data Model 폴더에 없는 경우 커넥터는 암시적 정의를 사용하여 대상 Common Data Model 폴더에 확인된 엔터티 정의를 만듭니다.

    • 엔터티가 Common Data Model 폴더에 있으면 기존 엔터티 정의에 대해 암시적 정의 유효성을 검사합니다. 정의가 일치하지 않으면 커넥터에서 오류를 반환합니다. 그렇지 않으면 커넥터는 데이터를 쓰고 파생 논리 엔터티 정의를 엔터티 폴더의 하위 폴더에 씁니다.

      커넥터는 엔터티 하위 폴더 내의 데이터 폴더에 데이터를 씁니다. 저장 모드는 새 데이터를 덮어쓸지 아니면 기존 데이터에 추가할지, 또는 데이터가 있는 경우 오류가 반환되는지 여부를 결정합니다. 데이터가 이미 있는 경우 오류를 반환하는 것이 기본값입니다.

Common Data Model 별칭 통합

Common Data Model 정의 파일은 import 문에서 별칭을 사용하여 import 문을 간소화하고 가져온 콘텐츠의 위치가 런타임 시 늦게 바인딩되는 것을 허용합니다. 별칭 사용:

  • 관련 Common Data Model 정의를 여러 위치에서 함께 그룹화할 수 있도록 Common Data Model 파일을 쉽게 구성할 수 있습니다.
  • 런타임에 배포된 여러 위치에서 Common Data Model 콘텐츠에 액세스할 수 있습니다.

다음 코드 조각은 Common Data Model 정의 파일의 import 문에 별칭을 사용하는 방법을 보여 줍니다.

"imports": [  
{     
  "corpusPath": "cdm:/foundations.cdm.json"
},  
{       
  "corpusPath": "core:/TrackedEntity.cdm.json"  
},  
{      
  "corpusPath": "Customer.cdm.json"  
} 
]

앞의 예제에서는 cdm을 Common Data Model 파운데이션 파일의 위치에 대한 별칭으로 사용합니다. 정의 파일의 TrackedEntity 위치에 대한 별칭으로 core를 사용합니다.

별칭은 Common Data Model config.json 파일의 어댑터 항목에 있는 네임스페이스 값과 일치하는 텍스트 레이블입니다. 어댑터 항목은 어댑터 유형(예: adls, CDN, GitHub 또는 local) 및 위치를 정의하는 URL을 지정합니다. 일부 어댑터는 연결 시간 제한과 같은 다른 구성 옵션을 지원합니다. 별칭은 임의의 텍스트 레이블이지만, cdm 별칭은 특별한 방식으로 처리됩니다.

Spark Common Data Model 커넥터는 엔터티 정의 모델 루트 위치에서 로드할 config.json 파일을 찾습니다. config.json 파일이 다른 위치에 있거나 모델 루트에서 config.json 파일을 재정의하려는 경우 사용자는 configPath 옵션을 사용하여 config.json 파일의 위치를 제공하면 됩니다. config.json 파일에는 확인 중인 Common Data Model 코드에 사용된 모든 별칭에 대한 어댑터 항목이 포함되어야 합니다. 그렇지 않으면 커넥터에서 오류를 보고합니다.

config.json 파일을 재정의하는 기능은 Common Data Model 정의에 런타임에 액세스할 수 있는 위치를 제공할 수 있음을 의미합니다. 런타임 시 참조되는 콘텐츠가 Common Data Model을 처음 작성했을 때 사용된 정의와 일치하는지 확인합니다.

규칙에 따라 cdm 별칭은 foundations.Common Data Model.json 파일을 포함하여 루트 수준 표준 Common Data Model 정의의 위치를 나타냅니다. 이 파일에는 Common Data Model 기본 데이터 형식과 대부분의 Common Data Model 엔터티 정의에 필요한 핵심 특성 정의 집합이 포함되어 있습니다.

cdm 별칭은 다른 별칭처럼 config.json 파일의 어댑터 항목을 사용하여 확인할 수 있습니다. 어댑터를 지정하지 않거나 null 항목을 제공하는 경우 cdm 별칭은 기본적으로 https://cdm-schema.microsoft.com/logical/에서 Common Data Model 공용 CDN(콘텐츠 배달 네트워크)으로 확인됩니다.

cdmSource 옵션을 사용하여 cdm 별칭을 확인하는 방법을 재정의할 수도 있습니다. cdm 별칭이 Common Data Model 정의에 사용되는 유일한 별칭인 경우 cdmSource 옵션을 사용하면 config.json 파일을 만들거나 참조할 필요가 없으므로 유용합니다.

매개 변수, 옵션, 저장 모드

읽기 및 쓰기 모두에 대해 Spark Common Data Model 커넥터의 라이브러리 이름을 매개 변수로 제공합니다. 옵션 세트를 사용하여 커넥터의 동작을 매개 변수화합니다. 쓸 때 커넥터는 저장 모드도 지원합니다.

커넥터 라이브러리 이름, 옵션, 저장 모드의 형식은 다음과 같습니다.

  • dataframe.read.format("com.microsoft.cdm") [.option("option", "value")]*
  • dataframe.write.format("com.microsoft.cdm") [.option("option", "value")]* .mode(savemode.\<saveMode\>)

다음은 읽기에 커넥터를 사용하는 몇 가지 옵션을 보여 주는 예제입니다.

val readDf = spark.read.format("com.microsoft.cdm")
  .option("storage", "mystorageaccount.dfs.core.windows.net")
  .option("manifestPath", "customerleads/default.manifest.cdm.json")
  .option("entity", "Customer")
  .load()

일반적인 읽기 및 쓰기 옵션

다음 옵션은 읽거나 쓰는 Common Data Model 폴더의 엔터티를 식별합니다.

옵션 설명 패턴 및 사용 예제
storage Common Data Model 폴더를 포함하는 HNS를 사용하도록 설정된 Azure Data Lake Storage 계정의 엔드포인트 URL입니다.
dfs.core.windows.net URL을 사용합니다.
<accountName>.dfs.core.windows.net "myAccount.dfs.core.windows.net"
manifestPath 스토리지 계정의 manifest 또는 model.json 파일에 대한 상대 경로입니다. 읽기의 경우 루트 매니페스트, 하위 매니페스트 또는 model.json입니다. 쓰기의 경우 반드시 루트 매니페스트여야 합니다. <container>/{<folderPath>}<manifestFileName>,
"mycontainer/default.manifest.cdm.json" "models/hr/employees.manifest.cdm.json"
"models/hr/employees/model.json"(읽기 전용)
entity 매니페스트에 있는 원본 또는 대상 엔터티의 이름입니다. 폴더에 처음으로 엔터티를 기록할 때 커넥터는 확인된 엔터티 정의에 이 이름을 지정합니다. 엔터티 이름은 대/소문자를 구분합니다. <entityName>
"customer"
maxCDMThreads 커넥터에서 엔터티 정의를 확인하는 동안 최대 동시 읽기 수입니다. 유효한 정수(예: 5)

참고 항목

읽기 시 Common Data Model 폴더의 물리적 엔터티 정의 외에 논리 엔터티 정의를 더 이상 지정할 필요가 없습니다.

명시적 쓰기 옵션

다음 옵션은 기록되는 엔터티에 대한 논리적 엔터티 정의를 식별합니다. 논리 엔터티 정의는 엔터티를 기록하는 방법을 정의하는 물리적 정의로 확인됩니다.

옵션 설명 패턴 또는 사용 예제
entityDefinitionStorage 엔터티 정의를 포함하는 Azure Data Lake Storage 계정입니다. Common Data Model 폴더를 호스트하는 스토리지 계정과 다른 경우 필요합니다. <accountName>.dfs.core.windows.net
"myAccount.dfs.core.windows.net"
entityDefinitionModelRoot 계정 내에서 모델 루트 또는 모음의 위치입니다. <container>/<folderPath>
"crm/core"
entityDefinitionPath 엔터티의 위치입니다. 해당 파일의 엔터티 이름을 포함하여 모델 루트를 기준으로 Common Data Model 정의 파일의 파일 경로입니다. <folderPath>/<entityName>.cdm.json/<entityName>
"sales/customer.cdm.json/customer"
configPath 엔터티 정의 파일에 포함된 모든 별칭 및 직접 또는 간접적으로 참조되는 Common Data Model 파일에 대한 어댑터 구성을 포함하는 config.json 파일의 컨테이너 및 폴더 경로입니다.

config.json이 모델 루트 폴더에 있는 경우에는 이 옵션이 필요하지 않습니다.
<container><folderPath>
useCdmStandardModelRoot 모델 루트가 https://cdm-schema.microsoft.com/CDM/logical/에 있음을 나타냅니다. Common Data Model CDN에 정의된 엔터티 형식을 참조하는 데 사용됩니다. entityDefinitionStorageentityDefinitionModelRoot를 재정의합니다(지정된 경우).
"useCdmStandardModelRoot"
cdmSource cdm 별칭(Common Data Model 정의 파일에 있는 경우)이 확인되는 방법을 정의합니다. 이 옵션을 사용하면 config.json 파일에 지정된 cdm 어댑터가 재정의됩니다. 값은 builtin 또는 referenced입니다. 기본값은 referenced입니다.

이 옵션을 referenced로 설정하면 커넥터는 https://cdm-schema.microsoft.com/logical/에 가장 최근에 게시된 표준 Common Data Model 정의를 사용합니다. 이 옵션을 builtin으로 설정하면 커넥터는 커넥터에서 사용 중인 Common Data Model 개체 모델에 기본 제공되는 Common Data Model 기본 정의를 사용합니다.

참고:
* Spark Common Data Model 커넥터가 최신 Common Data Model SDK를 사용하지 않을 수 있으므로 게시된 최신 표준 정의가 포함되지 않을 수 있습니다.
* 기본 제공 정의에는 foundations.Common Data Model.json 또는 primitives.Common Data Model.json과 같은 최상위 Common Data Model 콘텐츠만 포함됩니다. 하위 수준 표준 Common Data Model 정의를 사용하려면 referenced를 사용하거나 config.jsoncdm 어댑터를 포함합니다.
"builtin"|"referenced"

앞의 예제에서 고객 엔터티 정의 개체의 전체 경로는 https://myAccount.dfs.core.windows.net/models/crm/core/sales/customer.cdm.json/customer입니다. 해당 경로에서 모델은 Azure Data Lake Storage의 컨테이너입니다.

암시적 쓰기 옵션

기록 시 논리적 엔터티 정의를 지정하지 않은 경우 데이터 프레임 스키마에 따라 엔터티가 암시적으로 기록됩니다.

암시적으로 기록하는 경우 타임스탬프 열은 일반적으로 Common Data Model DateTime 데이터 형식으로 해석됩니다. 이 해석을 재정의하여 데이터 형식을 지정하는 열과 연결된 메타데이터 개체를 제공함으로써 Common Data Model Time 데이터 형식의 특성을 만들 수 있습니다. 자세한 내용은 이 문서의 뒷부분에 있는 Common Data Model 시간 데이터 처리를 참조하세요.

시간 데이터 쓰기는 CSV 파일에서만 지원합니다. 해당 지원은 현재 Parquet으로 확장되지 않습니다.

폴더 구조 및 데이터 형식 옵션

다음 옵션을 사용하여 폴더 구성 및 파일 형식을 변경할 수 있습니다.

옵션 설명 패턴 또는 사용 예제
useSubManifest true이면 하위 매니페스트를 통해 대상 엔터티가 루트 매니페스트에 포함됩니다. 하위 매니페스트 및 엔터티 정의는 루트 아래의 엔터티 폴더에 기록됩니다. 기본값은 false입니다. "true"|"false"
format 파일 형식을 정의합니다. 현재 지원되는 파일 형식은 CSV 및 Parquet입니다. 기본값은 csv입니다. "csv"|"parquet"
delimiter CSV에만 해당합니다. 사용 중인 구분 기호를 정의합니다. 기본값은 쉼표입니다. "|"
columnHeaders CSV에만 해당합니다. true이면 열 머리글이 있는 데이터 파일에 첫 번째 행을 추가합니다. 기본값은 true입니다. "true"|"false"
compression 쓰기에만 해당합니다. Parquet에만 해당합니다. 사용 중인 압축 형식을 정의합니다. 기본값은 snappy입니다. "uncompressed" | "snappy" | "gzip" | "lzo"
dataFolderFormat 엔터티 폴더 내에서 사용자 정의 가능한 데이터 폴더 구조를 허용합니다. DateTimeFormatter 서식을 사용하여 날짜 및 시간 값을 폴더 이름으로 대체할 수 있습니다. 포맷터가 아닌 콘텐츠는 작은따옴표로 묶어야 합니다. 기본 형식은 "yyyy"-"MM"-"dd"로, 2020-07-30과 같은 폴더 이름을 생성합니다. year "yyyy" / month "MM"
"Data"

Save mode

저장 모드는 DataFrame을 작성할 때 커넥터가 Common Data Model 폴더의 기존 엔터티 데이터를 처리하는 방법을 지정합니다. 데이터가 이미 있는 경우 데이터를 덮어쓰거나, 추가하거나, 오류를 반환할 수 있습니다. 기본 저장 모드는 ErrorIfExists입니다.

모드 설명
SaveMode.Overwrite 기존 엔터티 정의가 변경된 경우 기존 엔터티 정의를 덮어쓰고 기존 데이터 파티션을 작성 중인 데이터 파티션으로 바꿉니다.
SaveMode.Append 기존 파티션과 함께 기록되는 데이터를 새 파티션에 추가합니다.

이 모드는 스키마 변경을 지원하지 않습니다. 작성 중인 데이터의 스키마가 기존 엔터티 정의와 호환되지 않으면 커넥터에서 오류가 발생합니다.
SaveMode.ErrorIfExists 파티션이 이미 있는 경우 오류가 반환됩니다.

쓰기 시 데이터 파일의 이름을 지정하고 구성하는 방법에 대한 자세한 내용은 이 문서의 뒷부분에 있는 폴더 및 파일 이름 지정 및 조직 섹션을 참조하세요.

인증

Spark CDM 커넥터에서 세 가지 인증 모드(자격 증명 통과, SAS(공유 액세스 서명) 토큰, 앱 등록)를 사용하여 Common Data Model 메타데이터 및 데이터 파티션을 읽거나 쓸 수 있습니다.

자격 증명 통과

Azure Synapse Analytics에서 Spark CDM 커넥터는 Azure 리소스에 대한 관리 ID를 사용하여 Common Data Model 폴더가 포함된 Azure Data Lake Storage 계정에 대한 액세스를 중재하도록 지원합니다. 관리 ID는 모든 Azure Synapse Analytics 작업 영역마다 자동으로 만들어집니다. 커넥터는 커넥터가 호출된 Notebook이 포함된 작업 영역의 관리 ID를 사용하여 스토리지 계정을 인증합니다.

선택한 ID가 적절한 스토리지 계정에 액세스할 수 있는지 확인해야 합니다.

  • 라이브러리가 Common Data Model 폴더에 쓸 수 있도록 Storage Blob 데이터 기여자 권한을 부여합니다.
  • 읽기 권한만 허용하도록 Storage Blob 데이터 읽기 권한자 권한을 부여합니다.

두 경우 모두 추가 커넥터 옵션이 필요하지 않습니다.

SAS 토큰 기반 액세스 제어 옵션

SAS 토큰 자격 증명은 스토리지 계정 인증을 위한 추가 옵션입니다. SAS 토큰 인증을 사용하면 SAS 토큰이 컨테이너 또는 폴더 수준에 있을 수 있습니다. 적절한 권한이 필요합니다.

  • 매니페스트 또는 파티션에 대한 읽기 권한은 읽기 수준 지원만 필요합니다.
  • 쓰기 권한에는 읽기 및 쓰기 지원이 모두 필요합니다.
옵션 설명 패턴 및 사용 예제
sasToken 올바른 권한으로 상대 스토리지 계정에 액세스하기 위한 SAS 토큰 <token>

자격 증명 기반 액세스 제어 옵션

관리 ID 또는 사용자 ID를 사용하는 대신 명시적 자격 증명을 제공하면 Spark Common Data Model 커넥터가 데이터에 액세스할 수 있습니다. Microsoft Entra ID에서 앱 등록을 만듭니다. 그런 다음, 다음 역할 중 하나를 사용하여 스토리지 계정에 이 앱 등록 액세스 권한을 부여합니다.

  • 라이브러리가 Common Data Model 폴더에 쓸 수 있도록 하는 Storage Blob 데이터 기여자
  • 읽기 권한만 허용하는 Storage Blob 데이터 읽기 권한자

사용 권한이 만들어지면 다음 옵션을 사용하여 각 호출에서 커넥터에 앱 ID, 앱 키, 테넌트 ID를 전달할 수 있습니다. 이러한 값이 Notebook 파일에 명확한 텍스트로 저장되지 않도록 Azure Key Vault를 사용하여 이러한 값을 보호하는 것이 좋습니다.

옵션 설명 패턴 및 사용 예제
appId 스토리지 계정 인증에 사용되는 앱 등록 ID <guid>
appKey 등록된 앱 키 또는 비밀 <encrypted secret>
tenantId 앱이 등록된 Microsoft Entra 테넌트 ID <guid>

예제

다음 예제에서는 모두 appId, appKey, tenantId 변수를 사용합니다. 코드의 앞부분에서 Azure 앱 등록(쓰기의 경우 스토리지에 대한 Storage Blob 데이터 기여자 권한, 읽기의 경우 Storage Blob 데이터 읽기 권한자 권한)을 기반으로 이러한 변수를 초기화했습니다.

읽음

이 코드는 mystorage.dfs.core.windows.net/cdmdata/contacts/root.manifest.cdm.json의 매니페스트가 있는 Common Data Model 폴더에서 Person 엔터티를 읽습니다.

val df = spark.read.format("com.microsoft.cdm")
 .option("storage", "mystorage.dfs.core.windows.net")
 .option("manifestPath", "cdmdata/contacts/root.manifest.cdm.json")
 .option("entity", "Person")
 .load()

DataFrame 스키마만 사용하여 암시적 쓰기

다음 코드는 이벤트 엔터티를 사용하여 mystorage.dfs.core.windows.net/cdmdata/Contacts/default.manifest.cdm.json에 매니페스트가 있는 Common Data Model 폴더에 df DataFrame을 씁니다.

이 코드는 이벤트 데이터를 Parquet 파일로 쓰고, gzip을 사용하여 압축하고, 폴더에 추가합니다. 코드는 기존 파일을 삭제하지 않고 새 파일을 추가합니다.


df.write.format("com.microsoft.cdm")
 .option("storage", "mystorage.dfs.core.windows.net")
 .option("manifestPath", "cdmdata/Contacts/default.manifest.cdm.json")
 .option("entity", "Event")
 .option("format", "parquet")
 .option("compression", "gzip")
 .mode(SaveMode.Append)
 .save()

Data Lake Storage에 저장된 엔터티 정의를 사용하여 명시적 쓰기

다음 코드는 Person 엔터티를 사용하여 https://_mystorage_.dfs.core.windows.net/cdmdata/Contacts/root.manifest.cdm.json에 매니페스트가 있는 Common Data Model 폴더에 df DataFrame을 씁니다. 이 코드는 폴더의 기존 파일을 덮어쓰는 새 CSV 파일(기본적으로)로 사용자 데이터를 씁니다.

코드는 https://_mystorage_.dfs.core.windows.net/models/cdmmodels/core/Contacts/Person.cdm.json에서 Person 엔터티 정의를 검색합니다.

df.write.format("com.microsoft.cdm")
 .option("storage", "mystorage.dfs.core.windows.net")
 .option("manifestPath", "cdmdata/contacts/root.manifest.cdm.json")
 .option("entity", "Person")
 .option("entityDefinitionModelRoot", "cdmmodels/core")
 .option("entityDefinitionPath", "/Contacts/Person.cdm.json/Person")
 .mode(SaveMode.Overwrite)
 .save()

Common Data Model GitHub 리포지토리에 정의된 엔터티를 사용하여 명시적 쓰기

다음 코드는 다음을 사용하여 df DataFrame을 Common Data Model 폴더에 씁니다.

  • https://_mystorage_.dfs.core.windows.net/cdmdata/Teams/root.manifest.cdm.json의 매니페스트입니다.
  • TeamMembership 하위 디렉터리에서 만든 TeamMembership 엔터티를 포함하는 하위 매니페스트입니다.

TeamMembership 데이터는 기존 데이터 파일을 덮어쓰는 CSV 파일에 기록됩니다(기본값). 코드는 applicationCommon의 팀 구성원 자격에 있는 Common Data Model CDN의 TeamMembership 엔터티 정의를 검색합니다.

df.write.format("com.microsoft.cdm")
 .option("storage", "mystorage.dfs.core.windows.net")
 .option("manifestPath", "cdmdata/Teams/root.manifest.cdm.json")
 .option("entity", "TeamMembership")
 .option("useCdmStandardModelRoot", true)
 .option("entityDefinitionPath", "core/applicationCommon/TeamMembership.cdm.json/TeamMembership")
 .option("useSubManifest", true)
 .mode(SaveMode.Overwrite)
 .save()

기타 고려 사항

Spark에서 Common Data Model로 데이터 형식 매핑

커넥터는 Spark 간의 Common Data Model을 변환할 때 다음 데이터 형식 매핑을 적용합니다.

Spark Common Data Model
ShortType SmallInteger
IntegerType Integer
LongType BigInteger
DateType Date
Timestamp DateTime(필요에 따라 Time)
StringType String
DoubleType Double
DecimalType(x,y) Decimal (x,y)(기본 소수 자릿수 및 전체 자릿수는 18,4)
FloatType Float
BooleanType Boolean
ByteType Byte

커넥터는 Common Data Model Binary 데이터 형식을 지원하지 않습니다.

일반 데이터 모델 날짜, DateTime, DateTimeOffset 데이터 처리

Spark CDM 커넥터는 Spark 및 Parquet에 대해 일반적인 데이터 모델 DateDateTime 데이터 형식을 정상적으로 처리합니다. CSV에서 커넥터는 이러한 데이터 형식을 ISO 8601 형식으로 읽고 씁니다.

커넥터는 Common Data Model DateTime 데이터 형식 값을 UTC로 해석합니다. CSV에서 커넥터는 이러한 값을 ISO 8601 형식으로 씁니다. 예제는 2020-03-13 09:49:00Z입니다.

로컬 시간 인스턴트를 기록하기 위한 Common Data Model DateTimeOffset 값은 Spark와 Parquet에서 CSV와 다른 방식으로 처리됩니다. CSV 및 기타 형식은 현지 시간 인스턴트를 2020-03-13 09:49:00-08:00와 같은 날짜/시간을 구성하는 구조로 표현할 수 있습니다. Parquet 및 Spark는 이러한 구조를 지원하지 않습니다. 대신 인스턴스를 UTC(또는 지정되지 않은 표준 시간대)으로 기록할 수 있는 TIMESTAMP 데이터 형식을 사용합니다.

Spark CDM 커넥터는 CSV 형식의 DateTimeOffset 값을 UTC 타임스탬프로 변환합니다. 이 값은 Parquet에서 타임스탬프를 유지합니다. 값이 나중에 CSV에 유지되면 +00:00 오프셋이 있는 DateTimeOffset 값으로 직렬화됩니다. 임시 정확도의 손실은 없습니다. 직렬화된 값은 오프셋이 손실되더라도 원래 값과 동일한 인스턴트를 나타냅니다.

Spark 시스템은 시스템 시간을 기준선으로 사용하고 일반적으로 해당 현지 시간을 사용하여 시간을 표현합니다. UTC 시간은 항상 로컬 시스템 오프셋 적용을 통해 컴퓨팅할 수 있습니다. 모든 지역의 Azure 시스템에서 시스템 시간은 항상 UTC이므로 모든 타임스탬프 값은 일반적으로 UTC입니다. DataFrame에서 Common Data Model 정의가 파생되는 암시적 쓰기를 사용하는 경우 타임스탬프는 UTC 시간을 의미하는 Common Data Model DateTime 데이터 형식의 특성으로 변환됩니다.

현지 시간을 유지하는 것이 중요하고 데이터가 Spark에서 처리되거나 Parquet에 유지되는 경우 DateTime 특성을 사용하고 오프셋을 별도의 특성으로 유지하는 것이 좋습니다. 예를 들어 오프셋을 분을 나타내는 부록 정수 값으로 유지할 수 있습니다. Common Data Model에서 DateTime 값은 UTC이므로 현지 시간을 계산하기 위해 오프셋을 적용해야 합니다.

대부분의 경우 현지 시간을 유지하는 것은 중요하지 않습니다. 현지 시간은 사용자 편의를 위해 UI에서만 필요하고 사용자의 표준 시간대를 기준으로 하는 경우가 많으므로, UTC 시간을 저장하지 않는 것이 더 좋은 솔루션일 때가 많습니다.

Common Data Model 시간 데이터 처리

Spark는 명시적 Time 데이터 형식을 지원하지 않습니다. Common Data Model Time 데이터 형식의 특성은 Spark DataFrame에 데이터 형식이 Timestamp인 있는 열로 표시됩니다. Spark CDM 커넥터가 시간 값을 읽으면 DataFrame의 타임스탬프는 Spark epoch 날짜 01/01/1970과 원본에서 읽은 시간 값을 사용하여 초기화됩니다.

명시적 쓰기를 사용하는 경우 타임스탬프를 DateTime 또는 Time 특성에 매핑할 수 있습니다. 타임스탬프를 Time 특성에 매핑하면 타임스탬프를 제거한 날짜 부분이 제거됩니다.

암시적 쓰기를 사용하는 경우 타임스탬프 열은 기본적으로 DateTime 특성에 매핑됩니다. 타임스탬프 열을 Time 특성에 매핑하려면 타임스탬프를 시간 값으로 해석해야 함을 나타내는 메타데이터 개체를 데이터 프레임의 열에 추가해야 합니다. 다음 코드는 Scala에서 이 방법을 보여 줍니다.

val md = new MetadataBuilder().putString(“dataType”, “Time”)
val schema = StructType(List(
StructField(“ATimeColumn”, TimeStampType, true, md))

시간 값 정확도

Spark CDM 커넥터는 DateTime 또는 Time의 시간 값을 지원합니다. 초는 읽는 파일의 데이터 형식(CSV 또는 Parquet)에 따라 또는 DataFrame에 정의된 대로 최대 6개의 소수 자릿수를 가집니다. 10진수 자리 6개를 사용하면 1초에서 마이크로초까지의 정확도를 사용할 수 있습니다.

폴더와 파일 이름 지정 및 조직

Common Data Model 폴더에 쓸 때 조직 기본 폴더가 있습니다. 기본적으로 데이터 파일은 2010-07-31처럼 현재 날짜로 작성된 폴더에 기록됩니다. dateFolderFormat 옵션을 사용하여 폴더 구조 및 이름을 사용자 지정할 수 있습니다.

데이터 파일 이름은 <entity>-<jobid>-*.<fileformat> 패턴을 기반으로 합니다.

sparkContext.parallelize() 메서드를 사용하여 작성된 데이터 파티션 수를 제어할 수 있습니다. 파티션 수는 Spark 클러스터의 실행기 수에 따라 결정되거나 명시적으로 지정합니다. 다음 Scala 예제에서는 두 개의 파티션이 있는 DataFrame을 만듭니다.

val df= spark.createDataFrame(spark.sparkContext.parallelize(data, 2), schema)

참조된 엔터티 정의로 정의된 명시적 쓰기의 예는 다음과 같습니다.

+-- <CDMFolder>
     |-- default.manifest.cdm.json     << with entity reference and partition info
     +-- <Entity>
          |-- <entity>.cdm.json        << resolved physical entity definition
          |-- <data folder>
          |-- <data folder>
          +-- ...                            

다음은 하위 매니페스트가 포함된 명시적 쓰기의 예입니다.

+-- <CDMFolder>
    |-- default.manifest.cdm.json       << contains reference to submanifest
    +-- <Entity>
         |-- <entity>.cdm.json
         |-- <entity>.manifest.cdm.json << submanifest with partition info
         |-- <data folder>
         |-- <data folder>
         +-- ...

다음은 엔터티 정의가 DataFrame 스키마에서 파생되는 암시적 쓰기의 예입니다.

+-- <CDMFolder>
    |-- default.manifest.cdm.json
    +-- <Entity>
         |-- <entity>.cdm.json          << resolved physical entity definition
         +-- LogicalDefinition
         |   +-- <entity>.cdm.json      << logical entity definitions
         |-- <data folder>
         |-- <data folder>
         +-- ...

다음은 하위 매니페스트가 포함된 암시적 쓰기의 예입니다.

+-- <CDMFolder>
    |-- default.manifest.cdm.json       << contains reference to submanifest
    +-- <Entity>
        |-- <entity>.cdm.json           << resolved physical entity definition
        |-- <entity>.manifest.cdm.json  << submanifest with reference to the entity and partition info
        +-- LogicalDefinition
        |   +-- <entity>.cdm.json       << logical entity definitions
        |-- <data folder>
        |-- <data folder>
        +-- ...

문제 해결 및 알려진 문제

  • DataFrame에서 사용하는 10진수 데이터 형식 필드의 전체 자릿수와 소수 자릿수가 Common Data Model 엔터티 정의에 있는 데이터 형식과 일치하는지 확인합니다. 전체 자릿수와 소수 자릿수가 Common Data Model에서 명시적으로 정의되지 않은 경우 기본값 Decimal(18,4)가 사용됩니다. model.json 파일의 경우 DecimalDecimal(18,4)로 간주됩니다.
  • 다음 옵션의 폴더 및 파일 이름에는 등호(=): manifestPath, entityDefinitionModelRoot, entityDefinitionPath, dataFolderFormat 등의 공백이나 특수 문자가 포함되어서는 안 됩니다.

다음 단계

이제 다음과 같은 다른 Apache Spark 커넥터를 살펴볼 수 있습니다.