Hadoop的HA机制(Zookeeper集群+Hadoop集群)配置记录

博主:hadoop_version=2.4.1
java_version=1.7
zooKeeper_version=3.4.5
Linux =CentOs 6.5
1.首先说明HA是什么?
HA意为High Available。高可用性集群,是保证业务连续性的有效解决方式,一般有两个或两个以上的节点。且分为活动节点及备用节点。通常把正在执行业务的称为活动节点,而作为活动节点的一个备份的则称为备用节点。当活动节点出现故障,导致正在执行的业务(任务)不能正常执行时。备用节点此时就会侦測到,并马上接续活动节点来执行业务。从而实现业务的不中断或短暂中断。


2.HA机制的前世今生
2.1 Hadoop_1.X集群的NameNode
Namenode 管理者文件系统的Namespace。它维护着文件系统树(filesystem tree)以及文件树中全部的文件和文件夹的元数据(metadata)。管理这些信息的文件有两个,各自是Namespace 镜像文件(Namespace image)和操作日志文件(edit log),这些信息被Cache在RAM中。当然,这两个文件也会被持久化存储在本地硬盘。

Namenode记录着每一个文件里各个块所在的数据节点的位置信息,可是他并不持久化存储这些信息,由于这些信息会在系统启动时从数据节点重建。


在hadoop1时代。仅仅有一个NameNode。假设该NameNode数据丢失或者不能工作。那么整个集群就不能恢复了。这是hadoop1中的单点问题,也是hadoop1不可靠的表现。例如以下图所看到的。便是hadoop1.0的架构图;
这里写图片描写叙述
2.2 Hadoop_2.x集群的NameNode
为了解决hadoop1中的单点问题,在hadoop2中新的NameNode不再是仅仅有一个,能够有多个(眼下仅仅支持2个(2.4.1版本号))。每一个都有同样的职能。

一个是active状态的,一个是standby状态的。当集群执行时,仅仅有active状态的NameNode是正常工作的。standby状态的NameNode是处于待命状态的,时刻同步active状态NameNode的数据。一旦active状态的NameNode不能工作,通过手工或者自己主动切换,standby状态的NameNode就能够转变为active状态的,就能够继续工作了。这就是高可靠。
2.3 JournalNode实现NameNode(Active和Standby)数据的共享
当有两个NameNode,一个standby一个active,当active有数据变动时,standby也应该及时更新,这样才干够做到高可靠!否则,信息不一致还怎么叫高可靠呢?
这里写图片描写叙述
两个NameNode为了数据同步,会通过一组称作JournalNodes(JNs)的独立进程进行相互通信。当active状态的NameNode的命名空间有不论什么改动时,会告知大部分的JournalNodes进程。

standby状态的NameNode有能力读取JNs中的变更信息。而且一直监控edit log的变化。把变化应用于自己的命名空间。standby能够确保在集群出错时,命名空间状态已经全然同步了
2.4 NameNode之间的故障切换
active的NameNode出现了故障,比如挂机了。是谁去切换standby的NameNode变为active状态呢?这时。就须要引入ZooKeeper。

首先HDFS集群中的两个NameNode都在ZooKeeper中注冊,当active状态的NameNode出故障时,ZooKeeper能检測到这样的情况。它就会自己主动把standby状态的NameNode切换为active状态


3.Zookeeper集群+Hadoop集群
3.1 前期准备參见:http://blog.csdn.net/dingchenxixi/article/details/50775650 中 1-2节,Linux的安装以及网络配置
3.2 集群规划

主机名 IP 安装软件 执行的进程
had01 192.168.0.141 jdk,hadoop NameNode,DFSZKFailoverController(zkfc)
had02 192.168.0.142 jdk,hadoop NameNode,DFSZKFailoverController(zkfc)
had03 192.168.0.143 jdk,hadoop ResourceManager
had04 192.168.0.144 jdk,hadoop ResourceManager
had05 192.168.0.145 jdk,hadoop,zookeeper DataNode,NodeManager、JournalNode、QuorumPeerMain
had06 192.168.0.146 jdk、hadoop、zookeeper DataNode、NodeManager、JournalNode、QuorumPeerMain
had07 192.168.0.147 jdk、hadoop、zookeeper DataNode、NodeManager、JournalNode、QuorumPeerMain

