OpenStack是一个开源云基础架构,可以从多个公共IaaS提供商处进行访问并进行私有部署。它提供基础架构服务,例如VM托管(Nova),身份验证(Keystone)和二进制对象存储(Swift)。
该模块启用Apache Hadoop应用程序-包括MapReduce作业,在OpenStack Swift对象存储实例之间进行数据读写。
要使其成为Apache Hadoop的默认类路径的一部分,只需确保hadoop-env.sh中的HADOOP_OPTIONAL_TOOLS在列表中具有“ hadoop-openstack”。
读写存储在Swift对象存储中的数据
支持伪分层文件系统(目录,子目录和文件)
标准文件系统操作:create,delete,mkdir,ls,mv,stat。
可以充当MapReduce作业中的数据源或接收器。
支持多个OpenStack服务以及单个服务中的多个容器。
支持集群内和远程访问Swift数据。
支持带有密码或令牌的OpenStack Keystone身份验证。
根据Apache软件许可发布
已针对Hadoop 3.x和1.x分支以及多个公共OpenStack集群进行了测试:美国Rackspace,英国Rackspace和HP Cloud。
针对私有OpenStack集群进行了测试,包括对大文件上传的可伸缩性测试。
OpenStack swift是对象存储;也称为Blobstore。它按名称将任意二进制对象存储在容器中。
Hadoop Swift文件系统库增加了另一个概念,即service,它定义了哪个Swift blobstore托管了一个容器-以及如何连接到该容器。
容器是由用户在Swift文件存储上创建的,并拥有对象。
对象可以是零字节长,也可以包含数据。
容器中的对象最多可容纳5GB;对于比这更大的文件,有一个特殊的支持,它将多个对象合并为一个。
每个对象均以其名称引用;没有目录的概念。
您可以在对象名称中使用任何可以进行“ URL编码”的字符;URL编码后,名称的最大长度为1034个字符。
名称中可以包含/字符,用于创建目录结构的错觉。例如dir / dir2 / name。即使这看起来像一个目录,它仍然只是一个name。不需要在容器中包含名为dir或dir / dir2的任何条目
那就是。如果容器中的零字节对象看上去像其他对象上方的目录名,则它们可以假装为目录。继续该示例,一个名为dir的0字节对象将告诉客户端它是存在dir / dir2或dir / dir2 / name的目录。这会产生一种持有文件系统的容器的错觉。
客户端应用程序通过HTTP或HTTPS与Swift通讯,使用标准HTTP操作(分别为GET,PUT和DELETE)读取,写入和删除对象。还有一个COPY操作,该操作在容器中创建一个具有新名称的新对象,其中包含旧数据。本身没有重命名操作,需要复制对象-然后删除原始条目。
Swift文件系统*最终是一致的*:对该对象或其他客户端可能无法立即看到对该对象的操作。这是文件系统目标的结果:跨多个数据中心跨越一组计算机,使得当许多计算机出现故障时数据仍然可用。(相比之下,Hadoop HDFS文件系统“立即一致”,但不跨越数据中心。)
最终的一致性可能会给期望立即一致性的客户端应用程序带来意外:在删除或覆盖对象后,该对象可能仍然可见-或仍可检索旧数据。用于Apache Hadoop的Swift Filesystem客户端尝试与MapReduce引擎一起处理此问题,但是仍有可能最终一致性导致意外情况。
Hadoop期望某些操作是原子性的,尤其是rename(),MapReduce层依靠该操作来提交作业的输出,从而将数据从临时目录重命名为最终路径。因为重命名是作为目录路径下每个blob的副本实现的,然后删除原始副本,所以该操作的中间状态将对其他客户端可见。如果两个Reducer任务将其temp目录重命名为最终路径,则两个操作都可能成功,结果是输出目录包含混合数据。如果在启用推测的情况下运行MapReduce作业并将Swift用作MR作业的直接输出,则可能会发生这种情况(针对Amazon S3也会发生)。
非原子操作的其他后果是:
如果程序在对数据进行操作之前正在查找目录的存在,则它可能会过早启动。可以通过使用其他机制来协调程序来避免这种情况,例如是否存在在任何批量目录操作之后写入的文件。
一个rename()或delete()操作可能包括在操作期间在源目录树下添加的文件,可能会无意中将其删除,或者删除模仿目录并充当文件父级的0字节快速条目。尝试避免这样做。
避免所有这些问题的最佳方法是不使用Swift作为MapReduce作业或其他Hadoop工作流程之间的文件系统。它可以充当数据源和最终目的地,但是并不能满足Hadoop对文件系统是什么的所有期望-它是一个blobstore。
安装后,任何Hadoop应用程序都可以使用Swift FileSystem客户端读取或写入存储在Swift容器中的数据。
可以将存储在Swift中的数据用作MapReduce作业的直接输入-只需使用swift: URL(请参见下文)来声明数据源。
该Swift Filesystem客户端旨在与公共和私有的多个Swift对象存储一起使用。这样,客户端就可以使用不同的集群,并在其中一个集群之间读写数据。
它也可以使用多个登录详细信息来处理相同的对象存储。
这些功能是通过一个基本概念实现的:使用URI中的服务名称引用快速文件系统,并查找该特定服务的所有连接和登录详细信息。可以在Hadoop XML配置文件中定义不同的服务名称,从而定义不同的集群,或者为同一对象存储提供不同的登录详细信息。
Hadoop使用URI引用文件系统中的文件。一些常见的示例是:
本地:// etc / hosts hdfs:// cluster1 / users / example / data / set1 hdfs://cluster2.example.org:8020 / users / example / data / set1
Swift Filesystem Client添加了一个新的URL类型swift。在Swift Filesystem URL中,URL的主机名部分标识了要使用的容器和服务。路径对象的名称。这里有些例子
swift://container.rackspace/my-object.csv swift://data.hpcloud/data/set1 swift://dmitry.privatecloud/out/results
在最后两个示例中,路径看起来像目录:并非如此,它们分别只是名为data / set1和out / results的对象。
在Hadoop的OpenStack的 JAR必须对Hadoop的程序试图跟雨燕服务的类路径。如果安装在Hadoop MapReduce服务的类路径中,那么由MR引擎启动的所有程序将自动获取JAR。这是授予所有Hadoop作业访问Swift的最简单方法。
或者,可以将JAR包含为应用程序使用的JAR文件之一。即使未为此配置Hadoop集群,这也使Hadoop作业可与Swift对象存储一起使用。
该库还取决于Apache HttpComponents库,该库也必须位于类路径上。
要使用快速服务,用户必须提供:
定义容器和服务的URL。
在群集/作业配置中,该服务的登录详细信息。
多个服务定义可以共存于同一配置文件中:只需为其使用不同的名称。
该服务定义用于在Rackspace美国基础架构内部署的Hadoop集群中。
<属性> <name> fs.swift.service.rackspace.auth.url </ name> <value> https://auth.api.rackspacecloud.com/v2.0/tokens </ value> <description> Rackspace US(多区域)</ description> </ property> <属性> <name> fs.swift.service.rackspace.username </ name> <value> user4 </ value> </ property> <属性> <name> fs.swift.service.rackspace.region </ name> <value> DFW </ value> </ property> <属性> <name> fs.swift.service.rackspace.apikey </ name> <value> fe806aa86dfffe2f6ed8 </ value> </ property>
这里,在帐户设置API密钥页面中可见的API密钥用于登录。没有用于公共/私有访问的属性-默认为对Swift操作使用私有端点。
此配置还为其数据选择区域之一DFW。
对该服务的引用将使用机架服务名称:
swift://hadoop-container.rackspace/
这将连接到Rackspace的英国(“ LON”)数据中心。
<属性> <name> fs.swift.service.rackspaceuk.auth.url </ name> <value> https://lon.identity.api.rackspacecloud.com/v2.0/tokens </ value> <description> Rackspace UK </ description> </ property> <属性> <name> fs.swift.service.rackspaceuk.username </ name> <value> user4 </ value> </ property> <属性> <name> fs.swift.service.rackspaceuk.password </ name> <值>在此处插入密码/值> </ property> <属性> <name> fs.swift.service.rackspace.public </ name> <value> true </ value> </ property>
这是公共访问点连接,使用API密钥上的密码。
对该服务的引用将使用rackspaceuk服务名称:
swift://hadoop-container.rackspaceuk/
因为使用了公共端点,所以如果在伦敦数据中心内使用此服务定义,那么所有访问都将以公共上载/下载费率计费,而不管Hadoop集群在哪里。
这是一个连接到HP Cloud对象存储的示例。
<属性> <name> fs.swift.service.hpcloud.auth.url </ name> <值> https://region-a.geo-1.identity.hpcloudsvc.com:35357/v2.0/tokens </ value> <description> HP Cloud </ description> </ property> <属性> <name> fs.swift.service.hpcloud.tenant </ name> <value> FE806AA86 </ value> </ property> <属性> <name> fs.swift.service.hpcloud.username </ name> <value> FE806AA86DFFFE2F6ED8 </ value> </ property> <属性> <name> fs.swift.service.hpcloud.password </ name> <value>秘密密码进入此处</ value> </ property> <属性> <name> fs.swift.service.hpcloud.public </ name> <value> true </ value> </ property>
对该服务的引用将使用hpcloud服务名称:
swift://hadoop-container.hpcloud/
一些配置选项适用于Swift客户端,与所选的特定Swift文件系统无关。
Swift不会将文件分解为块,除非特殊情况是文件长度超过5GB。因此,没有“块大小”的概念来定义将数据保存在何处。
Hadoop的MapReduce层取决于声明其块大小的文件,因此它知道如何分区工作。块大小太小意味着许多映射器只能处理少量数据。块大小太大意味着仅少数映射器开始使用。
因此,Swift报告的块大小值控制着MapReduce引擎的基本工作负载分配,并且可以成为调整集群性能的重要参数。
该属性以千字节为单位;默认值为32 * 1024:32 MB
<属性> <name> fs.swift.blocksize </ name> <value> 32768 </ value> </ property>
这种块大小不会影响文件在Swift中的存储方式;它仅控制报告的块大小是多少-Hadoop MapReduce中用于划分工作的值。
请注意,可以通过设置mapred.min.split.size和mapred.max.split.size属性来独立地调整MapReduce引擎的拆分逻辑,这可以在特定的作业配置中完成。
<属性> <name> mapred.min.split.size </ name> <value> 524288 </ value> </ property> <属性> <name> mapred.max.split.size </ name> <value> 1048576 </ value> </ property>
在Apache Pig脚本中,这些属性将设置为:
mapred.min.split.size 524288 mapred.max.split.size 1048576
Swift文件系统客户端将非常大的文件分解为多个分区文件,并在进行过程中上载每个文件,并在关闭分区文件时写入所有剩余数据和XML清单。
分区大小默认为4608 MB。4.5GB,Swift可以支持的最大文件大小。
可以在fs.swift.partsize选项中设置较小的分区大小。这需要一个以KB为单位的值。
<属性> <name> fs.swift.partsize </ name> <value> 1024 </ value> <description>上载每MB </ description> </ property>
该值何时应从默认值更改?
尽管无需为Swift文件系统客户端的基本操作更改它,但可以对其进行调整
如果Swift文件系统可以识别位置,则将文件分解为较小的分区可以将数据分散到整个群集中。为了获得最佳性能,应将属性fs.swift.blocksize设置为小于文件分区大小的值。
写入未分区的文件时,整个写入均在close()操作中完成。对文件进行分区时,每当未完成的数据量大于分区大小时,将写入未完成的数据。这意味着数据将被增量写入
Swift文件系统客户端通过HTTP GET操作读取文件,一次请求一个数据块。
默认值为64KB。较大的值在较快的网络上可能更有效,因为它减少了设置HTTP操作的开销。
但是,如果通过许多随机访问来读取文件,则将从文件的不同部分发出数据请求-丢弃一些先前请求的数据。较大的请求大小的好处可能被浪费了。
fs.swift.requestsize属性设置请求大小(以KB为单位)。
<属性> <name> fs.swift.requestsize </ name> <value> 128 </ value> </ property>
这将以毫秒为单位设置连接到Swift服务的超时时间。
<属性> <name> fs.swift.connect.timeout </ name> <value> 15000 </ value> </ property>
较短的超时意味着连接失败的发生速度更快-但可能会触发更多的错误警报。较长的超时时间可以更灵活地解决网络问题-与远程文件系统对话时可能需要。
这将超时设置为毫秒,以等待来自已连接套接字的数据。
<属性> <name> fs.swift.socket.timeout </ name> <value> 60000 </ value> </ property>
较短的超时意味着连接失败的发生速度更快-但可能会触发更多的错误警报。较长的超时时间可以更灵活地解决网络问题-与远程文件系统对话时可能需要。
这设置了每次发出HTTP请求时尝试连接到服务的次数。
<属性> <名称> fs.swift.connect.retry.count </名称> <value> 3 </ value> </ property>
重试次数越多,它对瞬态中断的恢复就越有弹性-检测和报告服务器连接性问题的速度也就越慢。
在Hadoop的OpenStack的 JAR -或任何dependencies-可能无法在你的classpath。
确保在集群中的服务器上安装了* JAR。*“ hadoop-openstack”位于hadoop-env.sh中的HADOOP_OPTIONAL_TOOLS条目上,或者作业提交过程会将JAR文件上载到分布式缓存。
不要与任何人共享您的登录详细信息,这意味着请勿登录详细信息,或将XML配置文件签入您没有独占访问权的任何版本控制系统中。
同样,请勿在任何文档中*或在线提交的任何错误报告中使用您的真实帐户详细信息*
优先使用apikey身份验证而不是密码,因为它更容易撤销密钥-某些服务提供商允许您在密钥发布时设置密钥的自动到期日期。
不要在公共OpenStack群集中使用公共服务终结点,因为它将消耗大量账单。
请记住:它不是真实的文件系统或分层目录结构。某些操作(目录重命名和删除)需要时间,并且不是原子操作,也不与其他操作隔离。
不支持追加。
不支持Unix样式的权限。具有存储库写权限的所有帐户都具有无限访问权限;具有读取访问权限的用户也是如此。
在公共云中,除非您对任何读取数据的人感到满意并且准备支付下载费用,否则不要将容器公开。
对象路径的最大长度:1024个字符
二进制对象的最大大小:无绝对限制。大于5GB的文件在本机文件系统中划分为单独的文件,并在检索过程中合并。警告:分区/大文件支持是Hadoop / Swift FS集成中最复杂的部分,并且与身份验证一起,也是最麻烦的支持。
在Hadoop的OpenStack的可以针对其支持OpenStack的梯形认证机制任何公共或私有云基础架构进行远程测试。还可以针对私有OpenStack群集进行测试。强烈建议OpenStack开发团队针对他们正在开发或部署的任何Swift版本测试Hadoop swift文件系统客户端,以强调其群集并及早发现错误。
该模块附带了一大套JUnit测试-仅在源树包含针对特定集群进行测试的凭据时才执行测试。
在签出Hadoop源代码树之后,创建文件:
hadoop-tools / hadoop-openstack / src / test / resources / auth-keys.xml
如上所述,在此文件中插入绑定到测试文件系统所需的凭据。
接下来,将属性test.fs.swift.name设置为要测试的swift容器的URL。测试期望对该容器具有独占访问权-不要在其上保留任何其他数据,或者期望将其保留。
<属性> <name> test.fs.swift.name </ name> <value> swift://test.myswift/ </ value> </ property>
在基本hadoop目录中,运行:
mvn全新安装-DskipTests
这将构建一组与将要测试的hadoop-openstack模块一致的Hadoop JAR 。
在hadoop-tools / hadoop-openstack目录中运行
mvn test -Dtest = TestSwiftRestClient
这将运行一些简单的测试,其中包括针对远程swift服务进行身份验证。如果这些测试失败,其余所有测试也会失败。如果失败:检查您的身份验证。
测试成功后,您可以运行完整的测试套件
MVN测试
请注意,这些测试可能需要一个小时或更长时间,尤其是对于远程Swift服务-或限制大量操作的测试。
一旦AUTH-keys.xml文件到位,MVN测试从Hadoop的源基目录运行会自动运行这些测试的OpenStack虽然这将确保没有回归时有发生,它也可以显著时间添加到测试运行,并可以运行账单,具体取决于谁提供Swift存储服务。我们建议单独为Swift测试设置一个单独的源树,并手动或通过CI工具以比正常测试运行更低的频率运行它。
最后:Apache Hadoop是一个开源项目。非常欢迎提供代码(包括更多测试)。