Azure Databricks와 OneLake 통합

이 문서에서는 OneLake 데이터에 Azure Databricks에서 액세스하는 방법을 보여줍니다. 두 방법 모두 서비스 주체 인증과 OneLake ABFS 엔드포인트를 사용합니다. Databricks 컴퓨팅 유형과 일치하는 섹션을 선택합니다.

  • 표준 또는 작업 클러스터: OAuth 구성과 함께 Spark ABFS 드라이버를 사용하여 Spark DataFrames를 통해 직접 데이터를 읽고 씁니다.
  • 서버리스 컴퓨팅: 서버리스 런타임에서는 사용자 지정 Spark 구성 속성을 설정할 수 없습니다. 대신 MSAL(Microsoft 인증 라이브러리) 및 Python deltalake 라이브러리를 사용하여 델타 테이블을 인증하고 읽고 씁니다.

관련 Databricks 통합 시나리오는 다음 리소스를 참조하세요.

시나리오 설명서
Unity 카탈로그에서 OneLake 데이터를 복사하지 않고 쿼리 OneLake 카탈로그 페더레이션 사용
Fabric에서 Databricks Unity Catalog 데이터에 액세스하기 Azure Databricks Unity 카탈로그의 미러링

필수 조건

연결하기 전에 다음이 있는지 확인합니다.

  • Fabric 작업 영역 및 레이크하우스
  • 프리미엄 Azure Databricks 작업 영역
  • 적어도 기여자 작업 영역 역할 할당이 있는 서비스 주체입니다.
  • Databricks 비밀 또는 Azure Key Vault (AKV)을 사용하여 비밀을 저장하고 검색합니다. 이 문서의 예제에서는 Databricks 비밀을 사용합니다.

표준 클러스터를 사용하여 OneLake에 연결

올바른 OneLake ABFS 경로 형식 사용

다음 URI 형식 중 하나를 사용합니다.

  • abfss://<workspace_id_or_name>@onelake.dfs.fabric.microsoft.com/<lakehouse_id_or_name>.lakehouse/Files/<path>
  • abfss://<workspace_id_or_name>@onelake.dfs.fabric.microsoft.com/<lakehouse_id_or_name>.lakehouse/Tables/<path>

ID 또는 이름을 사용할 수 있습니다. 이름을 사용하는 경우 작업 영역 및 레이크하우스 이름에서 특수 문자와 공백을 사용하지 마세요.

서비스 주체 인증 사용

자동화된 작업 및 중앙 집중식 비밀 회전에 이 옵션을 사용합니다.

workspace_name = "<workspace_name>"
lakehouse_name = "<lakehouse_name>"
tenant_id = dbutils.secrets.get(scope="<scope-name>", key="<tenant-id-key>")
service_principal_id = dbutils.secrets.get(scope="<scope-name>", key="<client-id-key>")
service_principal_secret = dbutils.secrets.get(scope="<scope-name>", key="<client-secret-key>")

spark.conf.set("fs.azure.account.auth.type", "OAuth")
spark.conf.set(
   "fs.azure.account.oauth.provider.type",
   "org.apache.hadoop.fs.azurebfs.oauth2.ClientCredsTokenProvider",
)
spark.conf.set("fs.azure.account.oauth2.client.id", service_principal_id)
spark.conf.set("fs.azure.account.oauth2.client.secret", service_principal_secret)
spark.conf.set(
   "fs.azure.account.oauth2.client.endpoint",
   f"https://login.microsoftonline.com/{tenant_id}/oauth2/token",
)

# Read
df = spark.read.format("parquet").load(
   f"abfss://{workspace_name}@onelake.dfs.fabric.microsoft.com/{lakehouse_name}.lakehouse/Files/data"
)
df.show(10)

# Write
df.write.format("delta").mode("overwrite").save(
   f"abfss://{workspace_name}@onelake.dfs.fabric.microsoft.com/{lakehouse_name}.lakehouse/Tables/dbx_delta_spn"
)

서버리스 컴퓨팅을 사용하여 OneLake에 연결

Databricks 서버리스 컴퓨팅 을 사용하면 클러스터를 프로비전하지 않고도 워크로드를 실행할 수 있지만 지원되는 Spark 속성의 하위 집합만 허용합니다. 표준 클러스터에서 fs.azure.* 사용되는 Spark 구성은 설정할 수 없습니다.