3.3 安装配置zooKeeper集群(在had05上)
3.3.1 解压zookeeper的jar

tar -zxvf zookeeper-3.4.5.tar.gz -C ~/app

安装在用户主文件夹下的app文件夹内
3.3.2 改动配置

cd /weekend/zookeeper-3.4.5/conf/
cp zoo_sample.cfg zoo.cfg 
vim zoo.cfg
改动:dataDir=/home/hadoop/app/zookeeper-3.4.5/tmp
在最后加入:
server.1=had05:2888:3888
server.2=had06:2888:3888
server.3=had07:2888:3888
保存退出
然后创建一个tmp文件夹
mkdir /home/hadoop/app/zookeeper-3.4.5/tmp
再创建一个空文件
touch /home/hadoop/app/zookeeper-3.4.5/tmp/myid
最后向该文件写入ID
echo 1 > /home/hadoop/app/zookeeper-3.4.5/tmp/myid

server.x意义:
这里写图片描写叙述
zooKeeper工作原理:http://www.cnblogs.com/kunpengit/p/4045334.html
zoo.cfg配置文件:
这里写图片描写叙述
3.3.3 将配置好的zookeeper复制到其他节点
首先分别在had06、had07用户文件夹下创建一个app文件夹:mkdir app

scp -r app/zookeeper-3.4.5/ had06:app/
scp -r app/zookeeper-3.4.5/ had07:app/      
注意:改动had06、had07相应app/zookeeper-3.4.5/tmp/myid内容
had06:echo 2 > app/zookeeper-3.4.5/tmp/myid
had07:echo 3 > app/zookeeper-3.4.5/tmp/myid

4.安装配置hadoop集群
4.1 解压

tar -zxvf hadoop-2.4.1.tar.gz -C ~/app

4.2 配置HDFS

#将hadoop加入到环境变量中
vi /etc/profile
export JAVA_HOME=/home/hadoop/app/jdk1.7.0_79
export HADOOP_HOME=/home/hadoop/hadoop-2.4.1
export PATH=$PATH:$JAVA_HOME/bin:$HADOOP_HOME/bin

进入hadoop的配置文件夹

cd /home/hadoop/app/hadoop-2.4.1/etc/hadoop

4.2.1 改动hadoop-env.sh

export JAVA_HOME=/home/hadoop/app/jdk1.7.0_79

这里写图片描写叙述
4.2.2 改动core-site.xml

<configuration>
<!-- 指定hdfs的nameservice为ns1 -->
<property>
    <name>fs.defaultFS</name>
    <value>hdfs://ns1</value>
</property>
<!-- 指定hadoop暂时文件夹 -->
<property>  
    <name>hadoop.tmp.dir</name>
    <value>/home/hadoop/app/hadoop-2.4.1/tmp</value>
</property>             
<!-- 指定zookeeper地址 -->
<property>
    <name>ha.zookeeper.quorum</name>
    <value>had05:2181,had06:2181,had07:2181</value>
</property>
</configuration>

4.2.3 改动hdfs-site.xml

<configuration>
<!--指定hdfs的nameservice为ns1。须要和core-site.xml中的保持一致 -->
<property>
    <name>dfs.nameservices</name>
    <value>ns1</value>
</property>
<!-- ns1以下有两个NameNode,各自是nn1。nn2 -->
<property>
    <name>dfs.ha.namenodes.ns1</name>
    <value>nn1,nn2</value>
</property>
<!-- nn1的RPC通信地址 -->
<property>
    <name>dfs.namenode.rpc-address.ns1.nn1</name>
    <value>had01:9000</value>
</property>
<!-- nn1的http通信地址 -->
<property>
    <name>dfs.namenode.http-address.ns1.nn1</name>
    <value>had01:50070</value>
