Hadoop Azure 支持:Azure Blob 存储

另请参阅:

简介

hadoop-azure模块提供了与Azure Blob Storage集成的支持。构建的jar文件名为hadoop-azure.jar,它还声明了对所需其他组件的传递依赖,特别是Azure Storage SDK for Java

要将其作为Apache Hadoop默认类路径的一部分,只需确保hadoop-env.sh中的HADOOP_OPTIONAL_TOOLS列表包含'hadoop-azure。例如:

export HADOOP_OPTIONAL_TOOLS="hadoop-azure,hadoop-azure-datalake"

功能特性

  • 读取和写入存储在Azure Blob存储账户中的数据。
  • 通过实现标准的Hadoop FileSystem接口来呈现分层文件系统视图。
  • 支持配置多个Azure Blob存储账户。
  • 支持块Blob(适用于大多数用例,如MapReduce)和页Blob(适用于连续写入用例,如HBase预写日志)。
  • 使用wasb方案通过URL引用文件系统路径。
  • 同时,对于SSL加密访问,请使用带有wasbs方案的URL来引用文件系统路径。
  • 可以作为MapReduce作业中的数据源或数据接收端。
  • 在Linux和Windows系统上均经过测试。
  • 已进行大规模测试。

限制

  • 文件所有者和组会被保留,但不强制执行权限模型。授权操作发生在整个Azure Blob Storage账户级别。
  • 文件的最后访问时间未被追踪。

使用说明

概念

Azure Blob Storage 数据模型包含3个核心概念:

  • 存储账户: 所有访问都通过存储账户完成。
  • Container: 容器是多个blob的分组。一个存储账户可以包含多个容器。在Hadoop中,整个文件系统层次结构存储在单个容器中。也可以配置多个容器,实际上相当于呈现多个可以通过不同URL引用的文件系统。
  • Blob: 任何类型和大小的文件。在Hadoop中,文件以blob形式存储。内部实现也使用blob来持久化文件系统层次结构和其他元数据。

配置凭据

使用Azure Blob存储需要配置凭据。通常这是在core-site.xml文件中设置的。配置属性名称的格式为fs.azure.account.key..blob.core.windows.net,其值为访问密钥。访问密钥是保护存储账户访问权限的机密信息。请勿将访问密钥(或core-site.xml文件)分享给不可信的第三方。

例如:

<property>
  <name>fs.azure.account.key.youraccount.blob.core.windows.net</name>
  <value>YOUR ACCESS KEY</value>
</property>

在许多Hadoop集群中,core-site.xml文件是全局可读的。也可以通过凭证提供程序来保护访问密钥。这提供了加密的文件格式以及文件权限保护。

使用凭证提供程序保护WASB的Azure凭据

为防止这些凭据被窥探,建议使用凭据提供程序框架安全地存储它们,并通过配置进行访问。以下描述了在WASB文件系统中使用Azure凭据的方法。

如需了解更多关于凭证提供者API的信息,请参阅:Credential Provider API

使用凭证提供程序实现Distcp与WASB的端到端步骤
配置
% hadoop credential create fs.azure.account.key.youraccount.blob.core.windows.net -value 123
    -provider localjceks://file/home/lmccay/wasb.jceks
配置core-site.xml或命令行系统属性
<property>
  <name>hadoop.security.credential.provider.path</name>
  <value>localjceks://file/home/lmccay/wasb.jceks</value>
  <description>Path to interrogate for protected credentials.</description>
