Hadoop Azure 지원: ABFS - Azure Data Lake Storage Gen2
Hadoop Azure 지원: ABFS - Azure Data Lake Storage Gen2
hadoop-azure 모듈은 "abfs" 커넥터를 통해 Azure Data Lake Storage Gen2 스토리지 계층을 지원해요. Apache Hadoop의 기본 클래스패스의 일부로 만들려면 클러스터의 모든 머신에서 HADOOP_OPTIONAL_TOOLS 환경 변수 목록에 hadoop-azure가 있는지 확인해요:
export HADOOP_OPTIONAL_TOOLS=hadoop-azure
이것은 로컬의 .profile / .bashrc에 설정할 수 있지만, 클러스터 내에서 실행되는 작업에는 전파되지 않는다는 점에 유의하세요.
출처: 문서
본문
소개 (Introduction)
hadoop-azure 모듈은 "abfs" 커넥터를 통해 Azure Data Lake Storage Gen2 스토리지 계층을 지원해요.
ABFS 커넥터의 기능 (Features of the ABFS connector)
- Azure Blob Storage 계정에 저장된 데이터를 읽고 씀.
- 모든 클라이언트에 걸쳐 스토리지의 완전히 일관된(fully consistent) 뷰.
- deprecated
wasb:커넥터를 통해 쓴 데이터를 읽을 수 있음. - 표준 Hadoop
FileSystem인터페이스를 구현해 계층적 파일시스템 뷰를 제시. - 여러 Azure Blob Storage 계정 구성 지원.
- Hadoop MapReduce, Apache Hive, Apache Spark에서 데이터의 소스 또는 대상 역할을 할 수 있음.
- Microsoft가 Linux와 Windows 모두에서 규모에 맞게 테스트.
- Azure 인프라에 배포된 Hadoop 클러스터에서 HDFS의 대체품으로 사용될 수 있음.
ABFS에 대한 자세한 내용은 다음 문서를 참고하세요: A closer look at Azure Data Lake Storage Gen2; 2018년 6월 28일 MSDN 기사. Storage Tiers.
시작하기 (Getting started)
개념 (Concepts)
Azure Storage 데이터 모델은 3가지 핵심 개념을 제시해요:
- Storage Account: 모든 접근은 스토리지 계정을 통해 이루어져요.
- Container: 컨테이너는 여러 blob의 그룹화예요. 스토리지 계정은 여러 컨테이너를 가질 수 있어요. Hadoop에서 전체 파일시스템 계층은 단일 컨테이너에 저장돼요.
- Blob: 어떤 유형과 크기의 파일이든. Hadoop에서 파일은 blob에 저장돼요. 내부 구현은 또한 파일시스템 계층과 기타 메타데이터를 유지하기 위해 blob을 사용해요.
ABFS 커넥터는 클래식 컨테이너 또는 Hierarchical Namespace로 만들어진 컨테이너에 연결돼요.
계층적 네임스페이스 (Hierarchical Namespaces, and WASB Compatibility)
ADLS Gen 2의 핵심 측면은 계층적 네임스페이스(hierarchical namespaces) 지원이에요. 이것들은 사실상 디렉터리이며 고성능 rename·delete 연산을 제공해요 — MapReduce, Spark, Hive, DistCp를 포함해 데이터를 쓰는 쿼리 엔진의 성능에 상당한 개선을 만들어내는 것입니다. 이 기능은 컨테이너가 "namespace" 지원으로 생성된 경우에만 사용할 수 있어요.
새 Storage Account를 만들 때 네임스페이스 지원을 활성화할 수 있어요. 포털 UI에서 "Hierarchical Namespace" 옵션을 체크하거나, 명령줄로 만들 때 --hierarchical-namespace true 옵션을 사용해요.
기존 스토리지 계정에서는 Hierarchical Namespaces를 활성화할 수 없어요. Hierarchical Namespaces가 있는 스토리지 계정의 컨테이너는 (현재) deprecated wasb: 커넥터로 읽을 수 없어요. 일부 az storage 명령줄 명령도 실패해요. 예:
$ az storage container list --account-name abfswales1
Output: Blob API is not yet supported for hierarchical namespace accounts.
ErrorCode: BlobApiNotYetSupportedForHierarchicalNamespaceAccounts
비-계층적 네임스페이스 (Non-Hierarchical Namespaces)
ABFS 드라이버는 레거시 WASB 드라이버에서 마이그레이션하는 사용자를 위해 비-계층적 네임스페이스(FNS) 계정도 지원해요. 자세한 내용은 FNS-Blob을 참고하세요. 서비스는 FNS 계정에 DFS 엔드포인트를 사용하는 것을 권장하지 않아요. FNS 계정에 대한 DFS 엔드포인트는 이제 제거됐어요. FNS 계정에 대해 감지된 모든 요청은 자동으로 Blob 엔드포인트로 전환돼요.
Azure Storage Account 만들기 (Creating an Azure Storage Account)
abfs 커넥터로 Azure Datalake Gen2를 시작하는 가장 좋은 문서는 Using Azure Data Lake Storage Gen2 with Azure HDInsight clusters예요. 여기에는 Windows, MacOS(Homebrew를 통해)와 Linux(apt 또는 yum)에 설치할 수 있는 Azure 명령줄 도구에서 만드는 지침이 포함돼요. az storage 하위 명령이 모든 스토리지 명령을 처리하며, az storage account create가 생성을 수행해요. ADLS gen2 API 지원이 확정될 때까지 ADLS 명령에 확장을 추가해야 해요:
az extension add --name storage-preview
사용 명령에 --hierarchical-namespace가 포함되는지 확인해 모든 것이 정상인지 확인해요:
$ az storage account
Output: usage: az storage account create [-h] [--verbose] [--debug]
[--output {json,jsonc,table,tsv,yaml,none}]
[--query JMESPATH] --resource-group
RESOURCE_GROUP_NAME --name ACCOUNT_NAME
[--sku {Standard_LRS,Standard_GRS,Standard_RAGRS,Standard_ZRS,Premium_LRS,Premium_ZRS}]
[--location LOCATION]
[--kind {Storage,StorageV2,BlobStorage,FileStorage,BlockBlobStorage}]
[--tags [TAGS [TAGS ...]]]
[--custom-domain CUSTOM_DOMAIN]
[--encryption-services {blob,file,table,queue} [{blob,file,table,queue} ...]]
[--access-tier {Hot,Cool}]
[--https-only [{true,false}]]
[--file-aad [{true,false}]]
**[--hierarchical-namespace [{true,false}]]**
[--bypass {None,Logging,Metrics,AzureServices} [{None,Logging,Metrics,AzureServices} ...]]
[--default-action {Allow,Deny}]
[--assign-identity]
[--subscription _SUBSCRIPTION]
az account list-locations에서 위치를 나열할 수 있으며, --location 인수의 이름을 나열해요:
$ az account list-locations -o table
위치는 표 형식으로 나열돼요. 샘플 출력:
DisplayName Latitude Longitude Name
------------------- ---------- ----------- ------------------
East Asia 22.267 114.188 eastasia
Southeast Asia 1.283 103.833 southeastasia
.... .... ...... .......
위치가 선택되면 계정을 만들어요:
az storage account create --verbose \
--name abfswales1 \
--resource-group devteam2 \
--kind StorageV2 \
--hierarchical-namespace true \
--location ukwest \
--sku Standard_LRS \
--https-only true \
--encryption-services blob \
--access-tier Hot \
--tags owner=engineering \
--assign-identity \
--output jsonc
명령의 출력은 JSON 파일이며, 그 primaryEndpoints 필드에 스토어 엔드포인트의 이름이 포함돼요:
{
"primaryEndpoints": {
"blob": "https://abfswales1.blob.core.windows.net/",
"dfs": "https://abfswales1.dfs.core.windows.net/",
"file": "https://abfswales1.file.core.windows.net/",
"queue": "https://abfswales1.queue.core.windows.net/",
"table": "https://abfswales1.table.core.windows.net/",
"web": "https://abfswales1.z35.web.core.windows.net/"
}
}
abfswales1.dfs.core.windows.net 계정은 스토리지 계정을 가리키는 이름이에요. 이제 스토어에 대한 연결 문자열(계정 키가 들어 있는)을 요청해요:
az storage account show-connection-string --name abfswales1
{
"connectionString": "DefaultEndpointsProtocol=https;EndpointSuffix=core.windows.net;AccountName=abfswales1;AccountKey=ACCOUNT_KEY_VALUE"
}
그런 다음 접근 키를 core-site.xml, JCEKs 파일에 추가하거나 fs.azure.account.key.STORAGE-ACCOUNT 옵션을 이 값으로 설정하기 위해 클러스터 관리 도구를 사용해야 해요:
<property>
<name>fs.azure.account.key.abfswales1.dfs.core.windows.net</name>
<value>ACCOUNT_KEY_VALUE</value>
</property>
Azure Portal을 통한 생성 (Creation through the Azure Portal)
포털을 통한 생성은 Quickstart: Create an Azure Data Lake Storage Gen2 storage account에서 다룬다. 핵심 단계:
- 적합한 위치에 새 Storage Account를 만들어요.
- "Basics" 탭: "StorageV2"를 선택해요.
- "Advanced" 탭: "Hierarchical Namespace"를 활성화해요.
이제 스토리지 계정을 만들었어요. 다음으로 "Shared Key" 인증(기본 인증 유형)의 키를 얻어요:
- Azure Portal로 이동해요.
- "Storage Accounts"를 선택해요.
- 새로 만든 스토리지 계정을 선택해요.
- 설정 목록에서 "Access Keys"를 찾아 선택해요.
- 접근 키 중 하나를 클립보드에 복사하고, XML 옵션에 추가하고, 클러스터 관리 도구, Hadoop JCEKS 파일 또는 KMS 스토어에 설정해요.
새 컨테이너 만들기 (Creating a new container)
Azure 스토리지 계정은 여러 컨테이너를 가질 수 있으며, 각각은 그 컨테이너 이름을 참조하는 URI의 userinfo 필드로 사용해요. 예를 들어 방금 만든 스토리지 계정의 "container1" 컨테이너는 URL abfs://[email protected]/을 가질 거예요.
ABFS 커넥터를 통해 fs.azure.createRemoteFileSystemDuringInitialization을 true로 설정해 새 컨테이너를 만들 수 있어요. AuthType이 SAS일 때는 같은 것이 지원되지 않아요. 컨테이너가 존재하지 않으면 hadoop fs -ls로 나열하려는 시도가 실패해요:
$ hadoop fs -ls abfs://[email protected]/
ls: `abfs://[email protected]/': No such file or directory
원격 FS 생성을 활성화하고 두 번째 시도가 성공하며, 그 과정에서 컨테이너가 생성돼요:
$ hadoop fs -D fs.azure.createRemoteFileSystemDuringInitialization=true \
-ls abfs://[email protected]/
이것은 명령줄에서 계정을 만들 때 유용하며, 특히 az storage 명령이 계층적 네임스페이스를 완전히 지원하기 전에요.
스토리지 계정의 컨테이너 나열·검사 (Listing and examining containers)
Azure Storage Explorer를 사용할 수 있어요.
ABFS 구성 (Configuring ABFS)
어떤 구성이든 일반적으로(또는 모든 계정에 접근할 때 기본값으로) 지정하거나 특정 계정에 결부(tied)시킬 수 있어요. 예를 들어 OAuth 자격 증명은 접근하는 계정과 무관하게 사용하도록 fs.azure.account.oauth2.client.id 속성으로 구성하거나, 특정 스토리지 계정에만 사용할 자격 증명을 fs.azure.account.oauth2.client.id.<account_name>.dfs.core.windows.net으로 구성할 수 있어요.
인증 (Authentication)
ABFS에 대한 인증은 궁극적으로 Azure Active Directory가 부여해요. 여기서 다루는 개념은 이 문서의 범위를 넘어서요. 개발자는 다양한 인증 메커니즘을 활용하기 위해 그 개념을 읽고 이해했다고 기대돼요. 여기서는 서로 다른 배포 상황에서 ABFS 클라이언트를 인증하도록 구성하는 방법을 간략히 다뤄요.
ABFS 클라이언트는 여러 방식으로 배포될 수 있으며, 인증 요구는 그에 따라 결정돼요:
- 스토리지 계정의 인증 비밀이 구성에 있을 때: "Shared Key".
- 한 형태 또는 다른 형태의 OAuth 2.0 토큰 사용.
- Azure VMs가 애플리케이션에 OAuth 2.0 토큰을 제공하는 in-Azure 배포: "Managed Instance".
SASTokenProvider인터페이스의 사용자 정의 구현이 제공하는 Shared Access Signature (SAS) 토큰 사용.- 계정 구성 설정 파일에 고정 Shared Access Signature (SAS) 토큰을 직접 구성.
- OAuth 2.0 설정(위 2번)과 SAS 설정(위 4번) 모두를 요구하는 user-bound SAS auth type 사용.
참고: user-bound SAS 인증은 HNS Enabled 계정에서만 지원되지만, SAS 인증에서도 HNS Enabled 계정을 사용하는 것을 권장해요.
변경할 수 있는 것은 호출자를 인증하는 데 사용되는 비밀/자격 증명이에요. 인증 메커니즘은 fs.azure.account.auth.type(또는 계정 특정 변형)에 설정돼요. 가능한 값은 SharedKey, OAuth, Custom, SAS예요. 다양한 OAuth 옵션은 fs.azure.account.oauth.provider.type 구성을 사용해요. 지원되는 구현은 ClientCredsTokenProvider, UserPasswordTokenProvider, MsiTokenProvider, RefreshTokenBasedTokenProvider, WorkloadIdentityTokenProvider예요. 지정된 제공자 유형이 지원되는 것 중 하나가 아니면 IllegalArgumentException이 던져져요. 모든 비밀은 JCEKS 파일에 저장될 수 있어요. 이것들은 암호화되고 비밀번호로 보호돼요 — 그것들 또는 호환되는 Hadoop Key Management Store를 사용하세요.
기본: 공유 키 (Default: Shared Key)
<property>
<name>fs.azure.account.auth.type.ACCOUNT_NAME.dfs.core.windows.net</name>
<value>SharedKey</value>
<description>
</description>
</property>
<property>
<name>fs.azure.account.key.ACCOUNT_NAME.dfs.core.windows.net</name>
<value>ACCOUNT_KEY</value>
<description>
The secret password. Never share these.
</description>
</property>
참고: 계정 키의 소스는 사용자 정의 키 제공자를 통해 변경할 수 있어요. 하나는 그것을 검색하기 위해 셸 스크립트를 실행해야 해요. 사용자 정의 키 제공자 클래스는 fs.azure.account.keyprovider 구성으로 제공할 수 있어요. 키 제공자 클래스가 지정되면 계정 키를 얻는 데 같은 것이 사용돼요. 그렇지 않으면 fs.azure.account.key 구성에 지정된 키를 사용할 Simple 키 제공자가 사용돼요. 셸 스크립트로 검색하려면 fs.azure.shellkeyprovider.script 구성에 대한 스크립트 경로를 지정해요. ShellDecryptionKeyProvider 클래스는 키를 검색하기 위해 지정된 스크립트를 사용해요.
OAuth 2.0 인증 (OAuth 2.0 Authentication)
다음은 OAuth 설정의 주요 자격 증명 구성 옵션이에요. 이 모든 것은 OAuth를 인증 유형으로 설정하게 될 거예요:
<property>
<name>fs.azure.account.auth.type</name>
<value>OAuth</value>
<description>
Use OAuth authentication
</description>
</property>
클라이언트 자격 증명 (Client Credentials)
OAuth 2.0 자격 증명 (client id, client secret, endpoint)이 구성/JCEKS 파일에 제공돼요. 이 과정의 세부 내용은 hadoop-azure-datalake에서 다루며, 키 이름이 여기서는 약간 달라요.
<property>
<name>fs.azure.account.auth.type</name>
<value>OAuth</value>
<description>
Use OAuth authentication
</description>
</property>
<property>
<name>fs.azure.account.oauth.provider.type</name>
<value>org.apache.hadoop.fs.azurebfs.oauth2.ClientCredsTokenProvider</value>
<description>
Use client credentials
</description>
</property>
<property>
<name>fs.azure.account.oauth2.client.endpoint</name>
<value>TOKEN_ENDPOINT</value>
<description>
URL of OAuth endpoint
</description>
</property>
<property>
<name>fs.azure.account.oauth2.client.id</name>
<value>CLIENT_ID</value>
<description>
Client ID
</description>
</property>
<property>
<name>fs.azure.account.oauth2.client.secret</name>
<value>CLIENT_SECRET</value>
<description>
Secret
</description>
</property>
사용자 이름과 비밀번호 (Username and Password)
OAuth 2.0 엔드포인트, 사용자 이름, 비밀번호가 구성/JCEKS 파일에 제공돼요.
<property>
<name>fs.azure.account.auth.type</name>
<value>OAuth</value>
<description>
Use OAuth authentication
</description>
</property>
<property>
<name>fs.azure.account.oauth.provider.type</name>
<value>org.apache.hadoop.fs.azurebfs.oauth2.UserPasswordTokenProvider</value>
<description>
Use user and password
</description>
</property>
<property>
<name>fs.azure.account.oauth2.client.endpoint</name>
<value>TOKEN_ENDPOINT</value>
<description>
URL of OAuth 2.0 endpoint
</description>
</property>
<property>
<name>fs.azure.account.oauth2.user.name</name>
<value>USERNAME_VALUE</value>
<description>
username
</description>
</property>
<property>
<name>fs.azure.account.oauth2.user.password</name>
<value>USER_PASSWORD</value>
<description>
password for account
</description>
</property>
갱신 토큰 (Refresh Token)
기존 Oauth 2.0 토큰으로, 이 토큰을 갱신하기 위해 Active Directory 엔드포인트 https://login.microsoftonline.com/Common/oauth2/token에 요청해요.
<property>
<name>fs.azure.account.auth.type</name>
<value>OAuth</value>
<description>
Use OAuth 2.0 authentication
</description>
</property>
<property>
<name>fs.azure.account.oauth.provider.type</name>
<value>org.apache.hadoop.fs.azurebfs.oauth2.RefreshTokenBasedTokenProvider</value>
<description>
Use the Refresh Token Provider
</description>
</property>
<property>
<name>fs.azure.account.oauth2.refresh.token</name>
<value>REFRESH_TOKEN</value>
<description>
Refresh token
</description>
</property>
<property>
<name>fs.azure.account.oauth2.refresh.endpoint</name>
<value>REFRESH_ENDPOINT</value>
<description>
Refresh token endpoint
</description>
</property>
<property>
<name>fs.azure.account.oauth2.client.id</name>
<value>CLIENT_ID</value>
<description>
Optional Client ID
</description>
</property>
Azure Managed Identity
Azure Managed Identities, 이전 "Managed Service Identities". OAuth 2.0 토큰은 실행 중인 VM에서만 접근 가능한 특별한 엔드포인트 (http://169.254.169.254/metadata/identity/oauth2/token)가 발행해요. 발행된 자격 증명은 인증에 사용될 수 있어요. Azure Portal/CLI는 서비스 자격 증명을 만드는 데 사용돼요.
<property>
<name>fs.azure.account.auth.type</name>
<value>OAuth</value>
<description>
Use OAuth authentication
</description>
</property>
<property>
<name>fs.azure.account.oauth.provider.type</name>
<value>org.apache.hadoop.fs.azurebfs.oauth2.MsiTokenProvider</value>
<description>
Use MSI for issuing OAuth tokens
</description>
</property>
<property>
<name>fs.azure.account.oauth2.msi.tenant</name>
<value>MSI_TENANT_VALUE</value>
<description>
Optional MSI Tenant ID
</description>
</property>
<property>
<name>fs.azure.account.oauth2.msi.endpoint</name>
<value>TOKEN_ENDPOINT</value>
<description>
MSI endpoint
</description>
</property>
<property>
<name>fs.azure.account.oauth2.client.id</name>
<value>CLIENT_ID</value>
<description>
Optional Client ID
</description>
</property>
Azure Workload Identity
Azure Workload Identities, 이전 "Azure AD pod identity". OAuth 2.0 토큰은 실행 중인 pod에서만 접근 가능한 파일 (/var/run/secrets/azure/tokens/azure-identity-token)에 기록돼요. 발행된 자격 증명은 인증에 사용될 수 있어요. Azure Portal/CLI는 서비스 자격 증명을 만드는 데 사용돼요.
<property>
<name>fs.azure.account.auth.type</name>
<value>OAuth</value>
<description>
Use OAuth authentication
</description>
</property>
<property>
<name>fs.azure.account.oauth.provider.type</name>
<value>org.apache.hadoop.fs.azurebfs.oauth2.WorkloadIdentityTokenProvider</value>
<description>
Use Workload Identity for issuing OAuth tokens
</description>
</property>
<property>
<name>fs.azure.account.oauth2.msi.tenant</name>
<value>${env.AZURE_TENANT_ID}</value>
<description>
Optional MSI Tenant ID
</description>
</property>
<property>
<name>fs.azure.account.oauth2.client.id</name>
<value>${env.AZURE_CLIENT_ID}</value>
<description>
Optional Client ID
</description>
</property>
<property>
<name>fs.azure.account.oauth2.token.file</name>
<value>${env.AZURE_FEDERATED_TOKEN_FILE}</value>
<description>
Token file path
</description>
</property>
커스텀 OAuth 2.0 토큰 제공자 (Custom OAuth 2.0 Token Provider)
커스텀 OAuth 2.0 토큰 제공자는 getAccessToken() 메서드가 호출될 때 ABFS 커넥터에 OAuth 2.0 토큰을 공급해요.
<property>
<name>fs.azure.account.auth.type</name>
<value>Custom</value>
<description>
Custom Authentication
</description>
</property>
<property>
<name>fs.azure.account.oauth.provider.type</name>
<value>PROVIDER_TYPE</value>
<description>
classname of Custom Authentication Provider
</description>
</property>
선언된 클래스는 org.apache.hadoop.fs.azurebfs.extensions.CustomTokenProviderAdaptee와 선택적으로 org.apache.hadoop.fs.azurebfs.extensions.BoundDTExtension을 구현해야 해요. 선언된 클래스는 또한 접근 토큰을 가져오는 동안 재시도 로직을 구현할 책임을 가져요.
위임 토큰 제공자 (Delegation Token Provider)
위임 토큰 제공자는 CustomDelegationTokenManager 인터페이스를 구현해 ABFS 커넥터에 위임 토큰을 공급하고, 토큰을 갱신·취소하는 것을 도와요.
<property>
<name>fs.azure.enable.delegation.token</name>
<value>true</value>
<description>Make this true to use delegation token provider</description>
</property>
<property>
<name>fs.azure.delegation.token.provider.type</name>
<value>{fully-qualified-class-name-for-implementation-of-CustomDelegationTokenManager-interface}</value>
</property>
위임 토큰이 활성화되고 fs.azure.delegation.token.provider.type 구성이 제공되지 않으면 IllegalArgumentException이 던져져요.
Shared Access Signature (SAS) 토큰 제공자
SAS(공유 액세스 서명)는 스토리지 계정의 리소스에 대한 안전한 위임 접근을 제공해요. SAS를 사용하면 클라이언트가 데이터에 어떻게 접근할 수 있는지 세밀하게 제어할 수 있어요. SAS 인증이 어떻게 작동하는지 더 알려면 Grant limited access to Azure Storage resources using shared access signatures (SAS)를 참고하세요.
Azure Storage가 지원하는 SAS 유형은 세 가지예요:
- User Delegation SAS: SAS 기반 인증은 HNS-enabled ADLS Gen2 계정(ABFS와 함께 사용을 권장)에서 작동하며 비-HNS (FNS) Blob 계정에서도 지원돼요. 하지만 FNS-DFS 계정에서는 지원되지 않아요.
- Service SAS: 글로벌하며 컨테이너 수준에서 작동.
- Account SAS: 글로벌하며 계정 수준에서 작동.
SAS의 알려진 이슈: SAS 기반 인증은 HNS Enabled ADLS Gen2 계정(ABFS와 함께 사용할 권장 계정 유형)에서 작동해요. 비-HNS (FNS) Blob 계정에서도 지원돼요. FNS-DFS 계정에서는 지원되지 않아요. 특정 루트 수준 연산은 SAS 기반 인증에서 실패하는 것으로 알려져 있어요.
ABFS와 함께 User Delegation SAS 사용: ABFS는 사용자 정의 SAS 토큰 제공자를 구현할 수 있게 해줘요. 이 제공자는 사용자의 자격 증명을 사용해 user delegation key를 만들고, 그 키를 스토리지 계정 키 대신 SAS를 만드는 데 사용할 수 있어요. 선언된 클래스는 org.apache.hadoop.fs.azurebfs.extensions.SASTokenProvider를 구현해야 해요. 구성:
<property>
<name>fs.azure.account.auth.type</name>
<value>SAS</value>
</property>
<property>
<name>fs.azure.sas.token.provider.type</name>
<value>CUSTOM_SAS_TOKEN_PROVIDER_CLASS</value>
</property>
CUSTOM_SAS_TOKEN_PROVIDER_CLASS를 구현의 전체 자격 클래스 이름으로 대체해요. 구현에 따라 사용자 정의 구현에 필요한 추가 구성이 필요할 수 있어요. 예: ABFS Hadoop Driver는 자체 커스텀 SASTokenProvider를 구현하는 방법의 예로 사용할 수 있는 MockDelegationSASTokenProvider 구현을 제공해요. 이것은 위 두 가지 외에 다음 구성을 사용해 Application 자격 증명을 지정해야 해요:
<property>
<name>fs.azure.test.app.service.principal.tenant.id</name>
<value>TENANT_ID</value>
</property>
<property>
<name>fs.azure.test.app.service.principal.object.id</name>
<value>OBJECT_ID</value>
</property>
<property>
<name>fs.azure.test.app.id</name>
<value>APPLICATION_ID</value>
</property>
<property>
<name>fs.azure.test.app.secret</name>
<value>APPLICATION_SECRET</value>
</property>
보안: Shared Key보다 더 안전하며 접근 키를 노출하지 않고 데이터에 대한 제한된 접근을 부여할 수 있어요. HNS Enabled, ADLS Gen 2 스토리지 계정과만 함께 사용하는 것을 권장해요.
ABFS와 함께 Account/Service SAS 사용: ABFS는 사용자가 요청 인증에 Account/Service SAS를 사용할 수 있게 해줘요. 모든 요청에 걸쳐 사용할 고정 SAS 토큰으로 지정할 수 있어요. 구성:
<property>
<name>fs.azure.account.auth.type</name>
<value>SAS</value>
</property>
Account SAS (계정 수준의 고정 SAS 토큰):
<property>
<name>fs.azure.sas.fixed.token.ACCOUNT_NAME</name>
<value>FIXED_ACCOUNT_SAS_TOKEN</value>
</property>
FIXED_ACCOUNT_SAS_TOKEN을 고정 Account/Service SAS로 대체해요. Azure 포털에서 SAS를 생성할 수도 있어요: Account -> Security + Networking -> Shared Access Signature.
Service SAS (컨테이너 수준의 고정 SAS 토큰):
<property>
<name>fs.azure.sas.fixed.token.CONTAINER_NAME.ACCOUNT_NAME</name>
<value>FIXED_SAS_TOKEN</value>
</property>
FIXED_SERVICE_SAS_TOKEN을 고정 Service SAS로 대체해요. Azure 포털에서 SAS를 생성할 수도 있어요: Account -> Data storage -> Containers -> 컨테이너를 우클릭하고 generate SAS 선택 -> 유효한 권한과 만료 시간 부여 -> generate SAS 클릭하고 SAS 토큰 복사.
보안: Account/Service SAS는 계정 키를 사용해야 하므로 덜 안전해요. 서로 다른 사용자에게 위임 접근의 범위가 없어요.
참고: SAS의 선호 순서:
fs.azure.sas.token.provider.typefs.azure.sas.fixed.token.CONTAINER_NAME.ACCOUNT_NAMEfs.azure.sas.fixed.token.ACCOUNT_NAMEfs.azure.sas.fixed.token
User-bound SAS: user-bound SAS auth type은 생성된 SAS 토큰의 사용을 추적할 수 있게 해줘요 — user-delegation SAS 인증 유형에서는 불가능했던 것. 자세한 정보는 [email protected]으로 연락하세요. 이 인증 유형을 사용하려면 커스텀 SAS 토큰 제공자 클래스와 OAuth 2.0 제공자 유형 모두 지정해야 해요. OAuth 토큰 제공자 설정에 여러 자격 증명 구성이 있어요. 주요한 것들: Client Credentials, Custom token provider, Managed Identity, Workload Identity. 참고: user-bound SAS 인증은 HNS Enabled 계정에서만 지원돼요.
구성:
<property>
<name>fs.azure.account.auth.type</name>
<value>UserboundSASWithOAuth</value>
</property>
<property>
<name>fs.azure.account.oauth.provider.type</name>
<value>org.apache.hadoop.fs.azurebfs.oauth2.ADD_CHOSEN_OAUTH_IDENTITY_CONFIGURATION</value>
</property>
<property>
<name>fs.azure.sas.token.provider.type</name>
<value>CUSTOM_SAS_TOKEN_PROVIDER_CLASS</value>
</property>
선언된 클래스는 org.apache.hadoop.fs.azurebfs.extensions.SASTokenProvider를 구현해야 해요. ABFS Hadoop Driver는 자체 커스텀 SASTokenProvider를 구현하는 방법의 예로 사용할 수 있는 MockUserBoundSASTokenProvider 구현을 제공해요.
기술 노트 (Technical notes)
프록시 설정 (Proxy setup)
커넥터는 프록시 설정을 제어하기 위해 JVM 프록시 설정을 사용해요. 설정할 옵션은 The Oracle Java documentation을 참고하세요. 커넥터는 기본적으로 HTTPS를 사용하므로 https.proxyHost와 https.proxyPort 옵션을 구성해야 해요. MapReduce 작업(including distcp)에서 프록시 옵션은 mapreduce.map.java.opts와 mapreduce.reduce.java.opts 모두에 설정해야 해요.
# this variable is only here to avoid typing the same values twice.
# It's name is not important.
export DISTCP_PROXY_OPTS="-Dhttps.proxyHost=web-proxy.example.com -Dhttps.proxyPort=80"
hadoop distcp \
-D mapreduce.map.java.opts="$DISTCP_PROXY_OPTS" \
-D mapreduce.reduce.java.opts="$DISTCP_PROXY_OPTS" \
-update -skipcrccheck -numListstatusThreads 40 \
hdfs://namenode:8020/users/alice abfs://[email protected]/users/alice
이 설정이 없으면 ADLS 접근이 명령줄에서 작동할지라도 distcp 접근이 네트워크 오류로 실패할 수 있어요.
보안 (Security)
다른 객체 스토어와 마찬가지로 로그인 비밀은 귀중한 정보예요. 조직은 안전하게 공유하는 프로세스를 가져야 해요.
ABFS 커넥터의 제한 사항 (Limitations of the ABFS connector)
- 파일 마지막 접근 시간이 추적되지 않아요.
- 확장 속성(Extended attributes)이 지원되지 않아요.
- 파일 체크섬(File Checksums)이 지원되지 않아요.
fs.azure.enable.flush가true로 설정되면(기본=true) Syncable 인터페이스hsync()와hflush()연산이 지원돼요. Wasb 커넥터에서는 두 호출 중 어느 것이든 50,000회로 제한됐어요 (HADOOP-15478). abfs에 유사한 제한이 있다면 sync/flush를 과도하게 사용하면 문제가 발생할 수 있어요.
일관성과 동시성 (Consistency and Concurrency)
모든 Azure 스토리지 서비스와 마찬가지로 Azure Datalake Gen 2 스토어는 데이터·메타데이터 모두에 대해 완전한 Create, Read, Update, Delete 일관성으로 스토어의 완전히 일관된 뷰를 제공해요.
성능과 확장성 (Performance and Scalability)
계층적 네임스페이스가 있는 컨테이너의 확장성 수치(Big-O 표기):
| Operation | Scalability |
|---|---|
| File Rename | O(1) |
| File Delete | O(1) |
| Directory Rename | O(1) |
| Directory Delete | O(1) |
비-네임스페이스 스토어의 확장성:
| Operation | Scalability |
|---|---|
| File Rename | O(1) |
| File Delete | O(1) |
| Directory Rename | O(files) |
| Directory Delete | O(files) |
즉, 파일이 많을수록 디렉터리 연산이 느려져요. 더 읽기: Azure Storage Scalability Targets.
확장성 (Extensibility)
ABFS 커넥터는 타사가 자신의 인증·인가 서비스를 ABFS 클라이언트에 통합하기 위한 여러 제한된-비공개/불안정 확장 지점을 지원해요.
CustomDelegationTokenManager: Hadoop Delegation Tokens을 발행하는 능력 추가.SASTokenProvider: Azure Storage Shared Access Signature (SAS) 토큰의 커스텀 제공 허용.CustomTokenProviderAdaptee: 커스텀 제공 허용.
기타 구성 옵션 (Other configuration options)
전체 구성 옵션과 기본값 목록은 org.apache.hadoop.fs.azurebfs.constants.ConfigurationKeys, org.apache.hadoop.fs.azurebfs.constants.FileSystemConfigurations, org.apache.hadoop.fs.azurebfs.AbfsConfiguration의 javadocs를 참고하세요.
클라이언트 상관 옵션 (Client Correlation Options)
- Client CorrelationId 옵션:
fs.azure.client.correlationid는 클라이언트 제공 식별자를 사용해 클라이언트 요청을 상관시키는 옵션을 제공해요. 이 Id는 Azure Storage Analytics 로그의 request-id-header 필드에 표시돼요. 최대 72자 문자열을 받으며 영숫자 문자 및/또는 하이픈만 포함해야 해요. 입력이 유효하지 않으면 빈 문자열로 기본값이 정해져요. - Correlation IDs Display Options:
fs.azure.tracingcontext.format은request-id-header에 포함된 ID의 형식을 선택하는 옵션. 다음 enum 옵션에 해당하는 String 값을 받아요.SINGLE_ID_FORMAT: clientRequestId,ALL_ID_FORMAT: 모든 ID (기본),TWO_ID_FORMAT: clientCorrelationId:clientRequestId.
플러시 옵션 (Flush Options)
- Azure Blob File System Flush Options:
fs.azure.enable.flush는 ABFS 플러시 APIHFlush()와HSync()를 no-op으로 만들 옵션. 기본적으로true로 설정돼요. 두 API 모두 데이터가 유지되도록 해요. - OutputStream Flush Options:
fs.azure.disable.outputstream.flush는 AbfsOutputStream에서 OutputStreamFlush()API를 no-op으로 만들 옵션. 기본적으로true로 설정돼요. 지속적인 데이터 전송을 제공할 수 있는 문서화된 유일한 API가 Hflush()이므로, Flush()도 버퍼된 데이터를 유지하려 시도하면 성능 문제가 생겨요.
Hundred Continue Options
fs.azure.account.expect.header.enabled: 각 append 요청과 함께 expect 100 continue 헤더를 보낼지 여부를 지정하는 구성 파라미터. 기본적으로 true로 설정돼요.
성능 (Perf) 옵션
성능 로깅은 fs.azure.perf.logging.enabled로 제어되며, 요청 로깅은 서버로 전송돼요. 각 요청의 성능 수치는 후속 요청의 x-ms-abfs-client-latency HTTP 헤더로 ADLS Gen 2 API 엔드포인트에 다시 전송돼요. Azure는 이 설정을 사용해 종단간 지연을 추적해요.
성능 로그 필드 정의: h: host name, t: 요청이 기록된 시간, a: Azure 스토리지 계정 이름, c: 컨테이너 이름, cr: 호출자 메서드 이름, ce: 피호출자(calee) 메서드 이름, r: 결과 (Succeeded/Failed), l: 지연 (피호출자에서 보낸 시간), ls: 지연 합계 (호출자에서 소비된 총 시간; 여러 피호출자가 있을 때 기록되며 마지막 피호출자와 함께 기록), lc: 지연 수 (피호출자 수; 여러 피호출자가 있을 때 기록되며 마지막 피호출자와 함께 기록), s: HTTP Status 코드, e: 오류 코드, ci: 클라이언트 요청 ID, ri: 서버 요청 ID, ct: 연결 시간(밀리초), st: 전송 시간(밀리초), rt: 수신 시간(밀리초), bs: 전송 바이트, br: 수신 바이트, m: HTTP 메서드 (GET, PUT 등), u: 인코딩된 HTTP URL.
드라이버 메트릭 옵션 (Driver Metric Options)
fs.azure.metric.format: 메트릭용 헤더에 포함된 ID의 형식을 선택.INTERNAL_METRIC_FORMAT: backoff + footer metrics,INTERNAL_BACKOFF_METRIC_FORMAT: backoff metrics,INTERNAL_FOOTER_METRIC_FORMAT: footer metrics,EMPTY: 기본.fs.azure.metric.account.name: 메트릭을 백엔드로 푸시하는 데 사용할 계정의 이름. 별도의 계정을 구성하거나 다른 요청이 이루어지는 기존 계정과 같은 것을 사용할 수 있어요.fs.azure.metric.account.key: 메트릭을 스토어로 푸시하는 데 사용되는 스토리지 계정의 접근 키.fs.azure.metric.uri:'https://<accountname>.dfs.core.windows.net/<containername>'형식의 uri를 제공. 파일시스템 생성에 대한 추가 호출을 방지하려면 이것이 구성의 일부여야 해요. 메트릭을 푸시하기 위해 기존 파일시스템을 사용해요.
<property>
<name>fs.azure.metric.account.name</name>
<value>METRICACCOUNTNAME.dfs.core.windows.net</value>
</property>
<property>
<name>fs.azure.metric.account.key</name>
<value>ACCOUNTKEY</value>
</property>
<property>
<name>fs.azure.metric.uri</name>
<value>https://METRICACCOUNTNAME.dfs.core.windows.net/CONTAINERNAME</value>
</property>
문제 해결 (Troubleshooting)
커넥터와 관련된 문제는 보통 다음 순서로 귀결돼요:
- Classpath.
- 네트워크 설정 (proxy 등).
- 인증과 인가.
- 그 외.
org.apache.hadoop.fs.azurebfs.services를 DEBUG로 기록하면 실패하는 요청에 대한 더 많은 세부 정보를 볼 수 있어요. 연결성 디버깅에 유용한 도구 하나는 cloudstore의 storediag 유틸리티예요. 이것은 클래스패스, 설정을 검증한 다음 파일시스템으로 작업을 시도해요.
bin/hadoop jar cloudstore-0.1-SNAPSHOT.jar storediag abfs://[email protected]/
storediag 명령이 abfs 스토어로 작업할 수 없다면 다른 것도 할 수 없을 가능성이 높아요. storediag 스토어가 성공적으로 작동한다면 클러스터의 나머지 부분의 클래스패스나 구성도 작동한다고 보장하지는 않아요. 특히 분산 애플리케이션에서요. 하지만 적어도 시작이에요.
ClassNotFoundException: org.apache.hadoop.fs.azurebfs.AzureBlobFileSystem
hadoop-azure JAR가 클래스패스에 없어요.
java.lang.RuntimeException: java.lang.ClassNotFoundException:
Class org.apache.hadoop.fs.azurebfs.AzureBlobFileSystem not found
at org.apache.hadoop.conf.Configuration.getClass(Configuration.java:2625)
at org.apache.hadoop.fs.FileSystem.getFileSystemClass(FileSystem.java:3290)
at org.apache.hadoop.fs.FileSystem.createFileSystem(FileSystem.java:3322)
...
팁: 명령줄에서 발생한다면 hadoop 스크립트의 디버그 로깅을 켤 수 있어요: export HADOOP_SHELL_SCRIPT_DEBUG=true. 클러스터 내에서 실행되는 애플리케이션에서 발생한다면 클러스터가 (어떻게든) hadoop-azure 모듈과 의존성이 배포된 애플리케이션의 클래스패스에 있도록 구성되어야 함을 의미해요.
ClassNotFoundException: com.microsoft.azure.storage.StorageErrorCode
azure-storage JAR가 클래스패스에 없어요.
Server failed to authenticate the request
요청이 기본 shared-key 인증 메커니즘을 사용하는 동안 인증되지 않았어요.
Operation failed: "Server failed to authenticate the request.
Make sure the value of Authorization header is formed correctly including the signature.",
403, HEAD, https://account.dfs.core.windows.net/container2?resource=filesystem&timeout=90
at org.apache.hadoop.fs.azurebfs.services.AbfsRestOperation.execute(AbfsRestOperation.java:135)
at org.apache.hadoop.fs.azurebfs.services.AbfsClient.getFilesystemProperties(AbfsClient.java:209)
...
원인:
- 자격 증명이 올바르지 않음.
- 공유 비밀이 만료됨. Azure에서 이것은 자동으로 발생해요.
- 공유 비밀이 취소됨.
- 호스트/VM 시계 드리프트로 클라이언트의 시계가 Azure 서버와 맞지 않음 — 호출이 오래되었거나(재생으로 간주) 미래로 간주되어 거부됨.
해결: 시계 등을 확인.
Configuration property something.dfs.core.windows.net not found
클러스터 구성에 특정 계정의 접근 키를 선언하는 fs.azure.account.key. 항목이 없거나 잘못된 URL을 사용하고 있어요.
$ hadoop fs -ls abfs://[email protected]/
ls: Configuration property abfswales2.dfs.core.windows.net not found. Make sure that the URL is correct
없는 계정 키를 추가해요.
No such file or directory when trying to list a container
주어진 이름의 컨테이너가 없어요. 오타가 있거나 컨테이너를 만들어야 해요. URL이 올바른지 확인하고 필요하면 컨테이너를 만들어요.
"HTTP connection to https://login.microsoftonline.com/something failed for getting token from AzureAD. Http response: 200 OK"
OAuth 인증 페이지가 HTTP 오류 코드로 실패하지 않았지만 JSON도 반환하지 않았어요 (content-type이 text/html, text/plain, application/xml). 가능한 원인은 구성과 네트워킹이에요:
- 인증이 실패하고, 호출자가 머신임에도 사람을 위한 Azure Active Directory 로그온 페이지가 제공되고 있음.
- URL이 잘못됨 — OAuth2.0과 무관한 웹 페이지를 가리키고 있음.
- 유용한 지침을 반환하려 시도하는 프록시 서버가 방해하고 있음.
java.io.IOException: The ownership on the staging directory ... is not as expected
Azure Managed Identities를 사용할 때 ADLS Gen2의 파일/디렉터리는 기본적으로 서비스 principal 객체 id(즉 principal ID)가 소유하며, 로컬 OS 사용자 'user1'로 작업을 제출하면 위 예외가 발생해요. 해결책은 core-site.xml에 아래 속성을 추가해 소유권을 로컬 OS 사용자에 모방(mimic)하는 것이에요.
<property>
<name>fs.azure.identity.transformer.service.principal.id</name>
<value>service principal object id</value>
<description>
An Azure Active Directory object ID (oid) used as the replacement for names contained
in the list specified by "fs.azure.identity.transformer.service.principal.substitution.list".
Notice that instead of setting oid, you can also set $superuser here.
</description>
</property>
<property>
<name>fs.azure.identity.transformer.service.principal.substitution.list</name>
<value>user1</value>
<description>
A comma separated list of names to be replaced with the service principal ID specified by
"fs.azure.identity.transformer.service.principal.id". This substitution occurs
when setOwner, setAcl, modifyAclEntries, or removeAclEntries are invoked with identities
contained in the substitution list. Notice that when in non-secure cluster, asterisk symbol *
can be used to match all user/group.
</description>
</property>
위 속성을 구성하면 hdfs dfs -ls abfs://[email protected]/은 ADLS Gen2 파일/디렉터리가 이제 'user1'이 소유하는 것으로 보여줘요.
알려진 이슈 (Known Issues)
다음 실패는 알려져 있으며 현재로서는 실패할 것으로 예상돼요.
AzureBlobFileSystem.setXAttr()와AzureBlobFileSystem.getXAttr()는 루트("/") 경로에서Operation failed: "The request URI is invalid."HTTP 400 Bad Request로 실패해요.- user-delegation SAS 인증을 사용한다면:
- HNS 계정(DFS 엔드포인트에서)의 나열 연산은 blob 또는 디렉터리 스코프를 지원하는 SAS 토큰(Signed Resource Type as Blob or Directory)으로 작동하지만, 디렉터리 스코프에서만 작동하도록 의도됐어요. 알려진 버그예요.
AzureBlobFileSystem.getFileStatus()는 루트("/") 경로에서Operation failed: "Server failed to authenticate the request."HTTP 401 Unauthorized Error로 실패할 것으로 예상돼요.
ABFS 테스트 (Testing ABFS)
Testing Azure의 관련 섹션을 참고하세요.
더 알아보기 (Learn more)
- 원문: 문서