在NameNode HA的基础上部署HDFS Federation 2015-05-27 22:30

版本信息

Hadoop版本:2.4.1

介绍

已经部署了基于QJM的HDFS HA环境,环境如下:

  • NameNode: ctrl, data01
  • DataNode: data01, data02, data03
  • JournalNode: data01, data02, data03
  • Zookeeper:data01, data02, data03

要在此环境的基础上,部署第二套NameNode,实现两套NameNode的联邦。目标进程部署关系如下:

  • NameNode: ctrl, data01, data02, dat03 —— 增加data02、data03部署NameNode
  • ZKFC:ctrl, data01, data02, dat03 —— 增加data02、data03部署ZKFC
  • DataNode: data01, data02, data03
  • JournalNode: data01, data02, data03
  • Zookeeper:data01, data02, data03

在data02、data03两个节点上增加部署NameNode和ZKFC。两个NameNode同样也是主备关系。

NameService和NameNodeID规划如下:

  • NameService: myns1, myns2
  • NameNodeID: mynn1,mynn2, mynn3, mynn4

hdfs-site.xml

NameService和NameNode的重新配置如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
<property>
    <name>dfs.nameservices</name>
    <value>myns1, myns2</value>
    <description>提供服务的NS逻辑名称,与core-site.xml或cmt.xml里的对应</description>   
</property>
<property>
    <name>dfs.ha.namenodes.myns1</name>
    <value>mynn1,mynn2</value>
</property>
<property>
    <name>dfs.ha.namenodes.myns2</name>
    <value>mynn3,mynn4</value>
</property>
<property>
    <name>dfs.namenode.rpc-address.myns1.mynn1</name>
    <value>ctrl:9000</value>
    <description>指定第一个NameNode的RPC位置</description>
</property>
<property>
    <name>dfs.namenode.http-address.myns1.mynn1</name>
    <value>ctrl:50070</value>
    <description>指定第一个NameNode的Web Server位置</description>
</property>
<property>
    <name>dfs.namenode.rpc-address.myns1.mynn2</name>
    <value>data01:9000</value>
    <description>指定第二个NameNode的RPC位置</description>
</property>
<property>
    <name>dfs.namenode.http-address.myns1.mynn2</name>
    <value>data01:50070</value>
    <description>指定第二个NameNode的Web Server位置</description>
</property>
<property>
    <name>dfs.namenode.rpc-address.myns2.mynn3</name>
    <value>data02:9000</value>
    <description>指定第一个NameNode的RPC位置</description>
</property>
<property>
    <name>dfs.namenode.http-address.myns2.mynn3</name>
    <value>data02:50070</value>
    <description>指定第一个NameNode的Web Server位置</description>
</property>
<property>
    <name>dfs.namenode.rpc-address.myns2.mynn4</name>
    <value>data03:9000</value>
    <description>指定第二个NameNode的RPC位置</description>
</property>
<property>
    <name>dfs.namenode.http-address.myns2.mynn4</name>
    <value>data03:50070</value>
    <description>指定第二个NameNode的Web Server位置</description>
</property>
<property>
    <name>dfs.client.failover.proxy.provider.myns1</name>
    <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
    <description>指定客户端用于HA切换的代理类,不同的NS可以用不同的代理类
        以上示例为Hadoop 2.0自带的缺省代理类</description>
</property>
<property>
    <name>dfs.client.failover.proxy.provider.myns2</name>
    <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
    <description>指定客户端用于HA切换的代理类,不同的NS可以用不同的代理类
        以上示例为Hadoop 2.0自带的缺省代理类</description>
</property>

注意:删除了如下配置:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<property>
    <name>dfs.nameservices</name>
    <value>myns</value>
    <description>提供服务的NameService逻辑名称,与core-site.xml里的对应</description>
</property>
<property>
    <name>dfs.ha.namenodes.myns</name>
    <value>mynn1,mynn2</value>
    <description>列出该逻辑名称下的NameNode逻辑名称</description>
