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 中設定此本機,但請注意它不會傳播到群集中執行的作業。

ABFS 連接器的功能。

  • 支援讀取和寫入儲存在 Azure Blob Storage 帳戶中的資料。
  • 完全一致的儲存空間檢視,適用於所有客戶端。
  • 可以讀取透過 wasb: 連接器寫入的資料。
  • 透過實作標準 Hadoop FileSystem 介面,提供階層式檔案系統檢視。
  • 支援多個 Azure Blob Storage 帳戶的組態。
  • 可以在 Hadoop MapReduce、Apache Hive、Apache Spark 中作為資料的來源或目的地。
  • Microsoft 自行在 Linux 和 Windows 上大規模測試。
  • 可以用作部署在 Azure 基礎結構上的 Hadoop 群集中 HDFS 的替代方案。

有關 ABFS 的詳細資訊,請參閱下列文件

入門

概念

Azure Storage 資料模型提供 3 個核心概念

  • 儲存帳戶:所有存取都透過儲存帳戶進行。
  • 容器:容器是多個 blob 的群組。儲存帳戶可能有多個容器。在 Hadoop 中,整個檔案系統階層都儲存在單一容器中。
  • Blob:使用現有 wasb 連接器儲存的任何類型和大小的檔案

ABFS 連接器連線到傳統容器或使用階層式命名空間建立的容器。

階層式命名空間(和 WASB 相容性)

ADLS Gen 2 的一個主要方面是它支援 階層式命名空間。這些實際上是目錄,提供高效能的重新命名和刪除作業,這大幅改善了寫入資料的查詢引擎效能,包括 MapReduce、Spark、Hive,以及 DistCp。

此功能僅在使用「命名空間」支援建立容器時才可用。

您可以在建立新的儲存帳戶時啟用命名空間支援,方法是在入口網站 UI 中勾選「階層式命名空間」選項,或是在透過命令列建立時使用選項 --hierarchical-namespace true

您無法在現有的儲存帳戶上啟用階層式命名空間

具有階層式命名空間的儲存帳戶中的容器(目前)無法透過 wasb: 連接器讀取。

某些 az storage 命令列指令也會失敗,例如

$ az storage container list --account-name abfswales1
Blob API is not yet supported for hierarchical namespace accounts. ErrorCode: BlobApiNotYetSupportedForHierarchicalNamespaceAccounts

建立 Azure 儲存帳戶

使用 abfs 連接器開始使用 Azure Datalake Gen2 的最佳文件是 使用 Azure Data Lake Storage Gen2 搭配 Azure HDInsight 群集

其中包含從 Azure 命令列工具 建立它的說明,此工具可以安裝在 Windows、MacOS(透過 Homebrew)和 Linux(apt 或 yum)上。

az storage 子指令處理所有儲存指令,az storage account create 進行建立。

在 ADLS gen2 API 支援完成之前,您需要新增一個延伸模組到 ADLS 指令。

az extension add --name storage-preview

透過驗證使用指令包含 --hierarchical-namespace 來檢查一切是否正常

$  az storage account
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
Central US           41.5908     -93.6208     centralus
East US              37.3719     -79.8164     eastus
East US 2            36.6681     -78.3889     eastus2
West US              37.783      -122.417     westus
North Central US     41.8819     -87.6278     northcentralus
South Central US     29.4167     -98.5        southcentralus
North Europe         53.3478     -6.2597      northeurope
West Europe          52.3667     4.9          westeurope
Japan West           34.6939     135.5022     japanwest
Japan East           35.68       139.77       japaneast
Brazil South         -23.55      -46.633      brazilsouth
Australia East       -33.86      151.2094     australiaeast
Australia Southeast  -37.8136    144.9631     australiasoutheast
South India          12.9822     80.1636      southindia
Central India        18.5822     73.9197      centralindia
West India           19.088      72.868       westindia
Canada Central       43.653      -79.383      canadacentral
Canada East          46.817      -71.217      canadaeast
UK South             50.941      -0.799       uksouth
UK West              53.427      -3.084       ukwest
West Central US      40.890      -110.234     westcentralus
West US 2            47.233      -119.852     westus2
Korea Central        37.5665     126.9780     koreacentral
Korea South          35.1796     129.0756     koreasouth
France Central       46.3772     2.3730       francecentral
France South         43.8345     2.1972       francesouth
Australia Central    -35.3075    149.1244     australiacentral
Australia Central 2  -35.3075    149.1244     australiacentral2

選取位置後,建立帳戶

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=ZGlkIHlvdSByZWFsbHkgdGhpbmsgSSB3YXMgZ29pbmcgdG8gcHV0IGEga2V5IGluIGhlcmU/IA=="
}

