**注意:本文步骤完全参考阳光奶爸的博文,有些部分根据我自己的理解进行了修改和补充。
http://blog.csdn.net/carl810224/article/details/52160418
自己搭建成功,记录下来作为作业笔记。
**
一.高可用集群规划
主机名 | IP地址 | 安装的软件 | JPS |
hadoop-master1 | 192.168.105.150 | Jdk/hadoop | Namenode/zkfc/resourcemanager/JobHistoryServer |
hadoop-master2 | 192.168.105.153 | Jdk/hadoop | Namenode/zkfc/resourcemanager/WebProxyServer |
hadoop-slave1 | 192.168.105.154 | Jkd/hadoop/zookeeper | Datanode/journalnode/nodemanager/quorumPeerMain |
hadoop-slave2 | 192.168.105.155 | Jkd/hadoop/zookeeper | Datanode/journalnode/nodemanager/quorumPeerMain |
hadoop-slave3 | 192.168.105.157 | Jkd/hadoop/zookeeper | Datanode/journalnode/nodemanager/quorumPeerMain |
二.软件环境
Mac ox系统
虚拟机VmwareFusion上安装cent OS操作系统 :
http://jingyan.baidu.com/article/eae0782787b4c01fec548535.html
三.搭建步骤
1.准备工作:
1.1我们需要五个centOS虚拟机,但并不需要安装五次,只需要在完成一些同样的配置步骤后,直接克隆,然后修改虚拟机的名称就可得到所需要的虚拟机。
1.2下载所需要的软件包
jdk-7u79-linux-x64.tar.gz
http://download.csdn.net/download/love254443233/9179483
Hadoop 2.6.0-cdh5.7.1和zookeeper-3.4.5-cdh5.7.1
http://archive.cloudera.com/cdh5/cdh/5/
2.Linux环境准备
只需要在第一个安装的cent OS即hadoop-master1上完成2.1的配置,然后进行克隆,克隆出来的虚拟机已经完成了同样的配置。
2.1创建用户并添加权限
// 切换root用户
su root
// 创建hadoop用户组
groupadd hadoop
// 在hadoop用户组中创建hadoop用户
useradd -g hadoop hadoop
// 修改用户hadoop密码
passwd hadoop
// 修改sudoers配置文件给hadoop用户添加sudo权限
vim /etc/sudoers
hadoop ALL=(ALL) ALL
// 测试是否添加权限成功
exit
sudo ls /root
2.2修改五个节点的主机名
// 修改主机名
hostnamectl set-hostname 主机名
主机名分别是:hadoop-master1、hadoop-master2、 hadoop-slave1、hadoop-slave2、hadoop-slave3
// 查看主机名
hostnamectl status
2.3设置IP地址与主机名映射
// 切换root用户
su root
// 编辑hosts文件
vim /etc/hosts
192.168.105.150 hadoop-master1
192.168.105.153 hadoop-master2
192.168.105.154 hadoop-slave1
192.168.105.155 hadoop-slave2
192.168.105.157 hadoop-slave3
2.4配置SSH免密码登录
// 在hadoop-master1节点生成SSH密钥对
ssh-keygen -t rsa
注意:这里只要一直按回车即可!
// 将公钥复制到集群所有节点机器上(在master1上执行以下所有语句,而不是一条,并且注意所有节点的/etc/hosts文件要有所有节点的IP地址和主机名)
ssh-copy-id hadoop-master1
ssh-copy-id hadoop-master2
ssh-copy-id hadoop-slave1
ssh-copy-id hadoop-slave2
ssh-copy-id hadoop-slave3
//退出 ssh登录:
exit
// 通过ssh登录各节点测试是否免密码登录成功
ssh hadoop-master1
注意:在不同节点上输入同一条指令,均能登录。也可以是登录hadoop-master2,hadoop-slave1等所有节点。即每个节点都要做上面的测试操作。
2.5安装JDK
// 卸载系统自带的openjdk
rpm -qa | grep java
rpm -e –nodeps java-1.7.0-openjdk-1.7.0.91-2.6.2.3.el7.x86_64
rpm -e –nodeps java-1.7.0-openjdk-headless-1.7.0.91-2.6.2.3.el7.x86_64
rpm -e –nodeps tzdata-java-2015g-1.el7.noarch
rpm -e –nodeps java-1.8.0-openjdk-1.8.0.65-3.b17.el7.x86_64
rpm -e –nodeps java-1.8.0-openjdk-headless-1.8.0.65-3.b17.el7.x86_64
// 修改用户环境变量
cd ~
gedit ~/.bashrc
export JAVA_HOME=/home/qichenglin/hadoop/app/jdk1.7.0_79
export PATH=$PATH:$JAVA_HOME/bin
// 使修改的环境变量生效
source ~/.bashrc
// 测试jdk是否安装成功
java-version
3.集群时间同步
如果集群节点时间不同步,可能会出现节点宕机或引发其它异常问题,所以在生产环境中一般通过配置NTP服务器实现集群时间同步。只要在hadoop-master1节点设置ntp服务器。
// 切换root用户
su root
// 查看是否安装ntp
rpm -qa | grep ntp
// 安装ntp
yum install -y ntp
// 配置时间服务器
gedit /etc/ntp.conf
//禁止所有机器连接ntp服务器
restrict default ignore
//允许局域网内的所有机器连接ntp服务器
restrict 192.168.105.0 mask 255.255.255.0 nomodify notrap
// 使用本机作为时间服务器
server 192.168.105.2
// 启动ntp服务器
service ntpd start
// 设置ntp服务器开机自动启动
chkconfig ntpd on
集群其它节点通过执行crontab定时任务,每天在指定时间向ntp服务器进行时间同步,方法如下:
// 执行定时任务,每天00:00向服务器同步时间,并写入日志
crontab -e
0 0 * * * /usr/sbin/ntpdate hadoop-master1>>/home/hadoop/ntpd.log
// 查看任务
crontab -l
4.Zookeeper集群安装
首先在hadoop-slave1节点安装Zookeeper,将hadoop-slave1节点上的Zookeeper目录同步到hadoop-slave2和hadoop-slave3节点,并修改Zookeeper的数据文件。此外,不要忘记设置用户环境变量。
// 新建目录
cd /home/qichenglin/hadoop/app/
mkdir ./cdh
// 配置用户环境变量
su root
gedit ~/.bashrc
export ZOOKEEPER_HOME=/home/qichenglin/hadoop/app/cdh/zookeeper-3.4.5-cdh5.7.1
export PATH=$PATH:$ZOOKEEPER_HOME/bin
// 使修改的环境变量生效
source ~/.bashrc
修改zookeeper的配置文件
cd /home/qichenglin/hadoop/app/cdh/zookeeper-3.4.5-cdh5.7.1/conf/
cp zoo_sample.cfg zoo.cfg
gedit zoo.cfg
# 客户端心跳时间(毫秒)
tickTime=2000
# 允许心跳间隔的最大时间
initLimit=10
# 同步时限
syncLimit=5
# 数据存储目录
dataDir=/home/qichenglin/hadoop/app/cdh/zookeeper-3.4.5-cdh5.7.1/data
# 数据日志存储目录
dataLogDir=/home/qichenglin/hadoop/app/cdh/zookeeper-3.4.5-cdh5.7.1/data/log
# 端口号
clientPort=2181
# 集群节点和服务端口配置
server.1=hadoop-slave1:2888:3888
server.2=hadoop-slave2:2888:3888
server.3=hadoop-slave3:2888:3888
# 以下为优化配置
# 服务器最大连接数,默认为10,改为0表示无限制
maxClientCnxns=0
# 快照数
autopurge.snapRetainCount=3
# 快照清理时间,默认为0
autopurge.purgeInterval=1
// 创建zookeeper的数据存储目录和日志存储目录
cd ..
mkdir -p data/log
// 在data目录中创建一个文件myid,输入内容为1
echo “1” >> data/myid
gedit libexec/zkEnv.sh
if [ "x${ZOO_LOG_DIR}" = "x" ]
then
ZOO_LOG_DIR="$ZOOKEEPER_HOME/logs"
fi
if [ "x${ZOO_LOG4J_PROP}" = "x" ]
then
ZOO_LOG4J_PROP="INFO,ROLLINGFILE"
Fi
// 修改zookeeper的日志配置文件
gedit conf/log4j.properties
zookeeper.root.logger=INFO,ROLLINGFILE
// 创建日志目录
mkdir logs
将hadoop-slave1节点上的Zookeeper目录同步到hadoop-slave2和hadoop-slave3节点,并修改Zookeeper的数据文件。此外,不要忘记设置用户环境变量。
//先在另外两个虚拟机上建立路径,不要在root权限下。
cd /home/qichenglin/hadoop/app/
mkdir ./cdh
// 在hadoop-slave1中将zookeeper目录复制到其它节点,又回到hadoop-slave1上
scp -r /home/qichenglin/hadoop/app/cdh/zookeeper-3.4.5-cdh5.7.1 hadoop-slave2:/home/qichenglin/hadoop/app/cdh
scp -r /home/qichenglin/hadoop/app/cdh/zookeeper-3.4.5-cdh5.7.1 hadoop-slave3:/home/qichenglin/hadoop/app/cdh
//在hadoop-slave2中修改data目录中的myid文件
echo “2” >/home/qichenglin/hadoop/app/cdh/zookeeper-3.4.5-cdh5.7.1/data/myid
//在hadoop-slave3中修改data目录中的myid文件
echo “3” >/home/qichenglin/hadoop/app/cdh/zookeeper-3.4.5-cdh5.7.1/data/myid
最后,在安装了Zookeeper的各节点上启动Zookeeper,并查看节点状态,方法如下:
cd /home/qichenglin/hadoop/app/cdh/zookeeper-3.4.5-cdh5.7.1/bin/
./zkServer.sh start
图只截了hadoop-slave3的:
// 查看状态
zkServer.sh status
hadoop-slave1:
hadoop-slave2:
hadoop-slave3:
// 关闭
$ zkServer.sh stop
5.Hadoop HA配置
在hadoop-master1节点安装Hadoop并配置
// 修改hadoop-env.sh文件
cd /home/qichenglin/hadoop/app/cdh/hadoop-2.6.0-cdh5.7.1/etc/hadoop
gedit hadoop-env.sh
export JAVA_HOME=/home/qichenglin/hadoop/app/jdk1.7.0_79
// 配置core-site.xml文件
gedit core-site.xml
<configuration>
<!-- 指定hdfs的nameservices名称为mycluster,与hdfs-site.xml的HA配置相同 -->
<property>
<name>fs.defaultFS</name>
<value>hdfs://mycluster</value>
</property>
<!-- 指定缓存文件存储的路径 -->
<property>
<name>hadoop.tmp.dir</name>
<value>/home/qichenglin/hadoop/app/cdh/hadoop-2.6.0-cdh5.7.1/data/tmp</value>
</property>
<!-- 配置hdfs文件被永久删除前保留的时间(单位:分钟),默认值为0表明垃圾回收站功能关闭 -->
<property>
<name>fs.trash.interval</name>
<value>1440</value>
</property>
<!-- 指定zookeeper地址,配置HA时需要 -->
<property>
<name>ha.zookeeper.quorum</name>
<value>hadoop-slave1:2181,hadoop-slave2:2181,hadoop-slave3:2181</value>
</property>
</configuration>
// 配置hdfs-site.xml文件
gedit hdfs-site.xml
<configuration>
<!-- 指定hdfs元数据存储的路径 -->
<property>
<name>dfs.namenode.name.dir</name>
<value>/home/qichenglin/hadoop/app/cdh/hadoop-2.6.0-cdh5.7.1/data/namenode</value>
</property>
<!-- 指定hdfs数据存储的路径 -->
<property>
<name>dfs.datanode.data.dir</name>
<value>/home/qichenglin/hadoop/app/cdh/hadoop-2.6.0-cdh5.7.1/data/datanode</value>
</property>
<!-- 数据备份的个数 -->
<property>
<name>dfs.replication</name>
<value>3</value>
</property>
<!-- 关闭权限验证 -->
<property>
<name>dfs.permissions.enabled</name>
<value>false</value>
</property>
<!-- 开启WebHDFS功能(基于REST的接口服务) -->
<property>
<name>dfs.webhdfs.enabled</name>
<value>true</value>
</property>
<!-- //以下为HDFS HA的配置// -->
<!-- 指定hdfs的nameservices名称为mycluster -->
<property>
<name>dfs.nameservices</name>
<value>mycluster</value>
</property>
<!-- 指定mycluster的两个namenode的名称分别为nn1,nn2 -->
<property>
<name>dfs.ha.namenodes.mycluster</name>
<value>nn1,nn2</value>
</property>
<!-- 配置nn1,nn2的rpc通信端口 -->
<property>
<name>dfs.namenode.rpc-address.mycluster.nn1</name>
<value>hadoop-master1:8020</value>
</property>
<property>
<name>dfs.namenode.rpc-address.mycluster.nn2</name>
<value>hadoop-master2:8020</value>
</property>
<!-- 配置nn1,nn2的http通信端口 -->
<property>
<name>dfs.namenode.http-address.mycluster.nn1</name>
<value>hadoop-master1:50070</value>
</property>
<property>
<name>dfs.namenode.http-address.mycluster.nn2</name>
<value>hadoop-master2:50070</value>
</property>
<!-- 指定namenode元数据存储在journalnode中的路径 -->
<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://hadoop-slave1:8485;hadoop-slave2:8485;hadoop-slave3:8485/mycluster</value>
</property>
<!-- 指定journalnode日志文件存储的路径 -->
<property>
<name>dfs.journalnode.edits.dir</name>
<value>/home/qichenglin/hadoop/app/cdh/hadoop-2.6.0-cdh5.7.1/data/journal</value>
</property>
<!-- 指定HDFS客户端连接active namenode的java类 -->
<property>
<name>dfs.client.failover.proxy.provider.mycluster</name>
<value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
</property>
<!-- 配置隔离机制为ssh -->
<property>
<name>dfs.ha.fencing.methods</name>
<value>sshfence</value>
</property>
<!-- 指定秘钥的位置 -->
<property>
<name>dfs.ha.fencing.ssh.private-key-files</name>
<value>/home/qichenglin/hadoop/.ssh/id_rsa</value>
</property>
<!-- 开启自动故障转移 -->
<property>
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value>
</property>
</configuration>
// 配置mapred-site.xml文件
cp mapred-site.xml.template mapred-site.xml
gedit mapred-site.xml
<configuration>
<!-- 指定MapReduce计算框架使用YARN -->
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
<!-- 指定jobhistory server的rpc地址 -->
<property>
<name>mapreduce.jobhistory.address</name>
<value>hadoop-master1:10020</value>
</property>
<!-- 指定jobhistory server的http地址 -->
<property>
<name>mapreduce.jobhistory.webapp.address</name>
<value>hadoop-master1:19888</value>
</property>
<!-- 开启uber模式(针对小作业的优化) -->
<property>
<name>mapreduce.job.ubertask.enable</name>
<value>true</value>
</property>
<!-- 配置启动uber模式的最大map数 -->
<property>
<name>mapreduce.job.ubertask.maxmaps</name>
<value>9</value>
</property>
<!-- 配置启动uber模式的最大reduce数 -->
<property>
<name>mapreduce.job.ubertask.maxreduces</name>
<value>1</value>
</property>
</configuration>
// 配置yarn-site.xml文件
gedit yarn-site.xml
<configuration>
<!-- Site specific YARN configuration properties -->
<!-- NodeManager上运行的附属服务,需配置成mapreduce_shuffle才可运行MapReduce程序 -->
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<!-- 配置Web Application Proxy安全代理(防止yarn被攻击) -->
<property>
<name>yarn.web-proxy.address</name>
<value>hadoop-master2:8888</value>
</property>
<!-- 开启日志 -->
<property>
<name>yarn.log-aggregation-enable</name>
<value>true</value>
</property>
<!-- 配置日志删除时间为7天,-1为禁用,单位为秒 -->
<property>
<name>yarn.log-aggregation.retain-seconds</name>
<value>604800</value>
</property>
<!-- 修改日志目录 -->
<property>
<name>yarn.nodemanager.remote-app-log-dir</name>
<value>/logs</value>
</property>
<!-- 配置nodemanager可用的资源内存 -->
<property>
<name>yarn.nodemanager.resource.memory-mb</name>
<value>2048</value>
</property>
<!-- 配置nodemanager可用的资源CPU -->
<property>
<name>yarn.nodemanager.resource.cpu-vcores</name>
<value>2</value>
</property>
<!-- //以下为YARN HA的配置// -->
<!-- 开启YARN HA -->
<property>
<name>yarn.resourcemanager.ha.enabled</name>
<value>true</value>
</property>
<!-- 启用自动故障转移 -->
<property>
<name>yarn.resourcemanager.ha.automatic-failover.enabled</name>
<value>true</value>
</property>
<!-- 指定YARN HA的名称 -->
<property>
<name>yarn.resourcemanager.cluster-id</name>
<value>yarncluster</value>
</property>
<!-- 指定两个resourcemanager的名称 -->
<property>
<name>yarn.resourcemanager.ha.rm-ids</name>
<value>rm1,rm2</value>
</property>
<!-- 配置rm1,rm2的主机 -->
<property>
<name>yarn.resourcemanager.hostname.rm1</name>
<value>hadoop-master1</value>
</property>
<property>
<name>yarn.resourcemanager.hostname.rm2</name>
<value>hadoop-master2</value>
</property>
<!-- 配置YARN的http端口 -->
<property>
<name>yarn.resourcemanager.webapp.address.rm1</name>
<value>hadoop-master1:8088</value>
</property>
<property>
<name>yarn.resourcemanager.webapp.address.rm2</name>
<value>hadoop-master2:8088</value>
</property>
<!-- 配置zookeeper的地址 -->
<property>
<name>yarn.resourcemanager.zk-address</name>
<value>hadoop-slave1:2181,hadoop-slave2:2181,hadoop-slave3:2181</value>
</property>
<!-- 配置zookeeper的存储位置 -->
<property>
<name>yarn.resourcemanager.zk-state-store.parent-path</name>
<value>/rmstore</value>
</property>
<!-- 开启yarn resourcemanager restart -->
<property>
<name>yarn.resourcemanager.recovery.enabled</name>
<value>true</value>
</property>
<!-- 配置resourcemanager的状态存储到zookeeper中 -->
<property>
<name>yarn.resourcemanager.store.class</name>
<value>org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore</value>
</property>
<!-- 开启yarn nodemanager restart -->
<property>
<name>yarn.nodemanager.recovery.enabled</name>
<value>true</value>
</property>
<!-- 配置nodemanager IPC的通信端口 -->
<property>
<name>yarn.nodemanager.address</name>
<value>0.0.0.0:45454</value>
</property>
</configuration>
// 配置slaves文件
gedit slaves
hadoop-slave1
hadoop-slave2
hadoop-slave3
// 创建配置文件中涉及的目录
cd /home/qichenglin/hadoop/app/cdh/hadoop-2.6.0-cdh5.7.1/
mkdir -p data/tmp
mkdir -p data/journal
mkdir -p data/namenode
mkdir -p data/datanode
// 将hadoop工作目录同步到集群其它节点
scp -r /home/qichenglin/hadoop/app/cdh/hadoop-2.6.0-cdh5.7.1/ hadoop-master2:/home/qichenglin/hadoop/app/cdh/
scp -r /home/qichenglin/hadoop/app/cdh/hadoop-2.6.0-cdh5.7.1/ hadoop-slave1:/home/qichenglin/hadoop/app/cdh/
scp -r /home/qichenglin/hadoop/app/cdh/hadoop-2.6.0-cdh5.7.1/ hadoop-slave2:/home/qichenglin/hadoop/app/cdh/
scp -r /home/qichenglin/hadoop/app/cdh/hadoop-2.6.0-cdh5.7.1/ hadoop-slave3:/home/qichenglin/hadoop/app/cdh/
//在集群各节点上修改环境变量
gedit ~/.bashrc
export HADOOP_HOME=/home/qichenglin/hadoop/app/cdh/hadoop-2.6.0-cdh5.7.1
export LD_LIBRARY_PATH=$HADOOP_HOME/lib/native
export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin
// 使修改的环境变量生效
source ~/.bashrc
// 解决本地库文件不存在的问题
在apache官网下载hadoop-2.6.0.tar.gz,解压后将lib/native下所有文件复制到$HADOOP_HOME/lib/native中。
下载地址:
https://dist.apache.org/repos/dist/release/hadoop/common/hadoop-2.6.0/
chmod -R 777 /home/qichenglin/hadoop/app/cdh/hadoop-2.6.0-cdh5.7.1/
6.Hadoop集群的初始化
//启动zookeeper集群(在slave1-3上)
cd /home/qichenglin/hadoop/app/cdh/zookeeper-3.4.5-cdh5.7.1/bin/
./zkServer.sh start
// 格式化ZKFC(在master1上执行)
hdfs zkfc -formatZK
//启动journalnode(分别在slave1、slave2和slave3上执行)
hadoop-daemon.sh start journalnode
//格式化HDFS(在master1上执行)
hdfs namenode -format
// 将格式化后master1节点hadoop工作目录中的元数据目录复制到master2节点
scp -r /home/qichenglin/hadoop/app/cdh/hadoop-2.6.0-cdh5.7.1/data/namenode/* hadoop-master2:/home/qichenglin/hadoop/app/cdh/hadoop-2.6.0-cdh5.7.1/data/namenode/
初始化完毕后可关闭journalnode(分别在slave1、slave2和slave3上执行)
hadoop-daemon.sh stop journalnode
7.Hadoop集群的启动
7.1集群启动步骤
// 启动zookeeper集群(分别在slave1、slave2和slave3执行)
zkServer.sh start
// 启动HDFS(在master1执行)
start-dfs.sh
此命令分别在master1/master2节点启动了NameNode和ZKFC,分别在slave1/slave2/slave3节点启动了DataNode和JournalNode,如下图所示:
//启动YARN(在master2执行)
start-yarn.sh
备注:此命令在master2节点启动了ResourceManager,分别在slave1/slave2/slave3节点启动了NodeManager。
//启动YARN的另一个ResourceManager(在master1执行,用于容灾)
yarn-daemon.sh start resourcemanager
//启动YARN的安全代理(在master2执行)
yarn-daemon.sh start proxyserver
备注:proxyserver充当防火墙的角色,可以提高访问集群的安全性
//启动YARN的历史任务服务(在master1执行)
mr-jobhistory-daemon.sh start historyserver
备注:yarn-daemon.sh start historyserver已被弃用;CDH版本似乎有个问题,即mapred-site.xml配置的mapreduce.jobhistory.address和mapreduce.jobhistory.webapp.address参数似乎不起作用,实际对应的端口号是10200和8188,而且部需要配置就可以在任意节点上开启历史任务服务。
7.2集群启动截图
hadoop-master1开启了NameNode、ResourceManager、HistoryServer和ZKFC,如下图所示:
hadoop-master2开启了NameNode、ResourceManager、ProxyServer和ZKFC,如下图所示:
hadoop-slave1、hadoop-slave2和hadoop-slave3分别开启了DataNode、JournalNode、NodeManager和ZooKeeper,如下图所示:
7.3Web UI
下图为http://hadoop-master1:50070,可看到NameNode为active状态:
下图为http://hadoop-master2:50070,可看到NameNode为standby状态:
HDFS还有一个隐藏的UI页面http://hadoop-master1:50070/dfshealth.jsp比较好用:
下图为http://hadoop-master2:8088,可看到ResourceManager为active状态:
下图为http://hadoop-master1:8088,可看到ResourceManager为standby状态,它会自动跳转到http://hadoop-master2:8088:
下图为http://hadoop-master1:19888,可查看历史任务信息: