hadoop-azure模块通过"abfs"连接器为Azure Data Lake Storage Gen2存储层提供支持
要将其作为Apache Hadoop默认类路径的一部分,请确保HADOOP_OPTIONAL_TOOLS环境变量列表中包含hadoop-azure,在集群中的每台机器上都需要进行此设置
export HADOOP_OPTIONAL_TOOLS=hadoop-azure
你可以在本地的.profile/.bashrc文件中设置此项,但请注意该设置不会传播到集群内运行的作业中。
wasb:连接器写入的数据。FileSystem接口,呈现分层文件系统视图。有关ABFS的详细信息,请查阅以下文档:
Azure 存储数据模型包含3个核心概念:
ABFS连接器可连接到经典容器或使用分层命名空间创建的容器。
ADLS Gen 2的一个关键特性是支持分层命名空间。这些实际上是目录,并提供高性能的重命名和删除操作——这显著提升了包括MapReduce、Spark、Hive以及DistCp在内的查询引擎写入数据的性能。
此功能仅在容器创建时启用了“命名空间”支持的情况下可用。
在创建新的存储账户时,您可以通过在门户界面勾选"分层命名空间"选项来启用命名空间支持,或者通过命令行创建时使用--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
关于使用abfs连接器开始使用Azure Datalake Gen2的最佳文档是Using Azure Data Lake Storage Gen2 with Azure HDInsight clusters
它包含从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 Data Lake Storage Gen2存储账户
关键步骤
您现在已经创建了存储账户。接下来,获取用于默认“共享密钥”认证的密钥。
一个Azure存储账户可以包含多个容器,每个容器的名称作为URI中用于引用它的userinfo字段。
例如,刚创建的存储账户中的容器“container1”将具有URL abfs://container1@abfswales1.dfs.core.windows.net/
您可以通过ABFS连接器创建新容器,只需将选项fs.azure.createRemoteFileSystemDuringInitialization设置为true。但当认证类型为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
启用远程文件系统创建,第二次尝试成功,同时创建容器:
$ hadoop fs -D fs.azure.createRemoteFileSystemDuringInitialization=true \ -ls abfs://container1@abfswales1.dfs.core.windows.net/
这在命令行上创建账户时非常有用,尤其是在az storage命令尚未完全支持分层命名空间的情况下。
你可以使用 Azure Storage Explorer
任何配置都可以通用指定(或作为访问所有账户时的默认设置),也可以绑定到特定账户。例如,可以配置一个OAuth身份,无论访问哪个账户都使用该身份,通过属性fs.azure.account.oauth2.client.id;或者也可以配置一个身份,仅用于特定的存储账户,通过fs.azure.account.oauth2.client.id.。
这在认证部分展示。
ABFS的认证最终由Azure Active Directory授予。
其中涉及的概念超出了本文档的范围;开发者需要阅读并理解其中的概念,才能充分利用不同的认证机制。
这里简要介绍了如何配置ABFS客户端以在不同部署场景中进行身份验证。
ABFS客户端可以通过不同方式进行部署,其身份验证需求取决于部署方式。
注意:基于SAS的身份验证应仅用于启用了HNS的账户。
可以更改的是用于验证调用者身份的秘密/凭据。
认证机制在fs.azure.account.auth.type(或特定账户的变体)中设置。可能的值为SharedKey、OAuth、Custom和SAS。对于各种OAuth选项,使用配置fs.azure.account.oauth.provider.type。以下是支持的实现:ClientCredsTokenProvider、UserPasswordTokenProvider、MsiTokenProvider、RefreshTokenBasedTokenProvider和WorkloadIdentityTokenProvider。如果指定的提供程序类型不受支持,则会抛出IllegalArgumentException。
所有密钥都可以存储在JCEKS文件中。这些文件经过加密和密码保护——尽可能使用它们或兼容的Hadoop密钥管理存储
用于AAD令牌获取重试的指数退避策略可以通过以下配置进行调整:* fs.azure.oauth.token.fetch.retry.max.retries:设置最大重试次数。默认值为5。* fs.azure.oauth.token.fetch.retry.min.backoff.interval:最小退避间隔。该值会与根据增量退避计算出的重试间隔相加。默认设置为0。以毫秒为单位设置该间隔。* fs.azure.oauth.token.fetch.retry.max.backoff.interval:最大退避间隔。默认值为60000(六十秒)。以毫秒为单位设置该间隔。* fs.azure.oauth.token.fetch.retry.delta.backoff:重试之间的退避间隔。该时间跨度的倍数将用于后续重试尝试。默认值为2。
这是最简单的账号+密码认证机制。
账户名从URL推断得出;密码“key”则从XML/JCECKs配置文件中获取。
<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>
注意: 账户密钥的来源可以通过自定义密钥提供程序进行更改;现有方案支持通过执行shell脚本来获取密钥。
可以通过配置fs.azure.account.keyprovider提供自定义密钥提供程序类。如果指定了密钥提供程序类,则将使用相同的类来获取账户密钥。否则将使用简单密钥提供程序,该提供程序将使用为配置fs.azure.account.key指定的密钥。
要通过shell脚本检索,请为配置项fs.azure.shellkeyprovider.script指定脚本路径。ShellDecryptionKeyProvider类将使用指定的脚本来检索密钥。
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>
配置/JCEKS文件中提供了OAuth 2.0端点、用户名和密码。
<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令牌,向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 Identities,前身为"托管服务身份"。
OAuth 2.0令牌由一个特殊端点颁发,该端点只能从执行中的虚拟机访问(http://169.254.169.254/metadata/identity/oauth2/token)。颁发的凭证可用于身份验证。
Azure门户/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>
Azure Workload Identities,前身为“Azure AD pod identity”。
OAuth 2.0令牌会被写入一个仅能从执行中的pod访问的文件(/var/run/secrets/azure/tokens/azure-identity-token)。颁发的凭证可用于身份验证。
Azure门户/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令牌提供程序会在调用其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。
声明的类还负责在获取访问令牌时实现重试逻辑。
委托令牌提供者通过实现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,则会抛出IlleagalArgumentException异常。
共享访问签名(SAS)可安全地委托访问您存储账户中的资源。通过SAS,您可以精细控制客户端如何访问数据。要了解更多关于SAS认证工作原理,请参阅使用共享访问签名(SAS)授予对Azure存储资源的有限访问权限
Azure存储支持三种类型的SAS: - 用户委托SAS:建议用于启用了HNS的ADLS Gen2账户与ABFS驱动程序配合使用。这是一种基于身份的SAS,可在blob/目录级别工作) - 服务SAS:全局有效,作用于容器级别。 - 账户SAS:全局有效,作用于账户级别。
描述: ABFS允许您实现自定义的SAS令牌提供程序,该程序使用您的身份创建用户委托密钥,然后可用于生成SAS而非存储账户密钥。声明的类必须实现org.apache.hadoop.fs.azurebfs.extensions.SASTokenProvider。
配置: 要在ABFS驱动中使用此方法,请在您的core-site.xml文件中指定以下属性:
认证类型:
fs.azure.account.auth.type SAS
自定义SAS令牌提供者类:
fs.azure.sas.token.provider.type CUSTOM_SAS_TOKEN_PROVIDER_CLASS
将CUSTOM_SAS_TOKEN_PROVIDER_CLASS替换为您自定义令牌提供程序实现的完全限定类名。根据具体实现,您可能需要指定自定义实现所需的其他配置。
示例: ABFS Hadoop驱动提供了一个MockDelegationSASTokenProvider实现,可作为如何实现自定义SASTokenProvider的参考范例。除了上述两项配置外,这还要求使用以下配置来指定应用程序凭据:
fs.azure.test.app.service.principal.tenant.id TENANT_ID
fs.azure.test.app.service.principal.object.id OBJECT_ID
fs.azure.test.app.id APPLICATION_ID
fs.azure.test.app.secret APPLICATION_SECRET
安全性:比共享密钥更安全,允许在不暴露访问密钥的情况下授予对数据的有限访问权限。建议仅与启用了HNS的ADLS Gen 2存储账户一起使用。
描述: ABFS允许用户使用账户/服务SAS进行请求认证。用户可以将其指定为固定SAS令牌,以便在所有请求中使用。
配置: 要在ABFS驱动中使用此方法,请在您的core-site.xml文件中指定以下属性:
认证类型:
fs.azure.account.auth.type SAS
固定SAS令牌:
fs.azure.sas.fixed.token FIXED_SAS_TOKEN
将FIXED_SAS_TOKEN替换为固定的账户/服务SAS。您也可以从Azure门户生成SAS。路径:账户 -> 安全+网络 -> 共享访问签名
安全性: 账户/服务SAS需要使用账户密钥,这使得其安全性较低。无法实现向不同用户委派访问权限。
注意: 当同时配置 fs.azure.sas.token.provider.type 和 fs.azure.fixed.sas.token 时,将优先使用自定义令牌提供程序实现。
该连接器使用JVM代理设置来控制其代理配置。
请参阅Oracle Java文档了解可设置的选项。
由于连接器默认使用HTTPS,因此必须配置https.proxyHost和https.proxyPort选项。
在MapReduce作业(包括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://backups@account.dfs.core.windows.net/users/alice
如果没有这些设置,即使从命令行可以访问ADLS,distcp访问也可能因网络错误而失败。
与其他对象存储系统一样,登录凭证是重要的敏感信息。企业应建立安全共享这些信息的流程。
fs.azure.enable.flush设置为true(默认=true),则支持Syncable接口的hsync()和hflush()操作。在Wasb连接器中,这将任一调用的次数限制为50,000次HADOOP-15478。如果abfs有类似的限制,则过度使用sync/flush可能会导致问题。与所有Azure存储服务一样,Azure Datalake Gen 2存储提供了完全一致的存储视图,对数据和元数据具有完整的创建、读取、更新和删除一致性。
对于具有分层命名空间的容器,其可扩展性数值(用大O符号表示)如下:
| 操作 | 可扩展性 |
|---|---|
| File Rename | O(1) |
| File Delete | O(1) |
| Directory Rename: | O(1) |
| Directory Delete | O(1) |
对于非命名空间存储,可扩展性变为:
| 操作 | 可扩展性 |
|---|---|
| File Rename | O(1) |
| File Delete | O(1) |
| Directory Rename: | O(files) |
| Directory Delete | O(files) |
也就是说:文件数量越多,目录操作就会变得越慢。
ABFS连接器支持一些有限的私有/不稳定扩展点,允许第三方将其认证和授权服务集成到ABFS客户端中。
CustomDelegationTokenManager : 添加了颁发Hadoop委托令牌的能力。SASTokenProvider: 允许自定义提供Azure存储共享访问签名(SAS)令牌。CustomTokenProviderAdaptee: 允许自定义提供Azure OAuth令牌。KeyProvider.请参考org.apache.hadoop.fs.azurebfs.extensions中的源代码及所有相关测试,了解如何利用这些扩展点。
警告 这些扩展点不稳定。
ABFS 驱动程序可以使用以下网络库:- ApacheHttpClient:- Library Documentation。- 默认网络库。- JDK 网络库:- Library documentation。
网络库可以在初始化文件系统时通过配置fs.azure.networking.library进行设置。以下是支持的值: - JDK_HTTP_URL_CONNECTION : 使用JDK网络库 [默认] - APACHE_HTTP_CLIENT : 使用Apache HttpClient
以下是文件系统初始化时可提供的ApacheHttpClient网络层配置选项:1. fs.azure.apache.http.client.idle.connection.ttl:1. 连接池中保持连接存活的最大空闲时间(毫秒)。如果连接在时限内未被重用,该连接将被关闭。2. 默认值:5000毫秒。2. fs.azure.apache.http.client.max.cache.connection.size:1. 文件系统实例连接池中可缓存的最大连接数。并发连接总数没有限制。2. 默认值:5。3. fs.azure.apache.http.client.max.io.exception.retries:1. 客户端在使用ApacheHttpClient网络层时,对单个请求因IOExceptions而重试的最大次数。超过此限制将导致当前JVM实例中禁用ApacheHttpClient库的后续使用。2. 默认值:3。
ApacheHttpClient是hadoop-azure中的一个compile Maven依赖项,会被包含在hadoop-azure jar包中。使用hadoop-azure与ApacheHttpClient时,classpath中不需要额外配置信息。
请查阅org.apache.hadoop.fs.azurebfs.constants.ConfigurationKeys、org.apache.hadoop.fs.azurebfs.constants.FileSystemConfigurations和org.apache.hadoop.fs.azurebfs.AbfsConfiguration的javadocs文档,获取完整的配置选项列表及其默认值。
配置 fs.azure.client.correlationid 提供了使用客户端提供的标识符来关联客户端请求的选项。该ID将在Azure存储分析日志的request-id-header字段中可见。参考:Storage Analytics log format
此配置接受一个最多72个字符的字符串,且只能包含字母数字字符和/或连字符。如果输入无效,则默认为空字符串。
配置 fs.azure.tracingcontext.format 提供了选择 request-id-header 中包含ID格式的选项。该配置接受与以下枚举选项对应的字符串值。SINGLE_ID_FORMAT : clientRequestId ALL_ID_FORMAT : 所有ID (默认) TWO_ID_FORMAT : clientCorrelationId:clientRequestId
配置 fs.azure.enable.flush 提供了将ABFS刷新API - HFlush()和HSync()设置为无操作的选项。默认情况下,此配置将设置为true。
这两个API都将确保数据被持久化。
配置 fs.azure.disable.outputstream.flush 提供了在 AbfsOutputStream 中将 OutputStream Flush() API 设为无操作的可选项。默认情况下,该配置将被设置为 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秒。
配置 fs.azure.account.hns.enabled 提供了指定存储账户是否启用HNS的选项。如果未提供该配置,则会发起服务器调用来进行验证。
需要将配置 fs.azure.enable.check.access 设为 true 以启用 AzureBlobFileSystem.access()。
由于服务器超时和网络故障导致的请求失败将会自动重试。PUT/POST操作具有幂等性,除重命名和删除操作外无需特殊处理。
重命名操作的幂等性检查通过确保在重试时若源路径不存在,则目标路径的LastModifiedTime是最新的来实现。
默认情况下,如果重试时目标不存在,则删除操作被视为幂等的。
如果将以下配置设置为true fs.azure.skipUserGroupMetadataDuringInitialization,则作为FileStatus和AclStatus组成部分的组名将被设置为与用户名相同。
以下配置与读写操作相关。
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相同的读取模式,因为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之间(包含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。
以下两个选项只能配置其中一个。如果同时设置了两种类型的配置值,ABFS驱动程序将抛出异常。如果使用全局密钥类型,请确保提供预先计算的两个值。
可以通过提供以下预计算值来配置全局加密密钥。该密钥将应用于设置配置后创建的任何新文件,并且在读取或修改文件内容的请求中需要该密钥。
fs.azure.encryption.encoded.client-provided-key: 256位加密密钥的Base64编码版本。
fs.azure.encryption.encoded.client-provided-key-sha: 256位加密密钥的SHA256哈希值的Base64编码版本。
ABFS驱动程序支持一个名为EncryptionContextProvider的接口,该接口可作为客户端插件为加密框架提供自定义实现。该框架允许通过EncryptionContextProvider为待创建文件生成encryptionContext和encryptionKey。服务器会记录每个文件的encryptionContext。当需要对加密文件执行读取等后续操作时,ABFS驱动程序将通过向服务器发起GetFileStatus请求获取encryptionContext字符串,并据此从EncryptionContextProvider实现中获取对应的加密密钥。
fs.azure.encryption.context.provider.type: 实现EncryptionContextProvider接口的类的规范名称。
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/
fs.azure.list.max.results: listStatus API以分页方式从服务器获取FileStatus信息。该配置用于设置maxResults URI参数,该参数决定了每页的大小(每次调用的最大结果数)。该值应大于0,默认值为5000。服务器对该参数设置的最大值也是5000,因此即使配置值超过5000,响应也只会包含5000条记录。更多信息请参考以下链接。https://docs.microsoft.com/en-us/rest/api/storageservices/datalakestoragegen2/path/list
fs.azure.enable.checksum.validation: 当该配置设为true时,读取和追加调用会向服务器发送Content-MD5头部信息。这提供了一种验证数据传输完整性的方法。由于需要在客户端和服务器端重新计算MD5哈希值,这会对性能产生影响。详情请参阅Azure文档中关于Read和Append API的部分
ABFS驱动程序具备通过限制读写操作来最大化吞吐量的能力,同时最小化错误。当超过账户的入口或出口限制时,服务器端会限制请求,从而导致错误发生。服务器端限制会触发重试策略,但重试策略会导致长时间的休眠,使得总入口或出口吞吐量比最优值低多达35%。此外,重试策略是在请求失败后才生效的被动措施。相比之下,此处实现的客户端限制机制会在请求发出前进行干预,仅休眠必要时间以最小化错误,从而实现最优的入口和/或出口吞吐量。默认情况下,驱动程序已启用此限制机制。可通过将配置项fs.azure.enable.autothrottling设为false来禁用该功能。
fs.azure.atomic.rename.key: 在此配置中可以用逗号分隔指定支持原子重命名的目录。如果重命名的源路径属于配置的目录之一,驱动程序会打印以下警告日志:"ABFS方案不支持原子重命名功能;但如果您的Azure存储账户启用了命名空间,则重命名、创建和删除操作都是原子性的。" 目录可以指定为逗号分隔的值。默认值为"/hbase"
fs.azure.infinite-lease.directories: 在此配置中可以用逗号分隔指定支持无限租约的目录。默认情况下,多个客户端可以同时写入同一个文件。当写入此配置中指定目录包含的文件时,客户端将获取该文件的租约,这将阻止其他任何客户端写入该文件。当输出流关闭时,租约将被释放。要撤销客户端对文件的写入权限,可以调用AzureBlobFilesystem的breakLease方法。如果客户端在文件关闭和租约释放前崩溃,则需要先调用breakLease方法,其他客户端才能写入该文件。
fs.azure.lease.threads: 这是用于无限租约目录租约操作的线程池大小。默认值为0,因此必须至少设置为1才能支持无限租约目录。
如果将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使用这些设置来跟踪其端到端延迟。
与连接器相关的问题通常归结为,按顺序
如果将org.apache.hadoop.fs.azurebfs.services的日志级别设为DEBUG,就能看到更多关于失败请求的详细信息。
一个用于调试连接性的有用工具是cloudstore storediag实用程序。
这会验证类路径和设置,然后尝试与文件系统交互。
bin/hadoop jar cloudstore-0.1-SNAPSHOT.jar storediag abfs://container@account.dfs.core.windows.net/
storediag命令无法与abfs存储配合使用,那么其他方法很可能也无法使用。storediag存储确实能正常工作,这并不能保证集群其余部分的类路径或配置也能正常工作,特别是在分布式应用中。但这至少是一个开始。ClassNotFoundException: org.apache.hadoop.fs.azurebfs.AzureBlobFileSystemhadoop-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.StorageErrorCodeazure-storage JAR文件不在类路径中。
Server failed to authenticate the request在使用默认共享密钥认证机制时,请求未通过认证。
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)
原因包括:
Configuration property _something_.dfs.core.windows.net not found您的集群配置中没有声明特定账户访问密钥的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.
尝试列出容器时提示"没有这样的文件或目录"没有找到指定名称的容器。可能是名称输入错误,或者该容器需要被创建。
$ hadoop fs -ls abfs://container@abfswales1.dfs.core.windows.net/ ls: `abfs://container@abfswales1.dfs.core.windows.net/': No such file or directory
text/html, text/plain, application/xmlOAuth认证页面没有返回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';
可能的原因包括配置和网络问题:
java.io.IOException: 暂存目录 /tmp/hadoop-yarn/staging/user1/.staging 的所有权不符合预期。当前所有者是 。该目录必须由提交者 user1 或 user1 拥有 在使用Azure托管身份时,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'所有。
以下是目前已知且预期会发生的故障。1. 当在根路径("/")上尝试使用AzureBlobFileSystem.setXAttr()和AzureBlobFileSystem.getXAttr()时,将会失败,并返回Operation failed: "The request URI is invalid.", HTTP 400 Bad Request错误。
请参阅Testing Azure中的相关章节。