本文目的:搭建 HDFS 2.x 高可用的 分布式集群环境。
集群架构:
集群组成:
Namenode:2台
Datanode: 3台
Journalnode:3台
Zookeeper: 3台
ZKFC:2台
ResourceManager:2台
NodeManager:3台
具体安排:
本文中准备node~4 四台虚拟机:
node1: 192.168.152.101
node
2 : 192.168.152.102
node
3 : 192.168.152.103
node
4 : 192.168.152.104
用这四台虚拟机搭建起分布式环境,具体的分布如下:
Namenode | Datanode | Journalnode | Zookeeper | ZKFC | ResourceManager | NodeManager | |
node1 | 1 | 1 | 1 | 1 | |||
node2 | 1 | 1 | 1 | 1 | 1 | 1 | |
node3 | 1 | 1 | 1 | 1 | 1 | ||
node4 | 1 | 1 | 1 |
软件版本:
系统版本:
CentOS6.5
软件版本:
JDK: jdk-7u67-linux-x64
Hadoop: hadoop-2.5.1_x64
Zookeeper:zookeeper-3.4.6
具体步骤:
一、关闭防火墙、修改主机名称、配置hosts文件(node1~node4 都需要配置)
1、通过命令 service iptables status 查看防火墙是否开启,如开启, 使用命令 service iptables stop 予以关闭;
通过命令 chkconfig iptables off 禁止防火墙开机启动。
2、修改node1主机的/etc/sysconfig/network文件,将HOSTNAME分别修改为 node1。另外三台主机的HOSTNAME 分别修改为node2、node3、node4。
3、修改 /etc/hosts文件 ,添加如下配置:
192.168.152.101 node1
192.168.152.102 node2
192.168.152.103 node3
192.168.152.104 node4
4、删除持久化文件/etc/udev/rules.d/70-persistent-net.rules ,重启虚拟主机,使配置生效。
注:持久化文件,该文件记录的是当前主机的MAC地址与IP地址的映射关系。由于我们的4台主机是通过虚拟机克隆的方式得到的,所以4台主机的MAC地址是相同的,这在计算机通讯过程中是不允许的,所以要将持久化文件删除,以重新生成。重启虚拟机时,系统会重新生成4个互不冲突的MAC地址,并将MAC地址与本机当前IP的映射关系记录到持久化文件(重启时,系统检测不到该文件时,会重新生成)当中。
二、4台主机同步时间
1、yum install ntp
2、
ntpdate -c 时间服务器域名 或
ntpdate IP。自己百度一下,时间服务器的IP,此处我们采用上海交通大学网络中心的NTP服务器地址
ntpdate 202.120.2.101
三、免密钥设置
NN 与 DN之间需要做免密处理 两台NN之间也需要做免密处理
如果设置主机A到主机B的免密钥登录,可按如下方式进行:
在A主机执行
1、ssh-keygen -t rsa -P '' -f ~/.ssh/id_rsa -t密钥类型(rsa 或 dsa) -P 旧密码 ''代表为空 -f 密钥文件生成后,保存的位置
2、ssh-copy-id 192.168.0.102 IP是主机B的IP地址,将主机A生成的密钥,拷贝到远程主机对应的账户下
执行过程中,会提示让输入主机B的登录密码
四、安装JDK、hadoop和zookeeper,并配置环境变量
上传
jdk-7u67-linux-x64.rpm、
hadoop-2.5.1_x64.tar.gz、
zookeeper-3.4.6.tar.gz到/home/software目录下(路径随意)。
安装JDK : rpm -ivh
jdk-7u67-linux-x64.rpm
解压hadoop和zookeeper,将解压后的文件夹移动至/home目录下(注意,要将解压后的文件夹属主和属组都改成root)
配置环境变量 /etc/profile
export JAVA_HOME=/usr/java/jdk1.7.0_67
export PATH=$PATH:$JAVA_HOME/bin
export HADOOP_HOME=/home/hadoop-2.5.1
export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin
export ZOOKEEPER_HOME=/home/zookeeper-3.4.6 注意zookeeper只在node1 node2 node3上部署,node4不需配置这两行
export PATH=$PATH:$ZOOKEEPER_HOME/bin
配置完成后,使用命令source /etc/profile 将配置文件中的内容刷新进内存中。
可以使用命令 echo $PATH 检验环境变量是否配置成功。
JDK、hadoop四台主机都需要安装,zookeeper在前三台安装。
跨主机拷贝文件时可使用命令: scp
jdk-7u67-linux-x64.rpm node2:`pwd`(反引号)拷贝到node2主机的相同路径下。
五、搭建zookeeper集群(node1、node2、node3)
在上一步中,已经将zookeeper解压到指定目录/home下,并配置好了zookeeper的环境变量。
接下来,配置zookeeper的配置文件。进入目录/home/zookeeper-3.4.6/conf,在此目录下,会有一个配置模板zoo_sample.cfg,
我们使用该模板进行修改。
1、mv zoo_sample.cfg zoo.cfg
2、zookeeper的详细配置,可以参考zookeeper官网:
http://zookeeper.apache.org/doc/r3.4.6/zookeeperStarted.html
此处在zoo.cfg最后一行,添加如下配置:
dataDir=/opt/zookeeper ///模板中有此选项,此处将路径进行修改,此路径是zookeeper的快照存储路径,不要使用原有的/tmp下的路径(重启会丢失)
server.1=node1:2888:3888
server.2=node2:2888:3888
server.3=node3:2888:3888
配置文件修改完成后,进行同步,保证node1~3的zoo.cfg一致。
3、在上一步的配置文件中,配置了server.1 server.2 server.3,指定了三台server 1、2、3,但是哪个是1号server,哪个又是2号server,需要我们进行配置。在dataDir指定的路径(/opt/zookeeper)下,创建名为myid的文件,分别写入一个数字(node1主机的myid文件写1,node2主机的myid文件写入2,依次类推。。)
4、启动zookeeper集群。启动zookeeper集群时,要求同时启动,可以借助xshell撰写栏实现。
启动命令:zkServer.sh start
查看状态:zkServer.sh status
关闭命令:zkServer.sh stop
注意:启动时,各主机会相互通信,而zookeeper的进程正在启动过程中,有时会出现无法连接的情况。遇到这种情况,可以忽略,稍等片刻之后查看zookeeper的状态,能正常显示出 leader 或 follower ,就算启动成功(启动过程大概几秒钟时间)。如果一直启动失败,可以查看日志文件zookeeper.out,该日志文件的路径是 执行启动命令时所在的路径。
六、搭建Hadoop集群
hadoop集群的配置文件主要涉及到以下这几个:
hadoop-env.sh
core-site.xml
hdfs-site.xml
slaves
mapred-site.xml
yarn-site.xml
下面依次进行配置:
1、 hadoop-env.sh 修改JAVA_HOME 的值
export JAVA_HOME=/usr/java/jdk1.7.0_67
2、core-site.xml 在configuration中添加如下配置
<configuration>
<property>
<name>fs.defaultFS</name>
<value>hdfs://myhadoop</value> 此处名称需与hdfs-site.xml中dfs.nameservices的值保持一致
</property>
<property>
<name>hadoop.tmp.dir</name>
<value>/opt/hadoop</value>
</property>
<property>
<name>ha.zookeeper.quorum</name>
<value>hadoop1:2181,hadoop2:2181,hadoop3:2181</value> //zookeeper集群
</property>
</configuration>
注:hadoop.tmp.dir 是hadoop文件系统依赖的基础配置,很多路径都依赖它。如果hdfs-site.xml中不配 置namenode和datanode的存放位置,默认就放在这个路径中。
3、hdfs-site.xml
<configuration>
<property>
<name>dfs.nameservices</name>
<value>myhadoop</value> /此处名称需与core-site.xml中fs.defaultFS的值保持一致
</property>
<property>
<name>dfs.ha.namenodes.myhadoop</name> //配置namenode的组成
<value>nn1,nn2</value>
</property>
<property>
<name>dfs.namenode.rpc-address.myhadoop.nn1</name> 配置namenode1的rpc端口
<value>hadoop1:8020</value>
</property>
<property>
<name>dfs.namenode.rpc-address.myhadoop.nn2</name> 配置namenode2的rpc端口
<value>hadoop2:8020</value>
</property>
<property>
<name>dfs.namenode.http-address.myhadoop.nn1</name> 配置namenode1的http端口
<value>hadoop1:50070</value>
</property>
<property>
<name>dfs.namenode.http-address.myhadoop.nn2</name> 配置namenode2的http端口
<value>hadoop2:50070</value>
</property>
<property>
<name>dfs.namenode.shared.edits.dir</name> 配置journalnode集群
<value>qjournal://hadoop1:8485;hadoop2:8485;hadoop3:8485/myhadoop</value>
</property>
<property>
<name>dfs.client.failover.proxy.provider.myhadoop</name> 配置后台类。作用:HDFS Client用此类联系处于active状态的namenode
<value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
</property>
<property>
<name>dfs.ha.fencing.methods</name> 用于主备节点切换时实现隔离机制的
<value>sshfence</value>
</property>
<property>
<name>dfs.ha.fencing.ssh.private-key-files</name> 配置密钥的路径 需与前面免密钥设置的路径保持一致
<value>/root/.ssh/id_rsa</value>
</property>
<property>
<name>dfs.journalnode.edits.dir</name> journalnode的持久化文件保存路径
<value>/opt/journal/data</value>
</property>
<property>
<name>dfs.ha.automatic-failover.enabled</name> 设置故障自动切换功能可用
<value>true</value>
</property>
</configuration>
4、slaves 配置Datanode的主机名称,删除原有内容,添加如下配置:
hadoop2
hadoop3
hadoop4
5、mapred-site.xml 配置yarn 。使用hadoop自带的模板进行配置
mv mapred-site.xml.template mapred-site.xml
<configuration>
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
</configuration>
6、yarn-site.xml
<configuration>
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<property>
<name>yarn.resourcemanager.ha.enabled</name>
<value>true</value>
</property>
<property>
<name>yarn.resourcemanager.cluster-id</name>
<value>myyarncluster</value>
</property>
<property>
<name>yarn.resourcemanager.ha.rm-ids</name>
<value>rm1,rm2</value>
</property>
<property>
<name>yarn.resourcemanager.hostname.rm1</name>
<value>hadoop3</value>
</property>
<property>
<name>yarn.resourcemanager.hostname.rm2</name>
<value>hadoop4</value>
</property>
<property>
<name>yarn.resourcemanager.zk-address</name>
<value>hadoop1:2181,hadoop2:2181,hadoop3:2181</value>
</property>
</configuration>
7、以上6个配置文件配置完毕后, 同步至其它三台主机:
scp * hadoop2:`pwd`
scp * hadoop3:`pwd`
scp * hadoop4:`pwd`
8、启动journalnode集群。(之所以将journalnode集群放在namenode之前启动,是因为namenode启动时,会往journalnode写入edits日志文件)
在三台journalnode主机分别启动:
hadoop-daemon.sh start journalnode
9、NN的格式化 与 同步
在其中一台NN上,执行文件系统的格式化操作。注意:此处的格式化并非真正的格式化,而是一些准备和清除操作(比如清空fsimage和edits文件的存储目录下已有的文件)
hdfs namenode -format
此时,这一台NN已经完成了格式化操作,接下来,需要将格式化之后的文件系统同步到另一台NN。同步时,第二台NN会从第一台NN读取数据,故需要先将第一台NN启动起来。
hadoop-daemon.sh start namenode
第一台NN启动后,在第二台NN上执行以下命令(此时NN尚未启动),即可完成同步操作:
hdfs namenode -bootstrapStandby
10、zookeeper集群的格式化
在上面已经启动了zookeeper集群,故此处在其中一台NN上执行以下命令,完成zookeeper的格式化:
hdfs zkfc -formatZK /集群的一些高可用信息读到zookeeper中
至此,Hadoop完全分布式集群的配置工作都已经完成!
接下来,启动集群,在其中一台主机上执行以下命令(最好是在NN上执行,因为NN->DN设置了免密钥):
start-all.sh
然后分别在RS主机上启动resourcemanager
yarn-daemon.sh start resourcemanager
在start-all.sh的时候会有如下信息输出:
这里有一个需要注意的地方:
我是在hadoop1上执行的start-all.sh命令,hadoop1上并没有部署resourcemanager,但是打印出的信息显示启动了resourcemanager。why?
真正的执行过程是这样的:执行start-all.sh命令的时候,会在本机(hadoop1)启动一个进程去启动resourcemanager,但是系统发现本机并没有部署resourcemanager,这时候系统会把该进程杀死,但是日志会记录下这个过程。
|
在上面截图的信息中我们可以看到,集群的启动顺序是:
NN --> DN --> JN -->ZKFC --> NM
jps 查看进程
hadoop集群的启动顺序:
1、启动zk集群
zkServer.sh start | status
2、start-all.sh
3、手动启动两台RS
yarn-daemon.sh start resourcemanager
停止顺序:
1、stop-all.sh
2、手动停止两台rs
yarn-daemon.sh stop resourcemanager
3、停止zk集群
启动完成后,可用浏览器访问:
http://192.168.3.101:50070/
http://192.168.3.102:50070/
http://192.168.3.103:8088
http://192.168.3.104:8088 104主机上的RS处于standby状态,访问104的时候,会跳转到103主机上(跳转使用的是主机名)。
附:在启动集群的过程中,有时会遇到下图的情景:
在启动的过程中,提示namenode或journalnode已经启动了,但是使用使用jps查看进程时,却看不到namenode或journalnode的进程。出现上述情况的原因是,集群上一次关闭时,出现了非正常关闭的情况。解决这种问题的方法就是,手动启动进程。
手动启动进程:hadoop-daemon.sh start namenode/datanode/journalnode/zkfc