View File System(ViewFs)提供了一种管理多个Hadoop文件系统名称空间(或名称空间卷)的方法。对于HDFS Federation中具有多个名称节点(因此具有多个名称空间)的群集而言,它特别有用。ViewFs类似于某些Unix / Linux系统中的客户端挂载表。ViewF可以用于创建个性化的名称空间视图,也可以用于每个集群的通用视图。
本指南是在具有多个集群的Hadoop系统的上下文中介绍的,每个集群可以联合到多个命名空间中。它还介绍了如何在联合HDFS中使用ViewF来提供每个群集的全局名称空间,以便应用程序可以以类似于联合身份验证世界的方式进行操作。
在HDFS Federation之前的旧世界中,群集具有单个namenode,该namenode为该群集提供了单个文件系统名称空间。假设有多个集群。每个群集的文件系统名称空间是完全独立且不相交的。此外,物理存储不跨集群共享(即,数据节点不跨集群共享)。
每个集群的core-site.xml具有一个配置属性,该属性将默认文件系统设置为该集群的namenode:
<属性> <name> fs.default.name </ name> <value> hdfs:// namenodeOfClusterX:port </ value> </ property>
这种配置属性允许使用斜杠相对名称来解析相对于群集名称节点的路径。例如,使用上面的配置,路径/ foo / bar指向hdfs:// namenodeOfClusterX:port / foo / bar。
在群集上的每个网关以及该群集的关键服务(例如JobTracker和Oozie)上都设置了此配置属性。
因此,在如上设置core-site.xml的集群X 上,典型路径名是
/ foo / bar
hdfs:// namenodeOfClusterX:port / foo / bar
hdfs:// namenodeOfClusterY:port / foo / bar
distcp hdfs:// namenodeClusterY:port / pathSrc hdfs:// namenodeClusterZ:port / pathDest
webhdfs:// namenodeClusterX:http_port / foo / bar
http:// namenodeClusterX:http_port / webhdfs / v1 / foo / bar和http:// proxyClusterX:http_port / foo / bar
假设有多个集群。每个群集具有一个或多个名称节点。每个名称节点都有其自己的名称空间。名称节点属于一个集群,并且仅属于一个集群。同一群集中的名称节点共享该群集的物理存储。群集之间的命名空间与以前一样是独立的。
操作会根据存储需求决定在集群中每个名称节点上存储的内容。例如,他们可以将所有用户数据(/ user / <username>)放在一个namenode中,所有feed数据(/ data)放在另一个namenode中,所有项目(/ projects)放在另一个namenode中,等等。
为了提供与旧世界的透明性,ViewFs文件系统(即客户端安装表)用于为每个群集创建一个独立的群集名称空间视图,该视图类似于旧世界的名称空间。客户端安装表类似于Unix安装表,它们使用旧的命名约定安装新的名称空间卷。下图显示了一个装载表,该装载表装载了四个名称空间卷/ user,/ data,/ projects和/ tmp:
ViewFs像HDFS和本地文件系统一样实现Hadoop文件系统接口。从仅允许链接到其他文件系统的意义上来说,它是一个琐碎的文件系统。由于ViewFs实现了Hadoop文件系统接口,因此透明地运行Hadoop工具。例如,所有shell命令都可以与HDF和本地文件系统一起使用ViewF。
在每个集群的配置中,默认文件系统被设置为该集群的安装表,如下所示(将其与Single Namenode Clusters中的配置进行比较)。
<属性> <名称> fs.defaultFS </名称> <value> viewfs:// clusterX </ value> </ property>
URI中的viewfs://方案之后的权限是装入表名称。建议使用集群名称来命名集群的安装表。然后,Hadoop系统将在Hadoop配置文件中查找名称为“ clusterX”的装载表。操作将所有网关和服务机安排为包含所有群集的装入表,以便如上所述,对于每个群集,默认文件系统均设置为该群集的ViewFs装入表。
挂载表的挂载点在标准Hadoop配置文件中指定。viewfs的所有安装表配置条目均以fs.viewfs.mounttable为前缀。。使用链接标记指定链接其他文件系统的安装点。建议使用与链接文件系统目标位置相同的挂载点名称。对于未在安装表中配置的所有名称空间,我们可以通过linkFallback将它们回退到默认文件系统。
在以下安装表配置中,名称空间/ data链接到文件系统hdfs://nn1-clusterx.example.com:8020 / data,/ project链接到文件系统hdfs://nn2-clusterx.example.com: 8020 /项目。所有未在安装表中配置的名称空间(例如/ logs)都链接到文件系统hdfs://nn5-clusterx.example.com:8020 / home。
<配置> <属性> <name> fs.viewfs.mounttable.ClusterX.link./data </ name> <value> hdfs://nn1-clusterx.example.com:8020 / data </ value> </ property> <属性> <name> fs.viewfs.mounttable.ClusterX.link./project </ name> <value> hdfs://nn2-clusterx.example.com:8020 / project </ value> </ property> <属性> <name> fs.viewfs.mounttable.ClusterX.link./user </ name> <value> hdfs://nn3-clusterx.example.com:8020 / user </ value> </ property> <属性> <name> fs.viewfs.mounttable.ClusterX.link./tmp </ name> <value> hdfs://nn4-clusterx.example.com:8020 / tmp </ value> </ property> <属性> <name> fs.viewfs.mounttable.ClusterX.linkFallback </ name> <value> hdfs://nn5-clusterx.example.com:8020 / home </ value> </ property> </ configuration>
或者,我们可以通过linkMergeSlash将挂载表的根与另一个文件系统的根合并。在以下安装表配置中,ClusterY的根目录与根文件系统合并在hdfs://nn1-clustery.example.com:8020上。
<配置> <属性> <name> fs.viewfs.mounttable.ClusterY.linkMergeSlash </ name> <value> hdfs://nn1-clustery.example.com:8020 / </ value> </ property> </ configuration>
因此,在群集X上,其中将core-site.xml设置为使默认fs使用该群集的安装表,因此典型路径名是
/ foo / bar
viewfs:// clusterX / foo / bar
viewfs:// clusterY / foo / bar
distcp viewfs:// clusterY / pathSrc viewfs:// clusterZ / pathDest
viewfs:// clusterX-webhdfs / foo / bar
http:// namenodeClusterX:http_port / webhdfs / v1 / foo / bar和http:// proxyClusterX:http_port / foo / bar
HDFS和其他分布式文件系统通过某种冗余(例如块复制或更复杂的分布式编码)提供数据弹性。但是,现代设置可能由在内部和外部托管的多个Hadoop群集,企业文件管理器组成。Nfly挂载点使单个逻辑文件可以由多个文件系统同步复制。它是为较小的文件而设计的,最大容量为GB。通常,这是单个核心/单个网络链接性能的函数,因为逻辑使用ViewF(例如FsShell或MapReduce任务)驻留在单个客户端JVM中。
考虑以下示例,以了解Nfly的基本配置。假设我们要保留目录广告在URI表示的三个文件系统上复制:uri1,uri2和uri3。
<属性> <name> fs.viewfs.mounttable.global.linkNfly ../ ads </ name> <value> uri1,uri2,uri3 </ value> </ property>
注意连续2个..在属性名。它们的出现是由于对安装点进行高级调整的空设置,我们将在后续部分中显示。该属性值是URI的逗号分隔列表。
URI可能指向不同区域中的不同群集hdfs:// datacenter-east / ads,s3a:// models-us-west / ads,hdfs:// datacenter-west / ads或在最简单的情况下指向位于相同的文件系统,例如file:/ tmp / ads1,file:/ tmp / ads2,file:/ tmp / ads3
如果基础系统可用,则在全局路径viewfs:// global / ads下执行的所有修改都会传播到所有目标URI。
例如,如果我们通过hadoop shell创建文件
hadoop fs -touchz viewfs:// global / ads / z1
我们将在后一种配置中通过本地文件系统找到它
ls -al / tmp / ads * / z1 -rw-r--r-- 1个用户滚轮0 Mar 11 12:17 / tmp / ads1 / z1 -rw-r--r-- 1个用户滚轮0 Mar 11 12:17 / tmp / ads2 / z1 -rw-r--r-- 1个用户滚轮0 Mar 11 12:17 / tmp / ads3 / z1
第一个文件系统处理从全局路径读取的操作,不会导致异常。文件系统的访问顺序取决于当前是否可用,以及是否存在拓扑顺序。
挂载点linkNfly可以使用作为键=值对的逗号分隔列表传递的参数进行进一步配置。当前支持以下参数。
如果以下nfly写入失败,则minReplication = int确定必须处理写入修改而没有异常的最小目标数。如果minReplication高于目标URI的数量,则是配置错误。预设值为2。
如果minReplication低于目标URI的数量,我们可能会有一些目标URI没有最新写入。可以通过采用以下设置控制的更昂贵的读取操作来补偿它
readMostRecent = boolean如果设置为true,则会导致Nfly客户端检查所有目标URI下的路径,而不仅仅是根据拓扑顺序检查第一个。在当前所有可用的文件中,处理时间最近的文件将被处理。
repairOnRead = boolean如果设置为true,则会导致Nfly将最新的副本复制到过时的目标,以便可以从最近的副本再次廉价地进行后续读取。
Nfly试图满足对“最接近”目标URI的读取。
为此,Nfly将“ 机架感知”的概念扩展到目标URI的权限。
Nfly应用NetworkTopology来解析URI的权限。最常见的是,在异构设置中使用基于脚本的映射。我们可以使用一个脚本来提供以下拓扑映射
URI | 拓扑结构 |
---|---|
hdfs:// datacenter-east / ads | / us-east / onpremise-hdfs |
s3a:// models-us-west / ads | / us-west / aws |
hdfs:// datacenter-west / ads | / us-west / onpremise-hdfs |
如果目标URI不具有file:中的授权部分:/ Nfly注入客户端的本地节点名称。
<属性> <name> fs.viewfs.mounttable.global.linkNfly.minReplication = 3,readMostRecent = true,repairOnRead = false。/ ads </ name> <value> hdfs:// datacenter-east / ads,hdfs:// datacenter-west / ads,s3a:// models-us-west / ads,file:/ tmp / ads </ value> </ property>
FileSystem fs = FileSystem.get(“ viewfs:// global /”,...); FSDataOutputStream out = fs.create(“ viewfs:// global / ads / f1”); out.write(...); out.close();
上面的代码将导致以下执行。
在每个目标URI下创建一个不可见文件_nfly_tmp_f1,即hdfs:// datacenter-east / ads / _nfly_tmp_f1,hdfs:// datacenter-west / ads / _nfly_tmp_f1等。这是通过在基础文件系统上调用create并返回FSDataOutputStream来完成的对象了用于包装所有四个输出流。
因此在每个随后的写出可以被转发到每个包装流。
在out.close上,所有流都关闭,文件从_nfly_tmp_f1重命名为f1。截至此步骤开始,所有文件都将收到与客户端系统时间相对应的相同修改时间。
如果至少minReplication目标通过了第1-3步而没有失败,则Nfly认为该事务是逻辑提交的;否则,它会尽力尝试清除临时文件。
请注意,由于4是尽力而为的步骤,并且客户端JVM可能崩溃而无法恢复工作,因此,最好提供某种cron作业来清除此类_nfly_tmp文件。
当我从非联合世界转移到联合世界时,我将不得不跟踪不同卷的名称节点。我怎么做?
不,你不会。请参阅上面的示例–您正在使用相对名称并利用默认文件系统,或者将路径从hdfs:// namenodeCLusterX / foo / bar更改为viewfs:// clusterX / foo / bar。
操作将某些文件从群集中的一个名称节点移动到另一个名称节点会发生什么?
操作可能会将文件从一个名称节点移动到另一个名称节点,以处理存储容量问题。他们将以某种方式避免应用程序中断。让我们举一些例子。
示例1:/ user和/ data在一个namenode上,后来它们需要在单独的namenode上以处理容量问题。实际上,操作将为/ user和/ data创建单独的安装点。在更改之前,/ user和/ data的装载将指向相同的namenode,例如namenodeContainingUserAndData。操作将更新安装表,以便将安装点分别更改为namenodeContaingUser和namenodeContainingData。
示例2:所有项目都安装在一个名称节点上,但是后来它们需要两个或多个名称节点。ViewFs允许像/ project / foo和/ project / bar这样的挂载。这允许将安装表更新为指向相应的名称节点。
挂载表是位于每个 core-site.xml中 还是位于其自己的单独文件中?
计划是将挂载表保存在单独的文件中,并使core-site.xml x包含其中。尽管可以将这些文件本地保存在每台计算机上,但最好使用HTTP从中央位置访问它。
配置是否应该仅对一个集群或所有集群都具有安装表定义?
该配置应具有所有集群的安装定义,因为一个集群需要访问其他集群中的数据,例如distcp。
考虑到Operations可能会随着时间更改安装表,何时实际读取安装表?
将作业提交到集群后,将读取安装表。该XInclude的在核心的site.xml在作业提交时间展开。这意味着,如果更改了挂载表,则需要重新提交作业。由于这个原因,我们要实现合并安装,这将大大减少更改安装表的需求。此外,我们希望通过将来在作业开始时初始化的另一种机制读取装入表。
JobTracker(或Yarn的资源管理器)本身会使用ViewF吗?
不,不需要。NodeManager也没有。
ViewF是否仅允许在最高级别进行安装?
没有; 它更一般。例如,可以挂载/ user / joe和/ user / jane。在这种情况下,将在安装表中为/ user创建一个内部只读目录。/ user上的所有操作均有效,但/ user是只读的。
应用程序可跨群集工作,并且需要永久存储文件路径。它应该存储哪些路径?
您应该存储viewfs:// cluster / path类型的路径名,与运行应用程序时使用的路径名相同。只要操作以透明的方式进行移动,就可以防止您在集群内名称节点内移动数据。如果数据从一个群集移动到另一个群集,它不会使您与外界隔离。无论如何,较旧的(联合身份验证)世界并不能保护您形成跨集群的此类数据移动。
委托令牌呢?
您要向其提交作业的集群的委托令牌(包括该集群的装入表的所有装入的卷),以及映射减少作业的输入和输出路径(包括通过装入表为指定的输入和输出装入的所有卷)路径)都是自动处理的。此外,在特殊情况下,还有一种方法可以将其他委托令牌添加到基本群集配置中。
通常,用户不必定义安装表或core-site.xml即可使用该安装表。这是通过操作完成的,并且在正确的网关机器上设置了正确的配置,就像今天对core-site.xml所做的一样。
可以在core-site.xml中描述挂载表,但是最好在core-site.xml中使用间接引用来引用单独的配置文件,例如mountTable.xml。将以下配置元素添加到core-site.xml中,以引用mountTable.xml:
<configuration xmlns:xi =“ http://www.w3.org/2001/XInclude”> <xi:include href =“ mountTable.xml” /> </ configuration>
在文件mountTable.xml中,有一个假设群集的装入表“ ClusterX”的定义,该群集是由三个名称节点管理的三个名称空间卷的联合
这里/ home和/ tmp在名称节点nn1-clusterx.example.com:8020管理的命名空间中,项目/ foo和/ bar托管在联合集群的其他名称节点上。主目录的基本路径设置为/ home,以便每个用户都可以使用FileSystem / FileContext中定义的getHomeDirectory()方法访问其主目录。
<配置> <属性> <name> fs.viewfs.mounttable.ClusterX.homedir </ name> <value> / home </ value> </ property> <属性> <name> fs.viewfs.mounttable.ClusterX.link./home </ name> <value> hdfs://nn1-clusterx.example.com:8020 / home </ value> </ property> <属性> <name> fs.viewfs.mounttable.ClusterX.link./tmp </ name> <value> hdfs://nn1-clusterx.example.com:8020 / tmp </ value> </ property> <属性> <name> fs.viewfs.mounttable.ClusterX.link./projects/foo </ name> <value> hdfs://nn2-clusterx.example.com:8020 / projects / foo </ value> </ property> <属性> <name> fs.viewfs.mounttable.ClusterX.link./projects/bar </ name> <value> hdfs://nn3-clusterx.example.com:8020 / projects / bar </ value> </ property> </ configuration>