ViewFs
联邦存在的问题
通过HDFS联邦实现了单一集群多个namespace,并且所有namnode共享所有datanode的存储,这样一来将不同的数据存储在不同的namespace,从而解决了namenode的扩展问题。同样,它有其缺点:使用不便。现在数据存储在不同的namespace,因此访问时必须写上具体的地址。
实现
ViewFS全称是ViewFileSystem,它只是实现了标准的Hadoop FileSystem接口的逻辑上一个视图文件系统。主要是给用户提供统一的全局HDFS访问入口,这样自然就解决上述不便。
简而言之,路径映射。它借鉴Linux的client-side mount table(客户端挂载表),利用mount table将多个NS的文件路径和逻辑目录做一个统一的映射绑定, 从而使得客户端能通过ViewFS快速访问不同的NS路径。
典型配置
core-site.xml中
<property>
<name>fs.defaultFS</name>
<value>viewfs://clusterX</value>
</property>
<configuration>
<property>
<name>fs.viewfs.mounttable.ClusterX.link./data</name>
<value>hdfs://nn1-clusterx.example.com:8020/data</value>
</property>
<property>
<name>fs.viewfs.mounttable.ClusterX.link./project</name>
<value>hdfs://nn2-clusterx.example.com:8020/project</value>
</property>
<property>
<name>fs.viewfs.mounttable.ClusterX.link./user</name>
<value>hdfs://nn3-clusterx.example.com:8020/user</value>
</property>
<property>
<name>fs.viewfs.mounttable.ClusterX.link./tmp</name>
<value>hdfs://nn4-clusterx.example.com:8020/tmp</value>
</property>
<property>
<name>fs.viewfs.mounttable.ClusterX.linkFallback</name>
<value>hdfs://nn5-clusterx.example.com:8020/home</value>
</property>
</configuration>
(所有有关viewfs mount table的配置都是以fs.viewfs.mounttable为前缀的)
通过配置可以看出fs.defaultFS的值变成了统一的以viewfs开头的uri,并且 /data链接到了hdfs://nn1-clusterx.example.com:8020/data,/project链接到了hdfs://nn2-clusterx.example.com:8020/project,那么如果用户访问了/data路径,通过这个配置文件,我们就知道直接到hdfs://nn1-clusterx.example.com:8020集群的/data 路径下拿数据,其他同理。至于linkFallback,如果访问的路径在配置文件里面没找到,那么将会访问fs.viewfs.mounttable.ClusterX.linkFallback属性配置的集群和路径。
<configuration>
<property>
<name>fs.viewfs.mounttable.ClusterY.linkMergeSlash</name>
<value>hdfs://nn1-clustery.example.com:8020/</value>
</property>
</configuration
另外通过linkMergeSlash可以将ClusterY的根目录合并到hdfs://nn1-clustery.example.com:8020/
所以,在接收到应用的调用时,客户端通过维护的mount-table来解析用户的访问请求,并找到对应的底层存储目录,转发相应的请求到底层存储。
缺点
诚然,利用Federation和ViewFs很好解决了遇到的问题,但同样它也有缺点。mount-table是用来给客户端使用的,并不是一种服务端的解析。这样一旦涉及修改,则必须分发到所有的客户端,升级维护困难。同时也没有负载均衡,实现需要人工介入。
配置示例
mount-table的配置可以在core-site.xml,但间接的在core-site.xml中引用一个单独的mountTable.xml更好。
<configuration xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include href="mountTable.xml" />
</configuration>
<configuration>
<property>
<name>fs.viewfs.mounttable.ClusterX.homedir</name>
<value>/home</value>
</property>
<property>
<name>fs.viewfs.mounttable.ClusterX.link./home</name>
<value>hdfs://nn1-clusterx.example.com:8020/home</value>
</property>
<property>
<name>fs.viewfs.mounttable.ClusterX.link./tmp</name>
<value>hdfs://nn1-clusterx.example.com:8020/tmp</value>
</property>
<property>
<name>fs.viewfs.mounttable.ClusterX.link./projects/foo</name>
<value>hdfs://nn2-clusterx.example.com:8020/projects/foo</value>
</property>
<property>
<name>fs.viewfs.mounttable.ClusterX.link./projects/bar</name>
<value>hdfs://nn3-clusterx.example.com:8020/projects/bar</value>
</property>
</configuration>