暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Hadoop3.x配置3-5个NameNode-HA

Coding On Road 2019-01-05
2688

配置hadoop高可靠集群

hadoop2.0已经发布了稳定版本了,增加了很多特性,比如HDFS HAYARN都可以配置HA(高可靠),在hadoop2.x时一个namenodeservice只能只多有两个namenode,而到了3.0一个nameservice可以有三个namenode或是更多以下是官方说明:

The minimum number of NameNodes for HA is two, but you can configure more. Its suggested to not exceed 5 - with a recommended 3 NameNodes - due to communication overheads.

配置过程列表:

Ø 配置规划。

Ø 配置从一台主机到其他主机的SSH免密码登录。

Ø 关闭所有主机的防火墙。

Ø 配置所有主机的静态地址和hosts文件。

Ø 所有主机上安装JDK1.8,并配置环境变量。

Ø 至少在三台主机上安装好zookeeper并启动zookeeper集群。

Ø 在一台主机上配好hadoop的所有配置文件,并分发到所有主机。

这些配置文件为:hadoop-env.shcore-site.xmlhdfs-site.xmlmapred-site.xmlyarn-site.xmlworkersstart-dfs.sh,stop-dfs.sh,start-yarn.sh,stop-yarn.sh

Ø 所有主机配置hadoop环境变量。

Ø 启动JournalNode

Ø 在某台配置了NameNode的主机上格式化NameNode

Ø 然后将格式化后的目录copy到其他的主机(主是指配置了NameNode的主机)

Ø 格式化zkfc

Ø 格式化NameNodecopy给其他namenode节点。

Ø 启动hdfs,启动yarn

1、配置表

配置表:

IP/主机名

软件

进程

192.168.56.21

server21

JDK1.8

Zookeeper3.4

Hadoop3.1.1

QuorumPeerMain

NameNode

ZKFC

QJM

ResourceManager

NodeManager

DataNode

192.168.56.22

server22

JDK1.8

Zookeeper3.4

Hadoop3.11

QuorumPeerMain

NameNode

ZKFC

QJM

ResourceManager

NodeManager

DataNode

192.168.56.23

server23

JDK1.8

Zookeeper3.4

Hadoop3.1.1

QuourmPeerMain

NameNode

ZKFC

QJM

ResourceManager

NodeManager

DataNode

 

2、前期准备

所有主机关闭防火墙。

所有主机安装JDK1.8,并配置环境变量。

所有主机设置静态IP地址,修改主机名称。

设置所有主机selinux=disabled

安装好zookeeper集群。并启动。

3、配置hadoop-env.sh文件

此文件中只配置JAVA_HOME环境变量

export JAVA_HOME=/usr/local/java/jdk1.8.0_131

4、配置core-site.xml文件

<configuration>

<!-- 指定hdfsnameservicens1 -->

<property>

<name>fs.defaultFS</name>

<value>hdfs://cluster</value>

</property>

<!-- 指定hadoop hdfs目录 -->

<property>

<name>hadoop.tmp.dir</name>

<value>/opt/hadoop/tmp</value>

</property>

<!-- 指定zookeeper地址 -->

<property>

<name>ha.zookeeper.quorum</name>

<value>server21:2181,server22:2181,server23:2181</value>

</property>

         <!--可选的配置QJM日志目录-->

<property>

<name>dfs.journalnode.edits.dir</name>

<value>/opt/hadoop/journal/local/data</value>

</property>

</configuration>

3)、配置hdfs-site.xml文件,这里的配置信息比较多

<configuration>

<!--指定hdfsnameservicecluster,需要和core-site.xml中的保持一致 -->

<property>

<name>dfs.nameservices</name>

<value>cluster</value>

</property>

<!-- ns1下面有NameNodehadoop3.0以后),分别是nn1nn2nn3 

 注意,namenodes后面为cluster即之前配置的名称

-->

<property>

<name>dfs.ha.namenodes.cluster</name>

<value>nn1,nn2,nn3</value>

</property>

<!--配置每一个NameNoderpc通信地址-->

