Hadoop 2.8 的namenode 从单点向双namenode的HA的升级过程,含wordcount验证

来源:互联网 发布:天天有喜知画扮演者 编辑:程序博客网 时间:2024/06/15 02:49

原文地址点击此处

参考文章见本文末尾


本文的主机规划如下所示(jdk、关闭防火墙、免密码ssh登录这些就不在此多做介绍了)

编号ip主机名用途安装软件1192.168.122.10xxCentosZeroNameNode(active)、JournalNodeHadoop、zookeeper2192.168.122.11xxCentosOneNameNode(standby)、JournalNodeHadoop、zookeeper3192.168.122.12xxCentosTwoDataNode、JournalNodeHadoop、zookeeper4192.168.122.13xxCentosThreeDataNodeHadoop、zookeeper5192.168.122.14xxCentosFourDataNodeHadoop、zookeeper


配置双namenode的目的就是为了防错,防止一个namenode挂掉数据丢失,具体原理本文不详细讲解,这里只说明具体的安装过程。

Hadoop HA的搭建是基于Zookeeper的,关于Zookeeper的搭建可以查看这里 hadoop、zookeeper、hbase、spark集群环境搭建 ,本文可以看做是这篇文章的补充。这里讲一下Hadoop配置安装。

配置Hadoop文件

需要修改的配置文件在$HADOOP_HOME/etc/hadoop目录下面,具体修改内容如下:

core-site.xml

 <!-- 指定hdfs的nameservice为lw_ns--> <property>      <name>fs.defaultFS</name>      <value>hdfs://lw_ns</value> </property> <!--指定hadoop数据临时存放目录--> <property>      <name>hadoop.tmp.dir</name>      <value>/usr/local/hadoop/tmp</value> </property> <property>      <name>io.file.buffer.size</name>      <value>4096</value> </property> <!--指定zookeeper地址--> <property>      <name>ha.zookeeper.quorum</name>      <value>CentosZero:2181,CentosOne:2181,CentosTwo:2181,CentosThree:2181,CentosFour:2181</value> </property>

说明一下,core-site.xml中的fs.defaultFS键对应的值一定要和hdfs-site.xml中的dfs.nameservices键的值一致


hdfs-site.xml

<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet type="text/xsl" href="configuration.xsl"?><!--  Licensed under the Apache License, Version 2.0 (the "License");  you may not use this file except in compliance with the License.  You may obtain a copy of the License at    http://www.apache.org/licenses/LICENSE-2.0  Unless required by applicable law or agreed to in writing, software  distributed under the License is distributed on an "AS IS" BASIS,  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the specific language governing permissions and  limitations under the License. See accompanying LICENSE file.--><!-- Put site-specific property overrides in this file. --><configuration><!-- 指定hdfs的nameservice为ns,需要和core-site.xml中的保持一致 --><property><name>dfs.nameservices</name><value>lw_ns</value></property><!-- ns下面有两个NameNode,分别是 lw_nn_0 ,lw_nn_1 --><property><name>dfs.ha.namenodes.lw_ns</name><value>lw_nn_0,lw_nn_1</value></property><!-- lw_nn_0 的RPC通信地址 --><property><name>dfs.namenode.rpc-address.lw_ns.lw_nn_0</name><value>CentosZero:9000</value></property><!-- lw_nn_0 的http通信地址 --><property><name>dfs.namenode.http-address.lw_ns.lw_nn_0</name><value>CentosZero:50070</value></property><!-- lw_nn_1 的RPC通信地址 --><property><name>dfs.namenode.rpc-address.lw_ns.lw_nn_1</name><value>CentosOne:9000</value></property><!-- lw_nn_1 的http通信地址 --><property><name>dfs.namenode.http-address.lw_ns.lw_nn_1</name><value>CentosOne:50070</value></property><!-- 20170526注释掉原有的非高可用状态下的访问地址。<property><name>dfs.http.address</name><value>CentosOne:50070</value></property><property><name>dfs.namenode.secondary.http-address</name><value>CentosOne:50090</value></property>--><!-- 指定NameNode的元数据在JournalNode上的存放位置 --><property>       <name>dfs.namenode.shared.edits.dir</name>       <value>qjournal://CentosZero:8485;CentosOne:8485;CentosTwo:8485/lw_ns</value>  </property>  <!-- 指定JournalNode在本地磁盘存放数据的位置 -->  <property>        <name>dfs.journalnode.edits.dir</name>        <value>/usr/local/hadoop/journal</value>  </property>  <!-- 开启NameNode故障时自动切换 -->  <property>        <name>dfs.ha.automatic-failover.enabled</name>        <value>true</value>  </property>  <!-- 配置失败自动切换实现方式 -->  <property>          <name>dfs.client.failover.proxy.provider.ns</name>          <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>  </property>  <!-- 配置隔离机制 -->  <property>           <name>dfs.ha.fencing.methods</name>           <value>sshfence</value>  </property>  <!-- 使用隔离机制时需要ssh免登陆 -->  <property>          <name>dfs.ha.fencing.ssh.private-key-files</name>          <value>/root/.ssh/id_rsa</value>  </property>    <!-- 当前节点为name节点时的元信息存储路径.这个参数设置为多个目录,那么这些目录下都保存着元信息的多个备份 -->  <property>      <name>dfs.namenode.name.dir</name>      <value>file:///usr/local/hadoop/somedata/name</value>  </property>  <!-- 当前节点为data节点时的元信息存储路径.这个参数设置为多个目录,那么这些目录下都保存着数据信息的多个备份 -->  <property>      <name>dfs.datanode.data.dir</name>      <value>file:///usr/local/hadoop/somedata/data</value>  </property>  <property><name>dfs.replication</name><value>2</value></property><property><name>dfs.permissions.enabled</name>        <value>false</value></property></configuration>
这里要说明一下,dfs.namenode.name.dir和dfs.datanode.data.dir的写法一定要加 file://。否则启动会说路径不合法