然後您需要將存取金鑰新增至 core-site.xml、JCEKs 檔案,或使用叢集管理工具將選項 fs.azure.account.key.STORAGE-ACCOUNT 設定為此值。

<property>
  <name>fs.azure.account.key.abfswales1.dfs.core.windows.net</name>
  <value>ZGlkIHlvdSByZWFsbHkgdGhpbmsgSSB3YXMgZ29pbmcgdG8gcHV0IGEga2V5IGluIGhlcmU/IA==</value>
</property>

透過 Azure 入口網站建立

入口網站建立的說明在 快速入門:建立 Azure Data Lake Storage Gen2 儲存體帳戶

主要步驟

  1. 在適合您的位置建立新的儲存體帳戶。
  2. 「基本資料」標籤:選取「StorageV2」。
  3. 「進階」標籤:啟用「階層式命名空間」。

您現在已建立儲存體帳戶。接下來,取得金鑰進行驗證,以使用預設的「共用金鑰」驗證。

  1. 前往 Azure 入口網站。
  2. 選取「儲存體帳戶」
  3. 選取新建立的儲存體帳戶。
  4. 在設定清單中,找到「存取金鑰」並選取它。
  5. 將其中一個存取金鑰複製到剪貼簿,新增至 XML 選項,設定在叢集管理工具、Hadoop JCEKS 檔案或 KMS 儲存體中。

建立新容器

一個 Azure 儲存體帳戶可以有多個容器,每個容器的容器名稱為用於參考它的 URI 的使用者資訊欄位。

例如,剛建立的儲存體帳戶中的容器「container1」將有 URL abfs://container1@abfswales1.dfs.core.windows.net/

您可以透過將選項 fs.azure.createRemoteFileSystemDuringInitialization 設定為 true,透過 ABFS 連接器建立新容器。不過,當 AuthType 為 SAS 時不支援相同設定。

如果容器不存在,嘗試使用 hadoop fs -ls 列出它將會失敗

$ hadoop fs -ls abfs://container1@abfswales1.dfs.core.windows.net/