<property>

<name>dfs.namenode.rpc-address.cluster.nn1</name>

<value>server21:8020</value>

</property>

<property>

<name>dfs.namenode.rpc-address.cluster.nn2</name>

<value>server22:8020</value>

</property>

<property>

<name>dfs.namenode.rpc-address.cluster.nn3</name>

<value>server23:8020</value>

</property>

<!--配置每一个NameNodeweb http地址-->

<property>

<name>dfs.namenode.http-address.cluster.nn1</name>

<value>server21:9870</value>

</property>

<property>

<name>dfs.namenode.http-address.cluster.nn2</name>

<value>server22:9870</value>

</property>

<property>

<name>dfs.namenode.http-address.cluster.nn3</name>

<value>server23:9870</value>

</property>

         <!--配置QJM的地址-->

<property>

<name>dfs.namenode.shared.edits.dir</name>

<value>qjournal://server21:8485;server22:8485;server23:8485/cluster</value>

</property>

<!--配置QJM日志的目录-->

<property>

<name>dfs.journalnode.edits.dir</name>

<value>/opt/hadoop/qjm/edits</value>

</property>

         <!--配置为自动切换功能打开,需要在core-site.xml文件中配置ZK地址-->

<property>

<name>dfs.ha.automatic-failover.enabled</name>

<value>true</value>

</property>

<property>

<name>dfs.client.failover.proxy.provider.cluster</name>

<value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>

</property>

        <!--配置自动切换的方式-->

<property>

      <name>dfs.ha.fencing.methods</name>

      <value>

sshfence

shell(/bin/true)

</value>

    </property>

         <!--配置SSH key,注意根据不同的用户名修改目录-->

<property>

      <name>dfs.ha.fencing.ssh.private-key-files</name>

      <value>/root/.ssh/id_rsa</value>

         </property>

     <property>

<name>dfs.permissions.enabled</name>

<value>false</value>

</property>

<!-- 配置sshfence隔离机制超时时间 -->

<property>

<name>dfs.ha.fencing.ssh.connect-timeout</name>

<value>30000</value>

</property>

</configuration>

5、配置mapred-site.xml

<configuration>

<!-- 指定mr框架为yarn方式 -->

<property>

<name>mapreduce.framework.name</name>

<value>yarn</value>

</property>

</configuration>

6、配置yarn-site.xml

<configuration>

<!--配置RM高可靠-->

<property>

  <name>yarn.resourcemanager.ha.enabled</name>

  <value>true</value>

</property>

<property>

  <name>yarn.resourcemanager.cluster-id</name>

  <value>cluster1</value>

</property>

    <!--配置Resourcemanager个数,hadoop3以后可以为35-->

<property>

  <name>yarn.resourcemanager.ha.rm-ids</name>

  <value>rm1,rm2,rm3</value>

</property>

    <!--以下配置每一个RM的地址-->

<property>

 <name>yarn.resourcemanager.hostname.rm1</name>

  <value>server21</value>

</property>

<property>

  <name>yarn.resourcemanager.hostname.rm2</name>

  <value>server22</value>

</property>

<property>

<name>yarn.resourcemanager.hostname.rm3</name>

<value>server23</value>

</property>

    <!--配置每一个RMhttp地址-->

<property>

  <name>yarn.resourcemanager.webapp.address.rm1</name>

  <value>server21:8088</value>

</property>

<property>

  <name>yarn.resourcemanager.webapp.address.rm2</name>

  <value>server22:8088</value>

</property>

<property>

<name>yarn.resourcemanager.webapp.address.rm3</name>

<value>server23:8088</value>

</property>

    <!--配置zookeeper地址-->

<property>

  <name>yarn.resourcemanager.zk-address</name>

  <value>server21:2181,server22:2181,server23:2181</value>

</property>

<property>

<name>yarn.nodemanager.aux-services</name>

<value>mapreduce_shuffle</value>

</property>

    <!--hadoop3里面必须要添加的classpath-->

<property>

<name>yarn.application.classpath</name>