</property>
<!-- nn2的RPC通信地址 -->
<property>
    <name>dfs.namenode.rpc-address.ns1.nn2</name>
    <value>had02:9000</value>
</property>
<!-- nn2的http通信地址 -->
<property>
    <name>dfs.namenode.http-address.ns1.nn2</name>
    <value>had02:50070</value>
</property>
<!-- 指定NameNode的元数据在JournalNode上的存放位置 -->
<property>
    <name>dfs.namenode.shared.edits.dir</name>
    <value>qjournal://had05:8485;had06:8485;had07:8485/ns1</value>
</property>
<!-- 指定JournalNode在本地磁盘存放数据的位置 -->
<property>
    <name>dfs.journalnode.edits.dir</name>
    <value>/home/hadoop/app/hadoop-2.4.1/journaldata</value>
</property>
<!-- 开启NameNode失败自己主动切换 -->
<property>
    <name>dfs.ha.automatic-failover.enabled</name>
    <value>true</value>
</property>
<!-- 配置失败自己主动切换实现方式 -->
<property>
    <name>dfs.client.failover.proxy.provider.ns1</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>
<!-- 使用sshfence隔离机制时须要ssh免登陆 -->
<property>
    <name>dfs.ha.fencing.ssh.private-key-files</name>
    <value>/home/hadoop/.ssh/id_rsa</value>
</property>
<!-- 配置sshfence隔离机制超时时间 -->
<property>
    <name>dfs.ha.fencing.ssh.connect-timeout</name>
    <value>30000</value>
</property>
</configuration>

4.2.4 改动mapred-site.xml

<configuration>
<!-- 指定mr框架为yarn方式 -->
<property>
    <name>mapreduce.framework.name</name>
    <value>yarn</value>
    </property>
</configuration>

4.2.5 改动yarn-site.xml

<configuration>
<!-- 开启RM高可用 -->
<property>
    <name>yarn.resourcemanager.ha.enabled</name>
    <value>true</value>
</property>
<!-- 指定RM的cluster id -->
<property>
    <name>yarn.resourcemanager.cluster-id</name>
    <value>yrc</value>
</property>
<!-- 指定RM的名字 -->
<property>
    <name>yarn.resourcemanager.ha.rm-ids</name>
    <value>rm1,rm2</value>
</property>
<!-- 分别指定RM的地址 -->
<property>
    <name>yarn.resourcemanager.hostname.rm1</name>
    <value>had03</value>
</property>
<property>
    <name>yarn.resourcemanager.hostname.rm2</name>
    <value>had04</value>
</property>
<!-- 指定zk集群地址 -->
<property>
    <name>yarn.resourcemanager.zk-address</name>
    <value>had05:2181,had06:2181,had07:2181</value>
</property>
<property>
    <name>yarn.nodemanager.aux-services</name>
    <value>mapreduce_shuffle</value>
</property>
</configuration>

4.2.6 改动slaves文件
slaves是指定子节点的位置。由于要在had01上启动HDFS、在had03启动yarn,所以had01上的slaves文件指定的是datanode的位置。had03上的slaves文件指定的是nodemanager的位置
这里写图片描写叙述

这里写图片描写叙述
4.2.7 配置SSH无密登录
首先要配置had01到had02、had03、had04、had05、had06、had07的免password登陆,在had01上生产一对钥匙

ssh-keygen -t rsa

将公钥复制到其他节点,包含自己

ssh-coyp-id had01
ssh-coyp-id had02
ssh-coyp-id had03
ssh-coyp-id had04
ssh-coyp-id had05
ssh-coyp-id had06
ssh-coyp-id had07

配置had03到had04、had05、had06、had07的免password登陆
在had03上生产一对钥匙

ssh-keygen -t rsa

将公钥复制到其他节点

ssh-coyp-id had04
ssh-coyp-id had05
ssh-coyp-id had06
ssh-coyp-id had07

