目录
2.2查看node1上namenode VERSION的clusterid
2.3node4节点安装secondary namenode
1.基本概念
1.1背景
HDFS主要包括两层:
Namespace
由目录,文件和块组成。支持所有文件系统操作包括增加,删除,修改和列出文件和目录
Block Storage Service
有两个部分:
Block管理(包含于NameNode)提供datanode集群的注册和定期的心跳检查,处理block的报告并掌握block的位置;支持block的相关操作,如增删改查和得到block的位置管理副本位置,管理副本的复制和删除。
存储-本地系统的datanodes提供,允许读写。
多NameNode/NameSpace
为了水平扩展,HDFS联盟使用多个独立的Namenodes/namespaces。这些Namenodes是独立的,不需要互相协调。DataNode被所有的NameNode使用用来作为通用的数据块存储设备。每一个DataNode注册集群中所有的NameNode。Datanodes发送心跳和block报告并且处理NameNode发送的命令。
Block 池:
一个block池是一个隶属于一个namespace的所有block的集合。DataNode为所有的block池储存集群当中的block信息。block池被独立管理,互不影响。这个设计将允许为新的block产生Block ID并不会需要其他的namespace。一个NameNode出问题也不会影响datanode为集群中的其他NameNode服务。
Namespace和block池在一起叫做 Namespace Volume(Namespace 卷)。它是一个独立的单位管理。当一个Namenode/namespace被删除的时候,在datanodes中的对应的block池也会被删除。在集群升级时,一个namespace volume是一个升级单元。
ClusterID
一个新的标示ClusterID用来标示集群当中所有的节点。当一个Namenode被格式化,这个标识符或自动生成的。这个ID会被用来格式化集群中的其他Namenode。
HDFS联盟关键的好处
Namespace扩展性-HDFS集群可以通过水平扩展但是namespace不行。大型部署或者是小文件较多的系统可以通过向集群添加更多的NameNode获益。
性能-之前的架构中文件系统的吞吐量收单一NameNode限制。添加更多的NameNode会提高读写的吞吐量
隔离 - 一个NameNode无法隔离多用户环境,实验的程序可能造成Namenode变慢,影响生产环境,多个Namenodes使得不同类别的应用程序和用户可以分离不同的名称空间。
配置步骤概括
- 添加一个新的NameNode到一个既存的HDFS集群(core-site.xml)。
- 添加配置参数dfs.nameservices到配置文件且使用NameServiceID 作为后缀更新配置文件(hdfs-site.xml)。
- 将配置文件同步到集群当中的所有节点。
- 格式化并启动新增的Namenode节点,注意使用clusterid(尤其在大集群新增多个namenode)。
- 启动新的 Secondary/Backup节点。
- 刷新datanode获取新添加的namenode。
- 使用jps与HDFS UI检查配置是否成功。
2.测试配置
测试说明:理论上而言:完全可以实现三节点集群的HDFS联邦(实际操作三节点配置成功),但是三节点意味着有一个namenode无法配备SecondaryNamenode(或者某一节点需要承担两个节点的SNN任务),这对于用户实际使用是并不友善的(尤其考虑到再联合使用HA的情况)。所以文档中以四节点集群为例执行HDFS联邦测试。
测试环境:
操作系统:centos 6.5
四台虚拟机基本信息:
| hostname | IP |
1 | node1 | 101.12.27.40(原本namenode) |
2 | node2 | 101.12.27.41(原本SNN) |
3 | node3 | 101.12.27.42(新NN) |
4 | node4 | 101.12.27.43(新SNN) |
2.1界面配置参数
在HDP的Web界面配置参数:
在自定义hdfs-site.xml中添加如下配置:
在配置文件中加入如下参数: dfs.nameservices: 一些NameServiceID,用逗号隔开. 这个参数是被datanode用来识别namenode的.
<configuration>
<property>
<name>dfs.nameservices</name>
<value>ns1,ns2</value>
</property>
<!--每一个 Namenode和Secondary Namenode 加上以自己对应的NameServiceID 为后缀的参数-->
<property>
<name>dfs.namenode.rpc-address.ns1</name>
<value>node1:8020</value>
</property>
<property>
<name>dfs.namenode.http-address.ns1</name>
<value>node1:50070</value>
</property>
<property>
<name>dfs.namenode.secondary.http-address.ns1</name>
<value> node2:50090</value>
</property>
<property>
<name>dfs.namenode.rpc-address.ns2</name>
<value> node3:8020</value>
</property>
<property>
<name>dfs.namenode.http-address.ns2</name>
<value> node3:50070</value>
</property>
<property>
<name>dfs.namenode.secondary.http-address.ns2</name>
<value> node4:50090</value>
</property>
</configuration>
修改core-site.xml中配置:
注意,此处对应的官网链接为,增加fs.defaultFS的namenode列表属于推测执行,对应下图的第三步,官网给的配置也很模糊,翻译过来第三步就是到配置文件增加与新NameNode相关的配置。。哪个配置文件具体啥配置都没说,汗,http://hadoop.apache.org/docs/current/hadoop-project-dist/hadoop-hdfs/Federation.html。实际上这一步可以简单推测下该如何操作
- 1.不增加新的namenode,那么使用联邦特性的意义不大,每次操作还是默认提交到旧的namenode上。
- 2.增加新的namenode,无法将其一般化,例如集群节点数上千,namenode有10个左右的情况,操作会很不方便,同时会报错incomplete HDFS URI。
- 3.最后发现这个地方需要按照ViewFS的配置来,具体见后面的分析。
2.2查看node1上namenode VERSION的clusterid
登录node1节点执行以下命令:
磁盘数据信息:/hadoop/hdfs/data/current/BP-1527498365-101.12.27.1-1512955906990/current/finalized/subdir0/subdir0
[root@node1 ~]# cat /hadoop/hdfs/namenode/current/VERSION
登录node3节点:
创建目录:
[root@node3 hdfs]# mkdir /hadoop/hdfs/namenode
[root@node3 hdfs]# chown hdfs:hadoop /hadoop/hdfs/namenode
执行格式化命令:
[root@node3 ~]# su hdfs
[hdfs@node3 hdfs]$ hdfs namenode -format -clusterid <clusterid>
启动namenode:
[hdfs@node3 ~]# /usr/hdp/current/hadoop-hdfs-datanode/../hadoop/sbin/hadoop-daemon.sh start namenode
2.3node4节点安装secondary namenode
登录到node4上创建namesecondary文件:
[root@node4 ~]# mkdir -p /hadoop/hdfs/namesecondary/current/
[root@node4 ~]# chown hdfs:hadoop /hadoop/hdfs/namesecondary/
[root@node4 ~]# chown hdfs:hadoop /hadoop/hdfs/namesecondary/current/
将node3上namenode的文件拷贝到node4的/hadoop/hdfs/namesecondary/current下
[root@node3 current]$ scp /hadoop/hdfs/namenode/current/* 101.12.27.43:/hadoop/hdfs/namesecondary/current
修改node4中/hadoop/hdfs/namesecondary/current下所有文件权限为hdfs:Hadoop
[root@node4 ~]# chown hdfs:hadoop /hadoop/hdfs/namesecondary/current/*
[root@node4 current]# ll /hadoop/hdfs/namesecondary/current
[hdfs@node4 hdfs]# /usr/hdp/current/hadoop-hdfs-namenode/../hadoop/sbin/hadoop-daemon.sh start secondarynamenode
启动成功后启动集群所有服务
2.4查看namenode的webUI
可以查看两个namenode的webUI:
Namenode1:
Namenode2:
在创建并查看namenode3的目录可以向其中添加自己想要的信息:
[hdfs@node3 namesecondary]$ hdfs dfs -mkdir hdfs://node3:8020/input
[hdfs@node3 namesecondary]$ hdfs dfs -ls hdfs://node3:8020/
在各个节点hdfs下使用刷新命令
[hdfs@node3 ~]$hdfs dfsadmin -refreshNamenodes 101.12.27.40:8010(8010)
在各个节点均可以使用jps查看是否联邦成功
3.命令行接口的统一
在Hadoop 2中,由于引入了HDFS Federation,当你启用该功能时,会同时存在多个可用的namenode,为了便于配置“fs.default.name”,你可以规划这些namenode的使用方式,比如图片组使用namenode1,爬虫组使用namenode2等等,这样,爬虫组员工使用的HDFS client端的core-site.xml文件可进行如下配置:
<property>
<name>fs.defaultFS</name>
<value>hdfs://namenode1:9000</value>
</property>
图片组员工使用的HDFS client端的core-site.xml文件可进行如下配置:
<property>
<name>fs.default.name</name>
<value>hdfs://namenode2:9000</value>
</property>
从HDFS和HBase使用者角度看,当仅仅使用单NameNode上管理的数据时,是没有问题的,即对应的用户使用对应namenode(nameservice)里面的块池,而块池中这些块实际分布在各个datanode上。但是,当考虑HDFS之上的计算类应用,比如YARN/MapReduce应用程序,则可能出现问题。因为这类应用可能涉及到跨Nameservice数据读写,即数据的跨块池应用,这样必须显式的指定全URI,即输入输出目录中必须显式的提供类似“hdfs://namenode2:9000”的前缀,以注明目录管理者NameNode的访问地址。比如:
distcp hdfs://nnClusterY:port/pathSrc hdfs://nnCLusterZ:port/pathDest
为了解决这种麻烦,为用户提供统一的全局HDFS访问入口,HDFS Federation借鉴Linux提供了client-side mount table,这是通过一层新的文件系统viewfs实现的。
3.1 Viewfs配置
viewfs实际上提供了一种映射关系,将一个全局(逻辑)目录映射到某个具体的namenode(物理)目录上,采用这种方式后,core-site.xml配置如下:
在客户端(集群外部,后台)高级core-site.xml里面直接配置fs.defaultFS
cd /etc/hadoop/conf修改core-site.xml配置如下:
<configuration xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include href="mountTable.xml"/>
<property>
<name>fs.defaultFS</name>
<value>viewfs://testcluster/</value>
</property>
…
</configuration>
其中,“testcluster”为集群名字(官方文档如此说明,实际上名字可以随便起,已验证),指向client-side mount table。mountTable.xml配置了全局(逻辑)目录与具体namenode(物理)目录的映射关系,你可以类比linux挂载点来理解。
以上文为例,你的集群中有两个namenode,分别是namenode1,namenode2,其中,令namenode1管理原本的/user目录,namenode2管理/input目录。另外设置根目录为/home,则用户调用getHomeDirectory()接口时,就可以指向该路径。并在与hdfs-site.xml同一路径下增加mountTable.xml,mountTable.xml中进行如下配置:
<configuration>
<property>
<name>fs.viewfs.mounttable.testcluster.link./user</name>
<value>hdfs://node1:8020/user</value>
</property>
<property>
<name>fs.viewfs.mounttable.testcluster.link./input</name>
<value>hdfs://node3:8020/input</value>
</property>
</configuration>
经过以上配置后,你可以像以前方式那样,访问HDFS上的文件,比如(只是此时的主目录变为了逻辑路径而非实际的物理路径):
[hdfs@node1 root]$ hdfs dfs -ls /
中的“hdfs dfs –ls /”将被映射成“ hdfs://node3:8020/input”与“ hdfs://node1:8020/user”。文件对比如下,可知命令行统一接口配置成功:
Client-side mount table的引入为用户使用HDFS带来极大的方便,尤其是跨namenode的数据访问。
注意:如果直接配置映射无法成功,请在后台添加如下自定义core-site.xml配置并scp分发至各个节点,不要在前端修改,HDP前端操作修改配置再保存重启会引发hdfs-site.xml与core-site.xml配置的覆盖:
<property>
<name>fs.AbstractFileSystem.file.impl</name>
<value>org.apache.hadoop.fs.local.LocalFs</value>
</property>
<property>
<name>fs.AbstractFileSystem.hdfs.impl</name>
<value>org.apache.hadoop.fs.Hdfs</value>
</property>
<property>
<name>fs.AbstractFileSystem.viewfs.impl</name>
<value>org.apache.hadoop.fs.viewfs.ViewFs</value>
</property>
参考:
http://hadoop.apache.org/docs/current/hadoop-project-dist/hadoop-hdfs/Federation.html
http://dongxicheng.org/hadoop-hdfs/hdfs-federation-viewfs/
http://dongxicheng.org/mapreduce/hdfs-federation-introduction/
注:对Hadoop的入门,几乎全靠官网和董西成老师的blog,如果对Hadoop common的原理和源码感兴趣,又不想太多的查看官网的全英文文档,可以去买一下董西成老师的《Hadoop技术内幕》,非推销,看过blog才买的书,书里也讲的很深入。