<value>/opt/hadoop-3.1.1/etc/hadoop:/opt/hadoop-3.1.1/share/hadoop/common/lib/*:/opt/hadoop-3.1.1/share/hadoop/common/*:/opt/hadoop-3.1.1/share/hadoop/hdfs:/opt/hadoop-3.1.1/share/hadoop/hdfs/lib/*:/opt/hadoop-3.1.1/share/hadoop/hdfs/*:/opt/hadoop-3.1.1/share/hadoop/mapreduce/lib/*:/opt/hadoop-3.1.1/share/hadoop/mapreduce/*:/opt/hadoop-3.1.1/share/hadoop/yarn:/opt/hadoop-3.1.1/share/hadoop/yarn/lib/*:/opt/hadoop-3.1.1/share/hadoop/yarn/*</value>

</property>

</configuration>

7、配置workers文件

workers是指定DataNode节点的位置。在里面添加主机的名称或是ip地址即可,一行一个

 server21

server22

server23

8、配置start-dfs.sh/stop-dfs.sh

在中间位置,找到一个空白的位置添加:

HDFS_NAMENODE_USER=root

HDFS_SECONDARYNAMENODE_USER=root

HDFS_DATANODE_USER=root

HDFS_DATANODE_SECURE_USER=root

#以下是高可靠配置的

HDFS_JOURNALNODE_USER=root

HDFS_ZKFC_USER=root

9、配置start-yarn.sh/stop-yarn.sh

在两个配置文件中间位置添加以下内容:

YARN_RESOURCEMANAGER_USER=root

YARN_NODEMANAGER_USER=root

10、现在配置hadoop的环境变量

export HADOOP_HOME=/opt/hadoop-3.x

export PATH=$PATH:$HADOOP_HOME/bin

 让环境变量生效,执行以下命令

$source etc/profile

11、拷贝文件其他主机

将配置好的hadoop目录hadoop配置文件copy到其他主机相同的目录下使用scp命令由于share目录下的doc里面都是文档,可以删除这个目录,以加快copy速度。

$ scp -r /opt/hadoop-3/  server22:/opt/

12、启动journalnode

分别在在server21server22server23上执行

$ ./hadoop-daemon.sh start journalnode

13、格式化HDFS

#server21上执行命令:

hdfs namenode -format

格式化后会在根据core-site.xml中的hadoop.tmp.dir配置生成个文件,然后将这个文件使用scp拷贝到weric12的相同目录下。因为,都是NameNode节点,必须要拥有相同的数据文件。格式化成功的标志是在输出的日志中查看是否存在以下语句:

Storage directory /opt/hadoop_tmp_dir/dfs/name has been successfully formatted

现在将格式化后的hdfs目录,拷贝到weric12主机上的相同目录下:

$ scp -r /opt/hadoop/tmp/  server22:/opt/

14、格式化zkfc

server21上执行

hdfs zkfc -formatZK

Successfully created hadoop-ha/cluster in ZK.

在格式化完成以后,通过zkCli.sh登录zookeeper并查看目录列表,将显示一个hadoop-ha的目录,表示初始化成功

[zk: localhost:2181(CONNECTED) 0] ls

[zookeeper, hadoop-ha]

15、启动HDFS(在server21上执行)

 server21上启动hdfsNameNode同时也会将server22,server23nameNode一并启动。

$ ./start-dfs.sh

16、启动YARN

server21上执行:

$ ./start-yarn.sh

在启动完成以后,根据之前的配置列表,分别检查每一个主机上的服务是否都已经启动。如果没有请查看日志错误。

17、验证高可靠

通过浏览器访问以下是地址可以查看hdfs的信息,如图7.4.3所示:

http://192.168.56.21:9870

 

 

 

7.4.3

通过图7.4.3可以看出当前NameNodeactive。而通过图7.4.4所示weric12上的NameNodeStandby


7.4.4

也可以通过以下命令,检查NameNodeResourceManager的状态

$ hdfs haadmin -getServiceState nn1

active

$ hdfs haadmin -getServiceState nn2

standby

$ yarn rmadmin -getServiceState rm1

active

$ yarn rmadmin -getServiceState rm2

standby

现在让我们killactiveNameNode,即killnn1

$kill -9 <pid of NN>

然后再检查状态,这个时候weric12上的NameNode变成了active

$ hdfs haadmin -getServiceState nn2

active

手动启动那个挂掉的NameNode,即nn1,然后再检查状态,它已经成为standby的了

$./hadoop-daemon.sh start namenode

$ hdfs haadmin -getServiceState nn1

standby

使用同的样的方式,可以验证ResourceManager是否可以自动实现容灾切换。

 

有可能出现的问题:

 

问题地址:

https://issues.apache.org/jira/browse/HDFS-3447

即:如果hadoop有多个NameNode,如果访问到第二个NameNode还是StandayBy就会出现以上的Debug信息。但不影响使用。

所以,我们还是建议配置两个NameNode,实在是没有必要配置3-5NameNode

 

 

 

【注意】

1:在集群完成以后,建议执行一个mapreduce测试,如wordcount

    2Hadoop的高可靠集群每一次启动相对比较麻烦。但配置成功以后,下次启动就相对比较简单了。对于上面的示例而言,再次启动只要在server21主机上执行./start-dfs.sh./start-yarn.sh即可。

【注意】

关于免密码登录的说明

要求能通过免登录包括使用IP和主机名都能免密码登录:

1) NameNode能免密码登录所有的DataNode

2) 各NameNode能免密码登录自己

3) 各NameNode间能免密码互登录

4) DataNode能免密码登录自己

5) DataNode不需要配置免密码登录NameNode和其它DataNode6) ResourceManager必须要免密码登录所有DataNode以便于启动NodeManager

7.5、用Java代码操作集群

Java客户端面操作集群开发hdfs,必须要指定nameService的配置信息。以下是代码示例,以下代码显示hdfs上的文件和目录:

package cn.hadoop.hdfs;

import org.apache.hadoop.conf.Configuration;

import org.apache.hadoop.fs.FileStatus;

import org.apache.hadoop.fs.FileSystem;

import org.apache.hadoop.fs.Path;

/**

 * 访问HA-HDFS

 * @author wangjian

 * @version 1.0 2019年1月5日

 */