참고

이 제한은 Azure Databricks에 고유하지 않습니다. AWS(Amazon Web Services)Google Cloud의 Databricks 서버리스 구현은 동일한 동작을 갖습니다.

서버리스 Notebook에서 지원되지 않는 Spark 구성을 설정하려고 하면 시스템에서 CONFIG_NOT_AVAILABLE 오류를 반환합니다.

사용자가 서버리스 컴퓨팅에서 지원되지 않는 Spark 구성을 수정하려고 시도하는 경우 오류 메시지를 보여 주는 스크린샷

대신 MSAL을 사용하여 OAuth 토큰 및 Python deltalake 라이브러리를 획득하여 해당 토큰으로 델타 테이블을 읽거나 씁니다.

서버리스 Notebook 설정

  1. Databricks 작업 영역에서 Notebook을 만들고 서버리스 컴퓨팅에 연결합니다.

    Databricks Notebook을 서버리스 컴퓨팅과 연결하는 방법을 보여 주는 스크린샷

  2. Python 모듈을 가져옵니다. 이 샘플에서는 다음 두 가지 모듈을 사용합니다.

    • msal은 Microsoft ID 플랫폼과 인증합니다.
    • deltalake는 Python을 사용하여 Delta Lake 테이블을 읽고 씁니다.
    from msal import ConfidentialClientApplication
    from deltalake import DeltaTable, write_deltalake
    
  3. 애플리케이션 ID를 포함하여 Microsoft Entra 테넌트에 대한 변수를 선언합니다. Fabric이 배포된 테넌트의 테넌트 ID를 사용합니다.

    # Fetch from Databricks secrets.
    tenant_id = dbutils.secrets.get(scope="<replace-scope-name>",key="<replace value with key value for tenant_id>")
    client_id = dbutils.secrets.get(scope="<replace-scope-name>",key="<replace value with key value for client_id>")
    client_secret = dbutils.secrets.get(scope="<replace-scope-name>",key="<replace value with key value for secret>")
    
  4. 패브릭 작업 영역 변수를 선언합니다.

    workspace_id = "<replace with workspace name>"
    lakehouse_id = "<replace with lakehouse name>"
    table_to_read = "<name of lakehouse table to read>"
    onelake_uri = f"abfss://{workspace_id}@onelake.dfs.fabric.microsoft.com/{lakehouse_id}.lakehouse/Tables/{table_to_read}"
    
  5. 토큰을 획득하도록 클라이언트를 초기화합니다.

    authority = f"https://login.microsoftonline.com/{tenant_id}"
    
    app = ConfidentialClientApplication(
        client_id,
        authority=authority,
        client_credential=client_secret
    )
    
    result = app.acquire_token_for_client(scopes=["https://onelake.fabric.microsoft.com/.default"])
    
    if "access_token" in result:
        print("Access token acquired.")
        token_val = result['access_token']
    else:
        raise Exception(f"Failed to acquire token: {result.get('error_description', result)}")
    
  6. OneLake에서 델타 테이블을 읽습니다.

    dt = DeltaTable(onelake_uri, storage_options={"bearer_token": f"{token_val}", "use_fabric_endpoint": "true"})
    df = dt.to_pandas()
    print(df.head())
    
  7. OneLake에 델타 테이블을 씁니다.

    target_uri = f"abfss://{workspace_id}@onelake.dfs.fabric.microsoft.com/{lakehouse_id}.lakehouse/Tables/<target_table_name>"
    write_deltalake(
        target_uri,
        df,
        mode="overwrite",
        storage_options={"bearer_token": f"{token_val}", "use_fabric_endpoint": "true"}
    )
    

디자인 고려 사항

  • 가능한 경우 테이블 경로당 하나의 기록기 패턴을 사용합니다. 여러 컴퓨팅 엔진 또는 런타임 버전에서 동일한 스토리지 경로에 쓰면 충돌이 발생할 수 있습니다.
  • 서비스 주체 자격 증명을 위해 비밀 관리 시스템을 사용하십시오.
  • 데이터를 다른 레이크하우스 위치에 물리적으로 쓰는 대신 가상화된 액세스가 필요한 경우 OneLake 바로 가기 를 사용합니다.