</property>
distcp
% hadoop distcp
    [-D hadoop.security.credential.provider.path=localjceks://file/home/lmccay/wasb.jceks]
    hdfs://hostname:9001/user/lmccay/007020615 wasb://yourcontainer@youraccount.blob.core.windows.net/testDir/

注意:您可以选择将提供者路径属性添加到distcp命令行,而不是将作业特定配置添加到通用的core-site.xml中。上面的方括号展示了这一功能。

在加密文件中保护WASB的Azure凭据

除了使用凭证提供者框架来保护您的凭证外,还可以将其配置为加密形式。额外的配置属性指定了一个外部程序,由Hadoop进程调用以解密密钥。加密的密钥值会作为命令行参数传递给此外部程序:

<property>
  <name>fs.azure.account.keyprovider.youraccount</name>
  <value>org.apache.hadoop.fs.azure.ShellDecryptionKeyProvider</value>
</property>

<property>
  <name>fs.azure.account.key.youraccount.blob.core.windows.net</name>
  <value>YOUR ENCRYPTED ACCESS KEY</value>
</property>

<property>
  <name>fs.azure.shellkeyprovider.script</name>
  <value>PATH TO DECRYPTION PROGRAM</value>
</property>

支持压缩和配置的块Blob

块Blob是默认的Blob类型,适用于大多数大数据使用场景。然而,每个块Blob严格限制最多50,000个块。为防止达到此限制,WASB默认情况下不会在每次hflush()hsync()后都上传新块到服务。

在大多数情况下,将多个write()调用的数据组合成4MB的块是一个很好的优化。但在其他情况下,比如HBase日志文件,每次调用hflush()hsync()时都必须将数据上传到服务。

具有压缩功能的块Blob会在每次hflush()/hsync()后将数据上传到云服务。为了缓解50,000个块的数量限制,当Blob中的块数超过32,000时,hflush()/hsync()会执行一次压缩处理。

块压缩会搜索并用一个大块替换一系列小块。这意味着块压缩会带来相关成本:将小块读回客户端,然后重新将其作为一个大块写入。

为了使您创建的文件成为启用了块压缩的块Blob,客户端必须将配置变量fs.azure.block.blob.with.compaction.dir设置为以逗号分隔的文件夹名称列表。

例如:

<property>
  <name>fs.azure.block.blob.with.compaction.dir</name>
  <value>/hbase/WALs,/data/myblobfiles</value>
</property>

页Blob支持与配置

Hadoop的Azure Blob Storage接口支持两种类型的blob:block blobs和page blobs。块blob是默认类型,适用于大多数大数据用例,如Hive、Pig和分析性map-reduce作业的输入数据等。在hadoop-azure中引入页blob处理是为了支持HBase日志文件。页blob可以无限次写入,而块blob只能追加50,000次,超过后就会耗尽块空间导致写入失败。这对HBase日志来说不可行,因此引入了页blob支持来克服这一限制。

页 blob 的大小可达 1TB,比块 blob 的最大 200GB 容量更大。在大多数使用场景中应坚持使用块 blob,页 blob 仅在 HBase 预写日志的上下文中经过测试。

为了使您创建的文件成为页blob,您必须将配置变量fs.azure.page.blob.dir设置为以逗号分隔的文件夹名称列表。

例如:

<property>
  <name>fs.azure.page.blob.dir</name>
  <value>/hbase/WALs,/hbase/oldWALs,/data/mypageblobfiles</value>
</property>

你可以将其设置为简单的 / 以使所有文件成为页面blob。

配置选项 fs.azure.page.blob.size 是页面blob的默认初始大小。它必须为128MB或更大,且不超过1TB,以字节为单位的整数指定。

配置选项 fs.azure.page.blob.extension.size 表示页 blob 的扩展大小。该参数定义了当页 blob 即将填满时需要扩展的容量大小。必须设置为 128MB 或更大,以整数形式的字节数指定。

自定义用户代理

WASB将User-Agent头部传递给Azure后端。默认值包含WASB版本、Java运行时版本、Azure客户端库版本以及配置选项fs.azure.user.agent.prefix的值。自定义User-Agent头部有助于Azure服务进行更好的故障排查和分析。

<property>
    <name>fs.azure.user.agent.prefix</name>
    <value>Identifier</value>
</property>

原子文件夹重命名

Azure存储将文件存储为扁平的键/值存储,并不正式支持文件夹。hadoop-azure文件系统层在Azure存储之上模拟文件夹。默认情况下,hadoop-azure文件系统层中的文件夹重命名操作不是原子性的。这意味着在文件夹重命名过程中发生故障时,可能会导致部分文件夹留在原始目录中,而部分文件夹则转移到新目录中。

HBase依赖于原子性的文件夹重命名操作。因此,引入了一个名为fs.azure.atomic.rename.dir的配置项,允许您指定以逗号分隔的目录列表来获得特殊处理,从而实现原子性的文件夹重命名。该设置的默认值仅为/hbase。系统将应用重做机制来完成失败的重命名操作。临时可能会出现一个-renamePending.json文件,该文件记录了重命名操作的意图,以便在发生故障时进行重做。

例如:

<property>
  <name>fs.azure.atomic.rename.dir</name>
  <value>/hbase,/data</value>
</property>

访问wasb URL

在core-site.xml中配置好凭据后,任何Hadoop组件都可以通过以下格式的URL引用该Azure Blob存储账户中的文件:

wasb[s]://<containername>@<accountname>.blob.core.windows.net/<path>

方案 wasbwasbs 用于标识由Azure Blob Storage支持的文件系统上的URL。wasb 使用未加密的HTTP访问与Azure Blob Storage API进行所有交互。wasbs 则使用SSL加密的HTTPS访问。

例如,以下FileSystem Shell命令演示了如何访问名为youraccount的存储账户和名为yourcontainer的容器。

% hadoop fs -mkdir wasb://yourcontainer@youraccount.blob.core.windows.net/testDir

% hadoop fs -put testFile wasb://yourcontainer@youraccount.blob.core.windows.net/testDir/testFile

% hadoop fs -cat wasbs://yourcontainer@youraccount.blob.core.windows.net/testDir/testFile
test file content

也可以配置fs.defaultFS来使用wasbwasbs URL。这将使所有裸路径(如/testDir/testFile)自动解析到该文件系统。

追加API支持与配置

Hadoop的Azure Blob Storage接口通过将配置fs.azure.enable.append.support设置为true,可选择性支持单写入者的追加API。

例如:

<property>
  <name>fs.azure.enable.append.support</name>
  <value>true</value>
</property>

必须注意,Azure Blob Storage接口中的追加支持与HDFS语义不同。追加支持在内部并不强制单一写入者,但要求应用程序保证这一语义。应用程序有责任确保对特定文件路径进行单线程处理,或依赖其自身的外部锁定机制。未能做到这一点将导致意外行为。

多线程支持

对于包含大量文件和子目录的目录,重命名和删除blob操作目前非常缓慢,因为这些操作是逐个blob串行执行的。这些文件和子文件夹可以并行删除或重命名。以下配置可用于启用线程进行并行处理

要为删除操作启用10个线程。将配置值设置为0或1可禁用线程。默认行为是禁用线程。

<property>
  <name>fs.azure.delete.threads</name>
  <value>10</value>
</property>

要为重命名操作启用20个线程。将配置值设置为0或1可禁用线程。默认行为是禁用线程。

<property>
  <name>fs.azure.rename.threads</name>
  <value>20</value>
</property>

WASB安全模式与配置

WASB可以在安全模式下运行,此时与Azure存储通信所需的存储访问密钥不必与使用WASB的进程位于同一地址空间。在此模式下,所有与Azure存储的交互都通过SAS URI执行。安全模式下有两种子模式:一种是远程SAS密钥模式(SAS密钥由远程进程生成),另一种是本地模式(SAS密钥在WASB内部生成)。默认情况下SAS密钥模式以远程模式运行,但出于测试目的可以启用本地模式,在与WASB相同的进程中生成SAS密钥。

要启用安全模式,需要将以下属性设置为true。

<property>
  <name>fs.azure.secure.mode</name>
  <value>true</value>
</property>

要在本地启用SAS密钥生成,需要将以下属性设置为true。

<property>
  <name>fs.azure.local.sas.key.mode</name>
  <value>true</value>
</property>

要使用远程SAS密钥生成模式,需要提供以逗号分隔的外部REST服务来生成所需的SAS密钥。以下属性可用于指定远程SAS密钥生成的服务端点:

<property>
  <name>fs.azure.cred.service.urls</name>
  <value>{URL}</value>
</property>

远程服务预期需要支持两个REST调用{URL}/GET_CONTAINER_SAS{URL}/GET_RELATIVE_BLOB_SAS,用于生成容器和相对blob的SAS密钥。示例请求如下

{URL}/GET_CONTAINER_SAS?storage_account=&container=&sas_expiry=&delegation_token= {URL}/GET_CONTAINER_SAS?storage_account=&container=&relative_path=&sas_expiry=&delegation_token=

该服务预期会返回一个JSON格式的响应:

{
  "responseCode" : 0 or non-zero <int>,
  "responseMessage" : relavant message on failure <String>,
  "sasKey" : Requested SAS Key <String>
}

WASB中的授权支持

可以通过以下配置在WASB中启用授权支持:

<property>
  <name>fs.azure.authorization</name>
  <value>true</value>
</property>

当前的授权实现依赖于一个能够执行授权的外部服务。该服务预期运行在由以下配置提供的逗号分隔的URL上。

<property>
  <name>fs.azure.authorization.remote.service.urls</name>
  <value>{URL}</value>
</property>

远程服务预期需支持以下REST调用:{URL}/CHECK_AUTHORIZATION 示例请求:{URL}/CHECK_AUTHORIZATION?wasb_absolute_path=&operation_type=&delegation_token=

该服务预期会返回一个JSON格式的响应:

{
    "responseCode" : 0 or non-zero <int>,
    "responseMessage" : relevant message on failure <String>,
    "authorizationResult" : true/false <boolean>
}

WASB中的委托令牌支持

可以在WASB中通过以下配置启用委托令牌支持:

<property>
  <name>fs.azure.enable.kerberos.support</name>
  <value>true</value>
</property>

当前的委托令牌实现依赖于能够生成和管理委托令牌的外部服务实例的存在。该服务预期运行在由以下配置提供的逗号分隔的URL上。

<property>
  <name>fs.azure.delegation.token.service.urls</name>
  <value>{URL}</value>
</property>

远程服务预期需要支持以下REST调用:{URL}?op=GETDELEGATIONTOKEN{URL}?op=RENEWDELEGATIONTOKEN{URL}?op=CANCELDELEGATIONTOKEN。示例请求:{URL}?op=GETDELEGATIONTOKEN&renewer= {URL}?op=RENEWDELEGATIONTOKEN&token= {URL}?op=CANCELDELEGATIONTOKEN&token=

该服务预期会为GETDELEGATIONTOKEN请求返回JSON格式的响应:

{
    "Token" : {
        "urlString": URL string of delegation token.
    }
}

在WASB中启用授权时的chown行为

启用授权后,只有以下配置中列出的用户才被允许更改WASB中文件/文件夹的所有者。该配置值采用逗号分隔的用户名列表,这些用户有权执行chown操作。

<property>
  <name>fs.azure.chown.allowed.userlist</name>
  <value>user1,user2</value>
</property>

在WASB中启用授权时的chmod行为

启用授权后,只有文件/文件夹的所有者以及以下配置中列出的用户才被允许更改WASB中文件/文件夹的权限。该配置值采用逗号分隔的用户名列表,这些用户被允许执行chmod操作。

<property>
  <name>fs.azure.daemon.userlist</name>
  <value>user1,user2</value>
</property>
<property>
  <name>fs.azure.chmod.allowed.userlist</name>
  <value>userA,userB</value>
</property>

可以通过以下设置启用SAS密钥和授权响应的缓存:缓存设置仅在启用fs.azure.authorization时适用。缓存维护在文件系统对象级别。

    <property>
      <name>fs.azure.authorization.caching.enable</name>
      <value>true</value>
    </property>

缓存可容纳的最大条目数可通过以下设置进行自定义:

    <property>
      <name>fs.azure.authorization.caching.maxentries</name>
      <value>512</value>
    </property>

授权缓存条目的有效期可以通过以下设置进行控制:将该值设置为零将禁用授权缓存。如果未指定该键,则默认生效的过期时长为5分钟。

   <property>
     <name>fs.azure.authorization.cacheentry.expiry.period</name>
     <value>5m</value>
   </property>

SASKey缓存条目的有效期可以通过以下设置进行控制。将该值设置为零将禁用SASKey缓存。如果未指定该键,则sas-key请求中指定的默认过期时间将生效。

   <property>
     <name>fs.azure.saskey.cacheentry.expiry.period</name>
     <value>90d</value>
   </property>

使用容器saskey可访问容器内的所有blob。启用此设置后,将不使用特定于blob的saskeys。与特定于blob的saskeys相比,此设置能提供更好的性能。

   <property>
     <name>fs.azure.saskey.usecontainersaskeyforallaccess</name>
     <value>true</value>
   </property>

性能优化配置

fs.azure.block.blob.buffered.pread.disable: 默认情况下,位置读取API会在输入流上执行查找和读取操作。该读取会填充BlockBlobInputStream中的缓冲区缓存。如果将此配置设为true,则会跳过缓冲区的使用,直接执行无锁调用来从blob读取数据。这种优化对于HBase这类在共享InputStream实例上进行短随机读取的场景非常有帮助。注意:这不是一个可以在集群级别设置的配置,只能作为FutureDataInputStreamBuilder的一个选项使用。参见FileSystem#openFile(Path path)

延伸阅读