public class Demo01_HA {

public static void main(String[] args) throws Exception {

System.setProperty("HADOOP_USER_NAME","root");

Configuration config = new Configuration();

config.set("fs.defaultFS", "hdfs://cluster");

config.set("dfs.nameservices", "cluster");

config.set("dfs.ha.namenodes.cluster", "nn1,nn2");

config.set("dfs.namenode.rpc-address.cluster.nn1", "server21:8020");

config.set("dfs.namenode.rpc-address.cluster.nn2", "server22:8020");

config.set("dfs.client.failover.proxy.provider.cluster", //

"org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider");

FileSystem fs = FileSystem.get(config);

FileStatus[] fileStatus  = fs.listStatus(new Path("/"));

for(FileStatus f:fileStatus) {

System.out.println(">>:"+f.getPath());

}

fs.close();

}

}

 

保存一个文件:

//设置用户名为root用户

System.setProperty("HADOOP_USER_NAME","root");

Configuration config = new Configuration();

config.set("fs.defaultFS", "hdfs://cluster");

config.set("dfs.nameservices", "cluster");

config.set("dfs.ha.namenodes.cluster", "nn1,nn2");

config.set("dfs.namenode.rpc-address.cluster.nn1", "server21:8020");

config.set("dfs.namenode.rpc-address.cluster.nn2", "server22:8020");

config.set("dfs.client.failover.proxy.provider.cluster", //

"org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider");

FileSystem fs = FileSystem.get(config);

OutputStream out = fs.create(new Path("/test/c.txt"));

out.write("JackAndMary".getBytes());

out.write("中文数据".getBytes());

out.close();

fs.close();

 

 

 

 

其他更多操示例,请自行开发。


文章转载自Coding On Road,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论