</property>
<property>
    <name>dfs.namenode.rpc-address.myns.mynn1</name>
    <value>ctrl:9000</value>
    <description>指定第一个NameNode的RPC位置</description>
</property>
<property>
    <name>dfs.namenode.http-address.myns.mynn1</name>
    <value>ctrl:50070</value>
    <description>指定第一个NameNode的Web Server位置</description>
</property>
<property>
    <name>dfs.namenode.rpc-address.myns.mynn2</name>
    <value>data01:9000</value>
    <description>指定第二个NameNode的RPC位置</description>
</property>
<property>
    <name>dfs.namenode.http-address.myns.mynn2</name>
    <value>data01:50070</value>
    <description>指定第二个NameNode的Web Server位置</description>
</property>
<property>
    <name>dfs.client.failover.proxy.provider.myns</name>
    <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
    <description>指定客户端用于HA切换的代理类,不同的NS可以用不同的代理类
        以上示例为Hadoop 2.0自带的缺省代理类</description>
</property>
  • 经验

如果配置项【dfs.client.failover.proxy.provider.myns】漏掉了,会出现UnknownHostException:myns1的错误。

core-site.xml:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<configuration xmlns:xi="http://www.w3.org/2001/XInclude">
    <xi:include href="namenode_cmt.xml"/>
    <property>
        <name>fs.defaultFS</name>
        <value>viewfs://nsX</value>
        <description>整个Federation集群对外提供服务的NS逻辑名称,
            注意,这里的协议不再是hdfs,而是新引入的viewfs
            这个逻辑名称会在下面的挂载表中用到</description>
    </property>
</configuration>

注意:configuration需要增加xmlns:xi属性。同时xi:include/节点需要放在configuration内部。

namenode_cmt.xml:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<configuration>
    <property>
        <name>fs.viewfs.mounttable.nsX.link./share</name>
        <value>hdfs://myns1/real_share</value>
    </property>
    <property>
        <name>fs.viewfs.mounttable.nsX.link./user</name>
        <value>hdfs://myns2/real_user</value>
    </property>
</configuration>

复制配置文件

在ctrl节点上配置完上述配置后,将配置文件复制到其他三个节点:

scp namenode_cmt.xml core-site.xml hdfs-site.xml data01:/opt/hadoop/etc/hadoop/
scp namenode_cmt.xml core-site.xml hdfs-site.xml data02:/opt/hadoop/etc/hadoop/
scp namenode_cmt.xml core-site.xml hdfs-site.xml data03:/opt/hadoop/etc/hadoop/

准备

  • 停止HDFS
stop-dfs.sh
  • 在三台主机上启动Journal Node
[root@data01 /]# hadoop-daemon.sh start journalnode
[root@data02 /]# hadoop-daemon.sh start journalnode
[root@data03 /]# hadoop-daemon.sh start journalnode
  • 修改myns2的差异配置

修改data02、data03上的hdfs-site.xml,修改fs.namenode.shared.edits.dir为myns1不同的配置目录。

1
2
3
4
<property>
    <name>dfs.namenode.shared.edits.dir</name>
    <value>qjournal://data01:8485;data02:8485;data03:8485/namenode2-ha-data</value>
</property>

备注:第一套NameNode的目录是namenode-ha-data,第二套是namenode2-ha-data.

  • 格式化myns2中的NameNode

查询出第一套NameNode之前格式化生成的ClusterID(查询方法),使用相同的ClusterID格式化第二套NameNode:

hadoop namenode -format -clusterid CID-dcc791ba-00d8-4bb1-aab9-92ff06aafc12
  • 将myns2中data02节点格式化生成的name node数据复制到另一台。
[root@data02 dfs]# scp -r /opt/hadoop/dfs/name data03:/opt/hadoop/dfs/
  • 启动Hadoop集群