dfs.journalnode.edits.dir键的值保存的是namenodeHA的nameService的信息。所有启动了journal进程的主机的该路径下都会有内容

还一点就是,虽然上面定义了lw_nn_0和lw_nn_1,但是不代表0一定是alive,另一个一定是standby。启动时,这两个会随机产生一个alive


mapred-site.xml

<property>        <name>mapreduce.framework.name</name>        <value>yarn</value> </property>

yarn-site.xml

 <!-- 指定nodemanager启动时加载server的方式为shuffle server -->    <property>            <name>yarn.nodemanager.aux-services</name>            <value>mapreduce_shuffle</value>     </property>     <property>            <name>yarn.nodemanager.aux-services.mapreduce_shuffle.class</name>            <value>org.apache.hadoop.mapred.ShuffleHandler</value>     </property>     <!-- 指定resourcemanager地址 -->     <property>            <name>yarn.resourcemanager.hostname</name>            <value>CentosOne</value>      </property>

以上两个配置是原作者的,我只是修改了主机名,但是我的实际情况是,仍然使用我之前的非HA的配置方式,如下所示

mapred-site.xml

<configuration>    <property>        <name>mapred.job.tracker</name>        <value>CentosOne:9001</value>    </property>    <property>        <name>mapred.map.tasks</name>        <value>20</value>    </property>    <property>        <name>mapred.reduce.tasks</name>        <value>4</value>    </property>    <property>        <name>mapreduce.framework.name</name>        <value>yarn</value>    </property>    <property>        <name>mapreduce.jobhistory.address</name>        <value>CentosOne:10020</value>    </property>    <property>        <name>mapreduce.jobhistory.webapp.address</name>        <value>CentosOne:19888</value>    </property></configuration>

yarn-site.xml

<configuration><!-- Site specific YARN configuration properties -->        <property>                <name>yarn.resourcemanager.address</name>                <value>CentosOne:8032</value>        </property>        <property>                <name>yarn.resourcemanager.scheduler.address</name>                <value>CentosOne:8030</value>        </property>        <property>                <name>yarn.resourcemanager.webapp.address</name>                <value>CentosOne:8088</value>        </property>        <property>                <name>yarn.resourcemanager.resource-tracker.address</name>                <value>CentosOne:8031</value>        </property>        <property>                <name>yarn.resourcemanager.admin.address</name>                <value>CentosOne:8033</value>        </property>        <property>                <name>yarn.nodemanager.aux-services</name>                <value>mapreduce_shuffle</value>        </property>        <property>                <name>yarn.nodemanager.aux-services.mapreduce.shuffle.class</name>                <value>org.apache.hadoop.mapred.ShuffleHandler</value>        </property></configuration>

hadoop-env.sh添加如下内容

export JAVA_HOME=/data/install/jdk# ssh端口非默认22端口export HADOOP_SSH_OPTS="-p 22022"

yarn-env.sh添加如下内容

export JAVA_HOME=/data/install/jdk

启动命令

注意首次初始化启动命令和之后启动的命令是不同的,首次启动比较复杂,步骤不对的话就会报错,不过之后就好了

首次启动命令

1、首先启动各个节点的Zookeeper,在各个节点上执行以下命令:

bin/zkServer.sh start

2、在某一个namenode节点执行如下命令,创建命名空间

hdfs zkfc -formatZK

3、在每个journalnode节点用如下命令启动journalnode

/usr/local/hadoop/sbin/hadoop-daemon.sh start journalnode

4、在主namenode节点用格式化namenode和journalnode目录

hdfs namenode -format lwns

5、在主namenode节点启动namenode进程

/usr/local/hadoop/sbin/hadoop-daemon.sh start namenode

6、在备namenode节点执行第一行命令,这个是把备namenode节点的目录格式化并把元数据从主namenode节点copy过来,并且这个命令不会把journalnode目录再格式化了!然后用第二个命令启动备namenode进程!