注意:两个namenode之间要配置ssh免password登陆。别忘了配置had02到had01的免登陆
在had02上生产一对钥匙

ssh-keygen -t rsa
ssh-coyp-id -i had01

4.3 将配置好的hadoop复制到其他节点

scp -r ~/app/hadoop-2.4.1 had0x:/home/hadoop/app

x代表主机名称[2,7]
4.4 启动zookeeper集群
分别在had05、had06、had07上启动zk

cd /home/hadoop/app/zookeeper-3.4.5/bin/
./zkServer.sh start
#查看状态:一个leader。两个follower
./zkServer.sh status

4.5启动journalnode
分别在had05、had06、had07上启动

cd /home/hadoop/app/hadoop-2.4.1/sbin/
hadoop-daemon.sh start journalnode

执行jps命令检验。had05、had06、had07上多了JournalNode进程
这里写图片描写叙述

4.6 格式化HDFS
在had01上执行命令:

hdfs namenode -format

格式化后会在依据core-site.xml中的hadoop.tmp.dir配置生成个文件,这里我配置的是/home/hadoop/app/hadoop-2.4.1/tmp。然后将/home/hadoop/app/hadoop-2.4.1/tmp复制到had02的/home/hadoop/app/hadoop-2.4.1
scp -r tmp/ had02:/home/hadoop/app/hadoop-2.4.1/
也能够这样。建议

hdfs namenode -bootstrapStandby

4.7 格式化ZKFC
在had01上执行

hdfs zkfc -formatZK

4.8 启动HDFS
在had01上执行

start-dfs.sh

4.9 启动YARN
是在had03上执行start-yarn.sh,把namenode和resourcemanager分开是由于性能问题。由于他们都要占用大量资源,所以把他们分开了,他们分开了就要分别在不同的机器上启动

start-yarn.sh

4.10 查看
http://192.168.0.141:50070
NameNode ‘had01:9000’ (active)
这里写图片描写叙述
http://192.168.0.142:50070
NameNode ‘had02:9000’ (standby)
这里写图片描写叙述


5.验证
5.1验证HDFS HA
首先向hdfs上传一个文件

hadoop fs -put test1.txt test2.txt /input
hadoop fs -ls /input

这里写图片描写叙述
然后再kill掉active的NameNode

kill -9 <pid of NN>

这里写图片描写叙述
通过浏览器訪问:http://192.168.0.142:50070
NameNode ‘had02:9000’ (active)
这个时候had02上的NameNode变成了active
这里写图片描写叙述
在执行命令:

hadoop fs -ls /input

这里写图片描写叙述
刚才上传的文件依旧存在!!


手动启动那个挂掉的NameNode

hadoop-daemon.sh start namenode

通过浏览器訪问:http://192.168.0.141:50070
NameNode ‘had01:9000’ (standby)
这里写图片描写叙述
5.2 验证YARN
执行一下hadoop提供的demo中的WordCount程序:

hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-2.4.1.jar wordcount /input /out

这里写图片描写叙述
结果:
这里写图片描写叙述


PS:

假设仅仅有3台主机,则能够依照以下规划部署

主机名 安装软件 执行的进程
had01 jdk,hadoop,zookeeper journalnode namenode zkfc resourcemanager datanode
had02 jdk,hadoop,zookeeper journalnode namenode zkfc resourcemanager datanode
had03 jdk,hadoop,zookeeper journalnode datanode

在集群搭建过程中出现的BUG集合

1.

ssh-copy-id :command not found

由于安装的是mini版,所以出现这样的问题。

解决方式:

yum -y install openssh-clients

2.
这里写图片描写叙述
查询一下zookeeper集群是否已经启动成功。
在zookeeper文件夹bin下

./zkServer.sh status

若是没有启动,则手动启动它,

./zkServer.sh start

3.另一个问题须要注意的是,主机名不要带下划线 “_”

部分内容摘自:http://www.open-open.com/lib/view/open1436855630959.html

原文地址:https://www.cnblogs.com/wgwyanfs/p/7345255.html