ls: `abfs://container1@abfswales1.dfs.core.windows.net/': No such file or directory

啟用遠端 FS 建立,第二次嘗試成功,在建立容器時也會這樣做

$ hadoop fs -D fs.azure.createRemoteFileSystemDuringInitialization=true \
 -ls abfs://container1@abfswales1.dfs.core.windows.net/

這對於在命令列上建立帳戶很有用,特別是在 az storage 指令完全支援階層式命名空間之前。

列出和檢查儲存帳戶的容器。

您可以使用 Azure Storage Explorer

設定 ABFS

任何設定通常可以指定 (或在存取所有帳戶時指定為預設值),或者可以與特定帳戶連結。例如,OAuth 身分可以設定為不論使用哪個帳戶存取,都使用屬性 fs.azure.account.oauth2.client.id,或者您可以設定身分僅用於特定儲存帳戶,使用 fs.azure.account.oauth2.client.id.<account_name>.dfs.core.windows.net

這顯示在驗證部分。

驗證

ABFS 的驗證最終由 Azure Active Directory 授予。

這裡涵蓋的概念超出了本文檔的範圍;預期開發人員已閱讀並了解其中的概念,才能利用不同的驗證機制。

這裡簡要介紹如何設定 ABFS 用戶端,以便在不同的部署情況下進行驗證。

ABFS 用戶端可以透過不同的方式部署,其驗證需求由這些方式驅動。

  1. 在設定中使用儲存帳戶的驗證機密:「共用金鑰」。
  2. 使用某種形式的 OAuth 2.0 令牌。
  3. 在 Azure 中部署,Azure VM 提供 OAuth 2.0 令牌給應用程式,「受控執行個體」。
  4. 使用由 SASTokenProvider 介面的自訂實作提供的共用存取簽章 (SAS) 令牌。

可以變更的是用於驗證呼叫者的機密/憑證。

驗證機制設定在 fs.azure.account.auth.type (或特定帳戶變體) 中。可能的數值為 SharedKey、OAuth、Custom 和 SAS。對於各種 OAuth 選項,請使用設定 fs.azure.account .oauth.provider.type。以下是支援的實作 ClientCredsTokenProvider、UserPasswordTokenProvider、MsiTokenProvider 和 RefreshTokenBasedTokenProvider。如果指定的提供者類型不是其中一種支援的類型,將擲回 IllegalArgumentException。

所有機密都可以儲存在 JCEKS 檔案中。這些檔案經過加密和密碼保護,請盡可能使用它們或相容的 Hadoop 金鑰管理儲存。

AAD 令牌擷取重試

用於 AAD 令牌擷取重試的指數重試原則可透過下列組態進行調整。* fs.azure.oauth.token.fetch.retry.max.retries:設定最大重試次數。預設值為 5。* fs.azure.oauth.token.fetch.retry.min.backoff.interval:最小延後間隔。新增到從 delta 延後計算的重試間隔。預設設定為 0。將間隔設定為毫秒。* fs.azure.oauth.token.fetch.retry.max.backoff.interval:最大延後間隔。預設值為 60000(六十秒)。將間隔設定為毫秒。* fs.azure.oauth.token.fetch.retry.delta.backoff:重試之間的延後間隔。此時間範圍的倍數用於後續重試嘗試。預設值為 2。

預設:共用金鑰

這是帳戶 + 密碼最簡單的驗證機制。

帳戶名稱會從 URL 推斷;密碼「金鑰」會從 XML/JCECK 組態檔中擷取。

<property>
  <name>fs.azure.account.auth.type.abfswales1.dfs.core.windows.net</name>
  <value>SharedKey</value>
  <description>
  </description>
</property>
<property>
  <name>fs.azure.account.key.abfswales1.dfs.core.windows.net</name>
  <value>ZGlkIHlvdSByZWFsbHkgdGhpbmsgSSB3YXMgZ29pbmcgdG8gcHV0IGEga2V5IGluIGhlcmU/IA==</value>
  <description>
  The secret password. Never share these.
  </description>
</property>

注意:帳戶金鑰的來源可透過自訂金鑰提供者變更;其中一個存在於執行 shell 腳本以擷取金鑰。

自訂金鑰提供者類別可透過組態 fs.azure.account.keyprovider 提供。如果指定金鑰提供者類別,將使用相同的類別取得帳戶金鑰。否則,將使用簡單金鑰提供者,它會使用為組態 fs.azure.account.key 指定的金鑰。

若要使用 shell 腳本來擷取,請為組態 fs.azure.shellkeyprovider.script 指定腳本路徑。ShellDecryptionKeyProvider 類別會使用指定的腳本來擷取金鑰。

OAuth 2.0 應用程式憑證

OAuth 2.0 憑證(應用程式 ID、應用程式密碼、端點)會在組態/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></value>
  <description>
  URL of OAuth endpoint
  </description>
</property>
<property>
  <name>fs.azure.account.oauth2.client.id</name>
  <value></value>
  <description>
  Client ID
  </description>
</property>
<property>
  <name>fs.azure.account.oauth2.client.secret</name>
  <value></value>
  <description>
  Secret
  </description>
</property>

OAuth 2.0:使用者名稱和密碼

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></value>
  <description>
  URL of OAuth 2.0 endpoint
  </description>
</property>
<property>
  <name>fs.azure.account.oauth2.user.name</name>
  <value></value>
  <description>
  username
  </description>
</property>
<property>
  <name>fs.azure.account.oauth2.user.password</name>
  <value></value>
  <description>
  password for account
  </description>
</property>

OAuth 2.0:更新令牌

使用現有的 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></value>
  <description>
  Refresh token
  </description>
</property>
<property>
  <name>fs.azure.account.oauth2.refresh.endpoint</name>
  <value></value>
  <description>
  Refresh token endpoint
  </description>
</property>
<property>
  <name>fs.azure.account.oauth2.client.id</name>
  <value></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></value>
  <description>
  Optional MSI Tenant ID
  </description>
</property>
<property>
  <name>fs.azure.account.oauth2.msi.endpoint</name>
  <value></value>
  <description>
   MSI endpoint
  </description>
</property>
<property>
  <name>fs.azure.account.oauth2.client.id</name>
  <value></value>
  <description>
  Optional Client ID
  </description>
</property>

自訂 OAuth 2.0 令牌提供者

自訂 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></value>
  <description>
  classname of Custom Authentication Provider
  </description>
</property>

宣告的類別必須實作 org.apache.hadoop.fs.azurebfs.extensions.CustomTokenProviderAdaptee,以及選擇性實作 org.apache.hadoop.fs.azurebfs.extensions.BoundDTExtension

宣告的類別也負責在擷取存取令牌時實作重試邏輯。

委派令牌提供者

委派令牌提供者會提供 ABFS 連接器委派令牌,並透過實作 CustomDelegationTokenManager 介面來協助更新和取消令牌。

<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,則會擲回 IlleagalArgumentException。

共享存取簽章 (SAS) 令牌提供者

共享存取簽章 (SAS) 令牌提供者會透過實作 SASTokenProvider 介面來提供 ABFS 連接器 SAS 令牌。

<property>
  <name>fs.azure.account.auth.type</name>
  <value>SAS</value>
</property>
<property>
  <name>fs.azure.sas.token.provider.type</name>
  <value>{fully-qualified-class-name-for-implementation-of-SASTokenProvider-interface}</value>
</property>

宣告的類別必須實作 org.apache.hadoop.fs.azurebfs.extensions.SASTokenProvider

技術注意事項

Proxy 設定

連接器使用 JVM proxy 設定來控制其 proxy 設定。

請參閱 Oracle Java 文件 以取得可設定的選項。

由於連接器預設使用 HTTPS,因此必須設定 https.proxyHosthttps.proxyPort 選項。

在 MapReduce 作業中,包括 distcp,必須在 mapreduce.map.java.optsmapreduce.reduce.java.opts 中設定 proxy 選項。

# 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://backups@account.dfs.core.windows.net/users/alice

即使從命令列存取 ADLS 可行,但如果不設定這些設定,distcp 存取可能會因網路錯誤而失敗。

安全性

與其他物件儲存體一樣,登入機密是重要的資訊。組織應有一個安全分享這些資訊的流程。

ABFS 連接器的限制

  • 不會追蹤檔案最後存取時間。
  • 不支援延伸屬性。
  • 不支援檔案檢查碼。
  • 如果將 fs.azure.enable.flush 設為 true(預設值=true),則支援 Syncable 介面 hsync()hflush() 作業。使用 Wasb 連接器時,這會將這兩個呼叫的次數限制為 50,000 HADOOP-15478。如果 abfs 有類似的限制,則過度使用同步/快取可能會導致問題。

一致性和並行性

與所有 Azure 儲存服務一樣,Azure Datalake Gen 2 儲存體提供儲存體的完全一致性檢視,並為資料和元資料提供完整的建立、讀取、更新和刪除一致性。

效能和可擴充性

對於具有階層式命名空間的容器,可擴充性數字如下所示,以大 O 符號表示

作業 可擴充性
檔案重新命名 O(1)
檔案刪除 O(1)
目錄重新命名 O(1)
目錄刪除 O(1)

對於非命名空間儲存體,可擴充性變為

作業 可擴充性
檔案重新命名 O(1)
檔案刪除 O(1)
目錄重新命名 O(files)
目錄刪除 O(files)

也就是說:檔案越多,目錄作業的速度就越慢。

進一步閱讀:Azure Storage 可擴充性目標

可延伸性

ABFS 連接器支援許多有限的私有/不穩定的延伸點,供第三方將其驗證和授權服務整合到 ABFS 用戶端中。

  • CustomDelegationTokenManager:新增發出 Hadoop 委派權杖的能力。
  • SASTokenProvider:允許自訂提供 Azure Storage 共享存取簽章 (SAS) 權杖。
  • CustomTokenProviderAdaptee:允許自訂提供 Azure OAuth 權杖。
  • KeyProvider.

請參閱 org.apache.hadoop.fs.azurebfs.extensions 中的來源和所有相關測試,以了解如何使用這些延伸點。

警告 這些延伸點不穩定。

其他組態選項

請參閱 org.apache.hadoop.fs.azurebfs.constants.ConfigurationKeysorg.apache.hadoop.fs.azurebfs.constants.FileSystemConfigurationsorg.apache.hadoop.fs.azurebfs.AbfsConfiguration 的 javadoc,以取得組態選項和其預設值的完整清單。

用戶端關聯選項

1. 用戶端關聯識別碼選項

設定檔 fs.azure.client.correlationid 提供一個選項,可使用這個由用戶端提供的識別碼關聯用戶端要求。這個識別碼將會顯示在 Azure Storage Analytics 記錄檔的 request-id-header 欄位中。參考:Storage Analytics 記錄檔格式

此設定接受最多 72 個字元的字串,且只能包含英數字元和/或連字號。如果輸入無效,預設為空字串。

1. 相關性識別碼顯示選項

設定檔 fs.azure.tracingcontext.format 提供一個選項,用於選取包含在 request-id-header 中的識別碼格式。此設定檔接受一個字串值,對應下列列舉選項。SINGLE_ID_FORMAT:clientRequestId ALL_ID_FORMAT:所有識別碼(預設)TWO_ID_FORMAT:clientCorrelationId:clientRequestId

沖刷選項

1. Azure Blob 檔案系統沖刷選項

設定檔 fs.azure.enable.flush 提供一個選項,用於將 ABFS 沖刷 API(HFlush() 和 HSync())設定為無作用。預設情況下,此設定檔會設為 true。

這兩個 API 都會確保資料持續存在。

2. OutputStream 沖刷選項

設定檔 fs.azure.disable.outputstream.flush 提供一個選項,用於將 OutputStream Flush() API 設定為在 AbfsOutputStream 中無作用。預設情況下,此設定檔會設為 true。

由於 Hflush() 是唯一可提供持續資料傳輸的已記錄 API,因此 Flush() 也嘗試持續儲存緩衝資料,這將導致效能問題。

百續選項

fs.azure.account.expect.header.enabled:此設定參數用於指定您是否希望在每個附加要求中傳送 expect 100 continue 標頭。預設設定為 true。此旗標會設定用戶端在從輸出串流上傳資料區塊之前,先向 Azure 儲存體檢查。這允許用戶端在實際嘗試上傳區塊之前,優雅地降低頻寬。在實驗中,這在負載繁重的情況下提供了顯著的吞吐量改善。更多資訊:- https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Expect

帳戶層級限制選項

fs.azure.account.operation.idle.timeout:此值指定分析器(讀取或寫入)的計時器在沒有提出新要求之前應暫停的時間。其預設值為 60 秒。

HNS 檢查選項

設定檔 fs.azure.account.hns.enabled 提供一個選項,用於指定儲存體帳戶是否已啟用 HNS。如果未提供設定檔,則會呼叫伺服器來檢查。

存取選項

設定 fs.azure.enable.check.access 為 true 以啟用 AzureBlobFileSystem.access()。

作業冪等性

因伺服器逾時和網路故障而失敗的要求將會重試。PUT/POST 作業是冪等的,除了 Rename 和 Delete 作業之外,不需要任何特定處理。

Rename 冪等性檢查會透過確保目標的 LastModifiedTime 為最近時間來進行,如果在重試時發現來源路徑不存在。

如果在重試時目標不存在,預設會將 Delete 視為冪等的。

主要使用者群組選項

如果將下列設定設為 true,則 FileStatus 和 AclStatus 中的群組名稱將會設定為與使用者名稱相同 fs.azure.skipUserGroupMetadataDuringInitialization

IO 選項

下列設定與讀取和寫入作業有關。

fs.azure.io.retry.max.retries:設定 IO 作業的重試次數。目前這僅用於伺服器呼叫重試邏輯。在 AbfsClient 類別中使用,作為 ExponentialRetryPolicy 的一部分。值應大於或等於 0。

fs.azure.io.retry.min.backoff.interval:設定 IO 作業重試的最小延遲間隔。目前這僅用於伺服器呼叫重試邏輯。在 AbfsClient 類別中使用,作為 ExponentialRetryPolicy 的一部分。此值表示在重試 IO 作業之前等待的最小間隔(以毫秒為單位)。預設值為 3000(3 秒)。

fs.azure.io.retry.max.backoff.interval:設定 IO 作業重試的最大延遲間隔。目前這僅用於伺服器呼叫重試邏輯。在 AbfsClient 類別中使用,作為 ExponentialRetryPolicy 的一部分。此值表示在重試 IO 作業之前等待的最大間隔(以毫秒為單位)。預設值為 30000(30 秒)。

fs.azure.io.retry.backoff.interval:設定 IO 作業重試的預設延遲間隔。目前這僅用於伺服器呼叫重試邏輯。在 AbfsClient 類別中使用,作為 ExponentialRetryPolicy 的一部分。此值用於計算指定值 80% 到 120% 之間的隨機增量。然後將此隨機增量乘以目前 IO 重試次數的指數(亦即,預設值乘以 2^(retryNum - 1)),然後限制在 [fs.azure.io.retry.min.backoff.interval, fs.azure.io.retry.max.backoff.interval] 範圍內,以確定在下一次 IO 重試嘗試之前等待的時間長度。預設值為 3000(3 秒)。

fs.azure.write.request.size:設定寫入緩衝區大小。以位元組為單位指定值。值應介於 16384 到 104857600 之間(含)(16 KB 到 100 MB)。預設值為 8388608(8 MB)。

fs.azure.read.request.size:設定讀取緩衝區大小。以位元組為單位指定值。值應介於 16384 到 104857600 之間(含)(16 KB 到 100 MB)。預設值為 4194304(4 MB)。

fs.azure.read.alwaysReadBufferSize:僅當讀取以順序模式進行時,才會遵守由 fs.azure.read.request.size 設定的讀取請求大小。當偵測到讀取模式為隨機時,讀取大小會與呼叫程序提供的緩衝區長度相同。當此設定設為 true 時,會強制隨機讀取也以與順序讀取相同的請求大小進行讀取。這是為了讓讀取模式與 ADLS Gen1 相同,因為它不會區分讀取模式,而且總是根據設定的讀取請求大小進行讀取。此設定的預設值為 false,其中在偵測到隨機讀取模式時,會針對提供的緩衝區長度進行讀取。

fs.azure.readaheadqueue.depth:設定 AbfsInputStream 中的預讀取佇列深度。如果設定的值為負值,則預讀取佇列深度會設為 Runtime.getRuntime().availableProcessors()。預設值為 2。若要停用預讀取,請將此值設為 0。如果您的工作負載只進行隨機讀取(非順序),或者您看到流量限制,您可以嘗試將此值設為 0。

fs.azure.read.readahead.blocksize:設定預讀取的讀取緩衝區大小。以位元組為單位指定值。值應介於 16384 到 104857600 之間(含 16 KB 到 100 MB)。預設值為 4194304(4 MB)。

fs.azure.buffered.pread.disable:預設情況下,位置讀取 API 會在輸入串流上進行尋找和讀取。此讀取會填滿 AbfsInputStream 中的緩衝區快取,並更新游標位置。如果此最佳化為 true,它會略過緩衝區的使用,並執行無鎖定的 REST 呼叫以從 blob 進行讀取。此最佳化對於 HBase 類型的共享 AbfsInputStream 實例上的短隨機讀取非常有幫助。注意:這不是可以在叢集層級設定的設定。它可以用作 FutureDataInputStreamBuilder 上的選項。請參閱 FileSystem#openFile(Path path)

若要在有限的記憶體情況下執行,請設定下列設定。特別是在同一個程序有太多寫入時。

fs.azure.write.max.concurrent.requests:設定 AbfsOutputStream 實例在任何時間點對伺服器發出的最大同時寫入請求。這實際上會是 AbfsOutputStream 實例內的執行緒池大小。將值設定在 1 到 8 之間(含)。

fs.azure.write.max.requests.to.queue:設定可排入佇列的最大寫入要求。考慮到每個排入佇列的要求都包含一個緩衝區,可以使用此設定調整 AbfsOutputStream 執行個體的記憶體使用量。將值設定為 s.azure.write.max.concurrent.requests 所設定值的 3 或 4 倍。

fs.azure.analysis.period:分析指標後重新計算睡眠時間的間隔。其預設值為 10 秒。

安全性選項

fs.azure.always.use.https:將旗標設為 true 時,強制使用 HTTPS 而非 HTTP。無論旗標為何,如果使用安全方案 (ABFSS) 或使用 OAuth 進行驗證,AbfsClient 都會使用 HTTPS。預設情況下,這將設為 true。

fs.azure.ssl.channel.mode:使用指定的 SSL 通道模式初始化 DelegatingSSLSocketFactory。值應為列舉 DelegatingSSLSocketFactory.SSLChannelMode。預設值為 DelegatingSSLSocketFactory.SSLChannelMode.Default。

伺服器選項

當設定 fs.azure.io.read.tolerate.concurrent.append 為 true 時,傳送至伺服器的 If-Match 標頭會設定為 *,否則會設定為 ETag。這基本上是一種處理樂觀並行讀取的機制。請參閱以下連結以取得更多資訊。1. https://docs.microsoft.com/en-us/rest/api/storageservices/datalakestoragegen2/path/read 2. https://azure.microsoft.com/de-de/blog/managing-concurrency-in-microsoft-azure-storage-2/

listStatus API 以逐頁方式從伺服器擷取 FileStatus 資訊。設定 fs.azure.list.max.results 用於設定 maxResults URI 參數,它會設定頁面大小(每個呼叫的最大結果數)。值應大於 0。預設情況下,這將為 5000。伺服器對此參數的最大值為 5000。因此,即使設定大於 5000,回應也只會包含 5000 個項目。請參閱以下連結以取得更多資訊。 https://docs.microsoft.com/en-us/rest/api/storageservices/datalakestoragegen2/path/list

限制選項

ABFS 驅動程式有能力限制讀取和寫入作業,藉由將錯誤降至最低來達到最大處理量。當帳戶流入或流出限制超過時,就會發生錯誤,而伺服器端會限制要求。伺服器端限制會導致使用重試原則,但重試原則會休眠很長一段時間,導致總流入或流出處理量比最佳值低達 35%。重試原則也是事後才執行,也就是在要求失敗後才套用。另一方面,這裡實作的客戶端限制會在提出要求之前執行,並且只休眠足夠的時間來將錯誤降至最低,讓流入和/或流出處理量達到最佳化。預設情況下,驅動程式中已啟用限制機制。可以透過將設定 fs.azure.enable.autothrottling 設為 false 來停用它。

重新命名選項

fs.azure.atomic.rename.key:支援原子重新命名的目錄可以在此設定中以逗號分隔的方式指定。如果重新命名的來源屬於其中一個已設定的目錄,驅動程式會印出下列警告記錄:「ABFS 方案不支援原子重新命名功能;但是,如果已為 Azure Storage 帳戶啟用名稱空間,則重新命名、建立和刪除作業會是原子的。」目錄可以逗號分隔的值指定。預設值為「/hbase」

無限租約選項

fs.azure.infinite-lease.directories:支援無限租約的目錄可以在此設定中以逗號分隔指定。預設情況下,多個用戶端可以同時寫入同一個檔案。當寫入此設定中指定的目錄所包含的檔案時,用戶端會取得檔案的租約,以防止任何其他用戶端寫入檔案。當輸出串流關閉時,租約將會釋放。若要撤銷用戶端對檔案的寫入存取權,可以呼叫 AzureBlobFilesystem breakLease 方法。如果用戶端在檔案關閉和租約釋放之前終止,則需要在其他用戶端可以寫入檔案之前呼叫 breakLease。

fs.azure.lease.threads:這是將用於無限租約目錄租約作業的執行緒池大小。預設值為 0,因此必須設定為至少 1 才能支援無限租約目錄。

效能選項

1. HTTP 要求追蹤選項

如果您將 fs.azure.abfs.latency.track 設定為 true,模組會開始追蹤 ABFS HTTP 流量的效能指標。若要在您的機器或叢集上取得這些數字,您還需要在 log4j 設定中為 AbfsPerfTracker 類別啟用偵錯記錄。典型的效能記錄行如下所示

h=KARMA t=2019-10-25T20:21:14.518Z a=abfstest01.dfs.core.windows.net
c=abfs-testcontainer-84828169-6488-4a62-a875-1e674275a29f cr=delete ce=deletePath
r=Succeeded l=32 ls=32 lc=1 s=200 e= ci=95121dae-70a8-4187-b067-614091034558
ri=97effdcf-201f-0097-2d71-8bae00000000 ct=0 st=0 rt=0 bs=0 br=0 m=DELETE
u=https%3A%2F%2Fabfstest01.dfs.core.windows.net%2Ftestcontainer%2Ftest%3Ftimeout%3D90%26recursive%3Dtrue

欄位定義如下

h:主機名稱 t:記錄此要求的時間 a:Azure 儲存體帳戶名稱 c:容器名稱 cr:呼叫者方法名稱 ce:受呼叫者方法名稱 r:結果(成功/失敗) l:延遲時間(花費在受呼叫者上的時間) ls:延遲時間總和(花費在呼叫者上的總時間;在有多個受呼叫者時記錄;與最後一個受呼叫者一起記錄) lc:延遲時間計數(受呼叫者數量;在有多個受呼叫者時記錄;與最後一個受呼叫者一起記錄) s:HTTP 狀態碼 e:錯誤碼 ci:用戶端要求 ID ri:伺服器要求 ID ct:連線時間(毫秒) st:傳送時間(毫秒) rt:接收時間(毫秒) bs:傳送的位元組 br:接收的位元組 m:HTTP 方法(GET、PUT 等) u:編碼的 HTTP URL

請注意,這些效能數字也會在後續要求中以 x-ms-abfs-client-latency HTTP 標頭傳送回 ADLS Gen 2 API 端點。Azure 使用這些設定追蹤其端對端延遲時間。

疑難排解

與連接器相關的問題通常會依序發生

  1. 類別路徑。
  2. 網路設定(代理伺服器等)。
  3. 驗證和授權。
  4. 其他任何事項。

如果您在 DEBUG 中記錄 org.apache.hadoop.fs.azurebfs.services,您將會看到有關任何失敗要求的更多詳細資訊。

用於除錯連線的一個有用工具是 cloudstore storediag 輔助程式

這會驗證類別路徑、設定,然後嘗試使用檔案系統。

bin/hadoop jar cloudstore-0.1-SNAPSHOT.jar storediag abfs://container@account.dfs.core.windows.net/
  1. 如果 storediag 指令無法使用 abfs 儲存,其他指令可能也無法使用。
  2. 如果 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)
  at org.apache.hadoop.fs.FileSystem.access$200(FileSystem.java:136)
  at org.apache.hadoop.fs.FileSystem$Cache.getInternal(FileSystem.java:3373)
  at org.apache.hadoop.fs.FileSystem$Cache.get(FileSystem.java:3341)
  at org.apache.hadoop.fs.FileSystem.get(FileSystem.java:491)
  at org.apache.hadoop.fs.Path.getFileSystem(Path.java:361)
Caused by: java.lang.ClassNotFoundException:
    Class org.apache.hadoop.fs.azurebfs.AzureBlobFileSystem not found
  at org.apache.hadoop.conf.Configuration.getClassByName(Configuration.java:2529)
  at org.apache.hadoop.conf.Configuration.getClass(Configuration.java:2623)
  ... 16 more

提示:如果這發生在命令列中,您可以開啟 hadoop 腳本的除錯記錄

export HADOOP_SHELL_SCRIPT_DEBUG=true

如果這發生在群集中執行的應用程式中,表示群集(某種程度上)需要進行組態,以便 hadoop-azure 模組和依賴項位於已部署應用程式的類別路徑中。

ClassNotFoundException: com.microsoft.azure.storage.StorageErrorCode

azure-storage JAR 不在類別路徑中。

伺服器無法驗證要求

在使用預設共用金鑰驗證機制時,要求未通過驗證。

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)
  at org.apache.hadoop.fs.azurebfs.AzureBlobFileSystemStore.getFilesystemProperties(AzureBlobFileSystemStore.java:259)
  at org.apache.hadoop.fs.azurebfs.AzureBlobFileSystem.fileSystemExists(AzureBlobFileSystem.java:859)
  at org.apache.hadoop.fs.azurebfs.AzureBlobFileSystem.initialize(AzureBlobFileSystem.java:110)

原因包括

  • 您的憑證不正確。
  • 您的共用機密已過期。在 Azure 中,這會自動發生
  • 您的共用機密已被撤銷。
  • 主機/VM 時鐘漂移表示您的用戶端時鐘與 Azure 伺服器不同步 — 呼叫遭到拒絕,因為它已過時(視為重播)或來自未來。修正方式:檢查您的時鐘等。

組態屬性 _something_.dfs.core.windows.net 未找到

叢集設定中沒有宣告特定帳戶存取金鑰的 fs.azure.account.key. 項目,或者您使用錯誤的 URL

$ hadoop fs -ls abfs://container@abfswales2.dfs.core.windows.net/

ls: Configuration property abfswales2.dfs.core.windows.net not found.
  • 請確認 URL 正確無誤
  • 新增遺失的帳戶金鑰。

列出容器時出現「找不到此類檔案或目錄」

沒有名稱相同的容器。可能是輸入錯誤,或需要建立容器。

$ hadoop fs -ls abfs://container@abfswales1.dfs.core.windows.net/

ls: `abfs://container@abfswales1.dfs.core.windows.net/': No such file or directory
  • 請確認 URL 正確無誤
  • 視需要建立容器

「與 https://login.microsoftonline.com/某個 的 HTTP 連線,無法從 AzureAD 取得トークン。Http 回應:200 OK」

  • 內容類型為 text/htmltext/plainapplication/xml

OAuth 驗證頁面並未傳回 HTTP 錯誤代碼,但它也沒有傳回 JSON

$ bin/hadoop fs -ls abfs://container@abfswales1.dfs.core.windows.net/

 ...

ls: HTTP Error 200;
  url='https://login.microsoftonline.com/02a07549-0a5f-4c91-9d76-53d172a638a2/oauth2/authorize'
  AADToken: HTTP connection to
  https://login.microsoftonline.com/02a07549-0a5f-4c91-9d76-53d172a638a2/oauth2/authorize
  failed for getting token from AzureAD.
  Unexpected response.
  Check configuration, URLs and proxy settings.
  proxies=none;
  requestId='dd9d526c-8b3d-4b3f-a193-0cf021938600';
  contentType='text/html; charset=utf-8';

可能是設定和網路問題

  1. 驗證失敗,呼叫端會收到 Azure Active Directory 的人類登入頁面,即使呼叫端是機器。
  2. URL 錯誤,指向與 OAuth2.0 無關的網頁
  3. 中間有代理伺服器,嘗試傳回有用的指示

java.io.IOException: 暫存目錄 /tmp/hadoop-yarn/staging/user1/.staging 的擁有權與預期不同。它屬於 <principal_id>。此目錄必須屬於提交者 user1 或 user1

使用 Azure Managed Identities 時,ADLS Gen2 中的檔案/目錄預設會屬於服務主體物件 ID,也就是主體 ID,而以本機作業系統使用者「user1」提交工作會產生上述例外狀況。

解決方法是模擬本機作業系統使用者的擁有權,將下列屬性新增至 core-site.xml

<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://container1@abfswales1.dfs.core.windows.net/ 會顯示 ADLS Gen2 檔案/目錄現在屬於「user1」。

測試 ABFS

請參閱 測試 Azure 中相關的部分。