hdfs namenode -bootstrapStandby/usr/local/hadoop/sbin/hadoop-daemon.sh start namenode

7、在两个namenode节点都执行以下命令

/usr/local/hadoop/sbin/hadoop-daemon.sh start zkfc

8、在所有datanode节点都执行以下命令启动datanode

/usr/local/hadoop/sbin/hadoop-daemon.sh start datanode

日常启停命令

./start-all.sh./stop-all.sh

其实就是说,第一次启动比较复杂,最好按照这个次序来,然后以后启动,就可以随便在一个namenode上的/usr/local/hadoop/sbin/下执行上面的两个脚本即可。

测试验证

首先在浏览器分别打开两个节点的namenode状态,其中一个显示active,另一个显示standby




杀掉active主机的进程


再查看原来standby主机的状态



2017-05-28:为了测试这样升级后,是否还能执行mapreduce的功能。所以执行一下hadoop2.8自带的wordcount例子验证

创建input目录

hadoop fs -mkdir /hadoop/input1
使用hadoop的根目录下自带的LICENSE.txt文件测试

hadoop fs -put /usr/local/hadoop/LICENSE.txt /hadoop/input1

使用wordcount测试类进行处理测试

cd /usr/local/hadoop/share/hadoop/mapreduce/ls  --查看hadoop-mapreduce-examples-2.8.0.jarhadoop jar hadoop-mapreduce-examples-2.8.0.jar wordcount /hadoop/input /hadoop/output

稍后会在/hadoop/output路径下看到结果

hadoop fs -ls /hadoop/output


说明得到了执行结果,也说明HA的配置没问题。验证完毕


2017-05-31补充:

在当前这个配置及安装的软件环境下, 正常启动后,各主机的进程应该是这样的(各主机用途见文章开头)

192.168.122.11执行
/usr/local/hadoop/sbin/start-all.sh
执行后的再执行jps时,应该是在active的NameNode上看到六个进程
1780 NameNode
1988 JournalNode
1590 QuorumPeerMain
2230 ResourceManager
2545 Jps
2138 DFSZKFailoverController


standby的NameNode上看到5个进程,比上面少了一个ResourceManager
另外三个DataNode上面,除了有一个作为JournalNode存在,会多一个JournalNode进程之外
都是只有4个进程
1625 NodeManager
1564 DataNode
1800 Jps
1482 QuorumPeerMain

但是之前发现我的standby的NameNode上没有DFZKFailoverController进程,

我以为需要在这个standby节点上做一次对zookeeper的格式化

后来我再次启动的时候,发现在standby上自动出现了。这是我没做格式化操作的情况下出现的

所以可能我之前的启动不完全或者有什么异常存在吧。


2017-06-02

部署zookeeper的服务器不需要与hadoop一一对应。只需要在core-site.xml和hdfs-site.xml这些配置文件中关联即可

在mapred-site.xml的最后,需要添加以下配置。作用见注释

<!-- 配置historyserver。目的是在页面上可以看任务执行的所有节点日志信息汇总  --><property><name>mapreduce.jobhistory.address</name><value>liweiCentosOne:10020</value></property><!-- 指定historyserver在web端访问地址,默认端口19888 --><property><name>mapreduce.jobhistory.webapp.address</name><value>liweiCentosOne:19888</value></property><!-- 指定historyserver收集各节点日志后存放的数据路径 --><property><name>mapreduce.jobhistory.intermediate-done-dir</name><value>/usr/local/hadoop/tmp/mr-his</value></property><!-- 指定historyserver处理完毕各节点日志后存放的数据路径 --><property><name>mapreduce.jobhistory.done-dir</name><value>mkdir /usr/local/hadoop/tmp/mr-done</value></property>

在yarn-site.xml最后加上如下内容,作用见注释

<!-- 启动historyserver收集各节点日志功能这样才能在web端的访问地址上统一查看日志  --><property><name>yarn.log-aggregation-enable</name><value>true</value></property>



2017-06-06:

如果需要重新格式化zk和NameNode,那么JournalNode相应的东西一定要清除

这是因为:

1:这里面保存了原本该存储于NameNode的tmp目录下的VERSION文件夹及其内容

2:原本NameNode在非HA的情况下,本该保存在/usr/local/hadoop/tmp下面的东西,现在都由这个JournalNode来统一管理了。



2017-06-07:

昨天我因为处理hbase的异常,而重新格式化了hadoop和zookeeper之后,今天再执行/usr/local/hadoop/sbin/start-all.sh

发现CentosZero和CentosOne上都没有DFSZKFailoverController进程

然后从网页访问了一下这两台服务器,发现状态都是standby。是否我昨天格式化的时候哪儿弄错了,让它们变成了需要手动切换状态的样子了呢?

有人说需要重新格式化zookeeper。我尝试下看看



参考文章

1:zookeeper及NN的HA的实现原理及分析

原创粉丝点击