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。
仅当容器使用“命名空间”支持创建时,此功能才可用。
在创建新的存储帐户时,可以通过选中门户 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
有关使用 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 Data Lake Storage Gen2 存储帐户 中
主要步骤
您现在已创建存储帐户。接下来,获取用于使用默认“共享密钥”身份验证的身份验证密钥。
一个 Azure 存储帐户可以有多个容器,每个容器的容器名称作为 URI 的 userinfo 字段来引用它。
例如,刚创建的存储帐户中的容器“container1”将具有 URL abfs://[email protected]/
您可以通过将选项 fs.azure.createRemoteFileSystemDuringInitialization
设置为 true
来通过 ABFS 连接器创建新容器。但当 AuthType 为 SAS 时不支持相同内容。
如果容器不存在,则尝试使用 hadoop fs -ls
列出它将失败
$ hadoop fs -ls abfs://[email protected]/ ls: `abfs://[email protected]/': No such file or directory
启用远程文件系统创建,第二次尝试成功,同时创建容器
$ hadoop fs -D fs.azure.createRemoteFileSystemDuringInitialization=true \ -ls abfs://[email protected]/
这对于在命令行上创建帐户非常有用,尤其是在 az storage
命令完全支持分层命名空间之前。
可以使用 Azure 存储资源管理器
任何配置都可以一般指定(或在访问所有帐户时指定为默认值),也可以绑定到特定帐户。例如,可以配置 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 客户端可以通过不同的方式部署,其身份验证需求由这些方式驱动。
可以更改的是用于对调用者进行身份验证的密钥/凭据。
身份验证机制在 fs.azure.account.auth.type
(或特定于帐户的变体)中设置。可能的值是 SharedKey、OAuth、Custom 和 SAS。对于各种 OAuth 选项,请使用配置 fs.azure.account .oauth.provider.type
。以下是受支持的实现 ClientCredsTokenProvider、UserPasswordTokenProvider、MsiTokenProvider 和 RefreshTokenBasedTokenProvider。如果指定的提供程序类型不是受支持的类型之一,则会引发 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 中推断;密码,“密钥”,从 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 凭据(客户端 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 端点、用户名和密码在配置/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 令牌,针对活动目录端点 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 托管标识,以前称为“托管服务标识”。
OAuth 2.0 令牌由特殊端点颁发,该端点仅可从执行的 VM 访问(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>
当调用其 getAccessToken()
方法时,自定义 OAuth 2.0 令牌提供程序会向 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) 令牌提供程序通过实现 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
。
连接器使用 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://[email protected]/users/alice
如果没有这些设置,即使可以从命令行访问 ADLS,distcp
访问也会因网络错误而失败。
与其他对象存储一样,登录密钥是宝贵的信息。组织应制定一个安全共享密钥的流程。
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 存储可伸缩性目标
ABFS 连接器支持一些受限的私有/不稳定的扩展点,以便第三方将自己的身份验证和授权服务集成到 ABFS 客户端中。
CustomDelegationTokenManager
:增加签发 Hadoop 委派令牌的能力。SASTokenProvider
:允许自定义提供 Azure 存储共享访问签名 (SAS) 令牌。CustomTokenProviderAdaptee
:允许自定义提供 Azure OAuth 令牌。KeyProvider
.查阅 org.apache.hadoop.fs.azurebfs.extensions
中的源代码和所有关联的测试,以了解如何使用这些扩展点。
警告 这些扩展点不稳定。
查阅 org.apache.hadoop.fs.azurebfs.constants.ConfigurationKeys
、org.apache.hadoop.fs.azurebfs.constants.FileSystemConfigurations
和 org.apache.hadoop.fs.azurebfs.AbfsConfiguration
的 javadoc,以获取配置选项及其默认值的完整列表。
配置 fs.azure.client.correlationid
提供了一个选项,使用这个客户端提供的标识符关联客户端请求。此 ID 将在 request-id-header
字段中显示在 Azure 存储分析日志中。参考:存储分析日志格式
此配置接受一个字符串,该字符串最多可包含 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
提供了一个选项,将 OutputStream Flush() API 呈现为 AbfsOutputStream 中的无操作。默认情况下,此配置将设置为 true。
Hflush() 是唯一可以提供持久数据传输的已记录 API,而 Flush() 也尝试使缓冲数据持久化,这会导致性能问题。
fs.azure.account.expect.header.enabled
:此配置参数用于指定是否希望随每个追加请求发送一个预期 100 继续标头。它默认配置为 true。此标志配置客户端在从输出流上传数据块之前向 Azure 存储进行检查。这允许客户端在实际尝试上传块之前优雅地进行节流。在实验中,这在高负载下提供了显著的吞吐量改进。有关更多信息:- https://mdn.org.cn/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,则作为 FileStatus 和 AclStatus 一部分的组名将与用户名相同 fs.azure.skipUserGroupMetadataDuringInitialization
。
以下配置与读写操作相关。
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 将对输入流执行 seek 和读取。此读取将填充 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 存储帐户启用了命名空间,则重命名、创建和删除操作是原子的。”目录可以指定为逗号分隔的值。默认值为“/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 使用这些设置来跟踪其端到端延迟。
通常,与连接器相关的问题按顺序归结为
如果您在 DEBUG
中记录 org.apache.hadoop.fs.azurebfs.services
,那么您将看到有关任何失败请求的更多详细信息。
用于调试连接的一个有用工具是 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) 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)
原因包括
找不到配置属性 _something_.dfs.core.windows.net
群集配置中没有 fs.azure.account.key.
条目声明特定帐户的访问密钥,或者您使用了错误的 URL
$ hadoop fs -ls abfs://[email protected]/ ls: Configuration property abfswales2.dfs.core.windows.net not found.
尝试列出容器时,没有此类文件或目录
没有给定名称的容器。它已被输入错误,或者需要创建容器。
$ hadoop fs -ls abfs://[email protected]/ ls: `abfs://[email protected]/': No such file or directory
text/html
、text/plain
、application/xml
OAuth 身份验证页面未因 HTTP 错误代码而失败,但它也没有返回 JSON
$ bin/hadoop fs -ls abfs://[email protected]/ ... 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 的所有权与预期不同。它归 <principal_id> 所有。该目录必须归提交者 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://[email protected]/
显示 ADLS Gen2 文件/目录现在归“user1”所有。
请参阅 测试 Azure 中的相关部分。