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

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的架构图;
Hadoop的HA机制(Zookeeper集群+Hadoop集群)配置记要
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也应该及时更新,这样才可以做到高可靠!否则,信息不一致还怎么叫高可靠呢?
Hadoop的HA机制(Zookeeper集群+Hadoop集群)配置记要
两个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.****.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意义:
Hadoop的HA机制(Zookeeper集群+Hadoop集群)配置记要
zooKeeper工作原理:http://www.cnblogs.com/kunpengit/p/4045334.html
zoo.cfg配置文件:
Hadoop的HA机制(Zookeeper集群+Hadoop集群)配置记要
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

Hadoop的HA机制(Zookeeper集群+Hadoop集群)配置记要
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的位置
Hadoop的HA机制(Zookeeper集群+Hadoop集群)配置记要

Hadoop的HA机制(Zookeeper集群+Hadoop集群)配置记要
4.2.7 配置SSH无密登录
首先要配置had01到had02、had03、had04、had05、had06、had07的免密码登陆,在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的免密码登陆
在had03上生产一对钥匙

ssh-keygen -t rsa

将公钥拷贝到其他节点

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

注意:两个namenode之间要配置ssh免密码登陆,别忘了配置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进程
Hadoop的HA机制(Zookeeper集群+Hadoop集群)配置记要

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)
Hadoop的HA机制(Zookeeper集群+Hadoop集群)配置记要
http://192.168.0.142:50070
NameNode ‘had02:9000’ (standby)
Hadoop的HA机制(Zookeeper集群+Hadoop集群)配置记要


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

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

Hadoop的HA机制(Zookeeper集群+Hadoop集群)配置记要
然后再kill掉active的NameNode

kill -9 <pid of NN>

Hadoop的HA机制(Zookeeper集群+Hadoop集群)配置记要
通过浏览器访问:http://192.168.0.142:50070
NameNode ‘had02:9000’ (active)
这个时候had02上的NameNode变成了active
Hadoop的HA机制(Zookeeper集群+Hadoop集群)配置记要
在执行命令:

hadoop fs -ls /input

Hadoop的HA机制(Zookeeper集群+Hadoop集群)配置记要
刚才上传的文件依然存在!!!
手动启动那个挂掉的NameNode

hadoop-daemon.sh start namenode

通过浏览器访问:http://192.168.0.141:50070
NameNode ‘had01:9000’ (standby)
Hadoop的HA机制(Zookeeper集群+Hadoop集群)配置记要
5.2 验证YARN
运行一下hadoop提供的demo中的WordCount程序:

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

Hadoop的HA机制(Zookeeper集群+Hadoop集群)配置记要
结果:
Hadoop的HA机制(Zookeeper集群+Hadoop集群)配置记要


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.
Hadoop的HA机制(Zookeeper集群+Hadoop集群)配置记要
查询一下zookeeper集群是否已经启动成功。
在zookeeper目录bin下

./zkServer.sh status

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

./zkServer.sh start

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

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