[root@ctrl ~]# start-dfs.sh
  • 将data02, data03节点初始化
[root@data02 ~]# hdfs namenode -bootstrapStandby
[root@data03 ~]# hdfs namenode -bootstrapStandby
  • 格式化myns2的ZK数据
[root@data02 ~]# hdfs zkfc -formatZK
  • 创建两个映射的目录
hdfs dfs -mkdir hdfs://ctrl:9000/real_share
hdfs dfs -mkdir hdfs://data03:9000/real_user

备注:假设myns1的主节点是ctrl,myns2的主节点是data03。

使用

  • 操作ViewFS上的文件
hdfs dfs -ls /
hdfs dfs -ls /user

注意:默认ViewFS的根路径/不能映射到具体的NameService上。

  • 操作某一个NameService上的文件
hdfs dfs -ls hdfs://myns1/
hdfs dfs -ls hdfs://myns1/real_user
  • 操作某一个NameNode上的文件
hdfs dfs -ls hdfs://ctrl:9000/
hdfs dfs -ls hdfs://data02:9000/

注意:只允许操作active状态下的NameNode上的文件,不允许操作standby状态的NameNode下的文件。

  • NameService之间、NameService与ViewFS之间的文件拷贝
hadoop distcp hdfs://myns1/spark /user/
hadoop distcp hdfs://myns1/spark hdfs://myns1/

DistCp的用法详见: HDFS DistCp命令使用

经验

Hadoop 2.4.1版本存在Bug(详情),如果core-site.xml中include时没有指定cmt.xml的绝对路径,而是指定相对路径。那么Yarn启动时会报错,ResourceManager无法正常启动。

规避办法是:把core-site.xml中include的相对路径,改为绝对路径。

更改上层组件配置

说明

如果使用VIewFS统一视图操作HDFS,因为只有映射后的目录才能使用,并且各个上层组件(如H ive,HBase等)使用起来较不方便。

因此,建议将HDFS的fs.defaultFS设置为myns1,默认访问第一个NameService。

core-site.xml

1
2
3
4
<property>
    <name>fs.defaultFS</name>
    <value>hdfs://myns1</value>
</property>

HBase

  • 修改配置文件

修改各个节点的/opt/hbase/conf/hbase-site.xml文件,将:

1
2
3
4
<property>
  <name>hbase.rootdir</name>
  <value>hdfs://ctrl:9000/hbase</value>
</property>

修改为:

1
2
3
4
<property>
  <name>hbase.rootdir</name>
  <value>hdfs://myns1/hbase</value>
</property>
  • 重启HBase

在HMaster节点:

stop-hbase.sh
start-hbase.sh
  • 测试
hbase shell
\> list
\> scan 'house'

Hive

Hive连接HDFS是直接使用HDFS的配置文件,HDFS配置文件中已经指定默认的FS是hdfs://myn s1,所以Hive无需额外配置,可以直接使用。

beeline --color=true --fastConnect=true
!connect jdbc:hive2://ctrl:10000
show tables;

注意:hive需要在HDFS中使用到一个临时目录{hive.exec.local.scratchdir},此目录需 要运行Hive的用户有写权限。

hdfs dfs -chmod 777 /tmp/hive

Spark

同Hive,Spark连接HDFS是直接使用HDFS的配置文件,HDFS配置文件中已经指定默认的FS是hd fs://myns1,所以Spark无需额外配置,可以直接使用。

spark-shell --master yarn
1
2
3
4
5
6
/* HDFS上的文件 */
var textRDD = sc.textFile("/tmp/a.txt")
var wordRDD = textRDD.flatMap( text => text.toString().split("\\s+"))
wordRDD.collect
/* HDFS上的文件 */
wordRDD.saveAsTextFile("/tmp/a2.txt.dir")

参考文档

  1. ViewFS Guide
Tags: #HDFS    Post on Hadoop