基于zookeeper的Hadoop集群
集群规划
hadoop1(master) | hadoop2 | hadoop3 | |
---|---|---|---|
NameNode | √ | √ | |
DataNode | √ | √ | √ |
ResourceManager | √ | √ | |
zookeeper | √ | √ | √ |
准备工作
1、确保服务器安装了JDK
Hadoop需要java环境支持
输入该命令
java -version
确认是否有jdk,如没有请先安装jdk
2、关闭防火墙
#centos7启动firewall
systemctl start firewalld.service
#centos7重启firewall
systemctl restart firewalld.service
#centos7停止firewall
systemctl stop firewalld.service
#centos7禁止firewall开机启动
systemctl disable firewalld.service
#centos7查看防火墙状态
firewall-cmd --state
3、关闭selinux
Hadoop主节点管理子节点是通过SSH实现的, SELinux不关闭的情况下无法实现,会限制ssh免密码登录
vi /etc/selinux/config
# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
# enforcing - SELinux security policy is enforced.
# permissive - SELinux prints warnings instead of enforcing.
# disabled - No SELinux policy is loaded.
SELINUX=enforcing
# SELINUXTYPE= can take one of these two values:
# targeted - Targeted processes are protected,
# minimum - Modification of targeted policy. Only selected processes are protected.
# mls - Multi Level Security protection.
SELINUXTYPE=targeted
将 SELINUX=enforcing 改为 SELINUX=disabled
保存, 执行以下命令使selinux 修改立即生效
setenforce 0
4、修改主机名与IP映射
vi /etc/sysconfig/network
NETWORKING=yes
HOSTNAME=hadoop1
hostname填写当前主机的名字
vi /etc/hosts
192.168.37.251 hadoop1
192.168.37.252 hadoop2
192.168.37.253 hadoop3
在hosts中填写各个主机IP和主机名
5、创建hadoop用户
hadoop集群的用户名要一样
用root权限创建hadoop用户和hadoop用户组
groupadd hadoop
useradd -g hadoop hadoop
#修改用户密码
passwd hadoop
6、SSH免密登录
为了Hadoop主节点方便管理多个的从节点,配置SSH免密登录
切换到hadoop用户操作,输入该命令生成非对称公钥和私钥,这个在集群中所有节点机器都必须执行
ssh-keygen -t rsa
回车后不管提示什么,不要输入任何东西,一直按回车,按三次即可完成
cd /home/hadoop/.ssh/
首先将Master节点的公钥添加到authorized_keys
cat id_rsa.pub>>authorized_keys
其次将从节点的公钥添加到authorized_keys,这里我是在Hadoop1机器上操作的
ssh [email protected] cat /home/hadoop/.ssh/id_rsa.pub>> authorized_keys
ssh [email protected] cat /home/hadoop/.ssh/id_rsa.pub>> authorized_keys
设置修改/home/hadoop/.ssh/authorized_keys权限
chmod 700 /home/hadoop/.ssh
chmod 600 /home/hadoop/.ssh/authorized_keys
将Master节点的authorized_keys分发到其他slaves节点
scp -r /home/hadoop/.ssh/authorized_keys [email protected]:/home/hadoop/.ssh/
scp -r /home/hadoop/.ssh/authorized_keys [email protected]:/home/hadoop/.ssh/
用该命令验证下ssh免密登录是否成功
ssh hadoop@hadoop2
安装zookeeper
1、下载zookeeper
官网下载地址:http://mirror.bit.edu.cn/apache/zookeeper/
2、解压
tar -zxvf zookeeper-3.3.6.tar.gz
3、修改配置文件 zoo.cfg
将zookeeper压缩文件解压后,我们进入到 conf 目录
将 zoo_sample.cfg 文件复制并重命名为 zoo.cfg 文件
cp zoo_sample.cfg zoo.cfg
然后通过 vim zoo.cfg 命令对该文件进行修改
我们需要修改的第一个是 dataDir ,在指定的位置处创建好目录,这是zookeeper数据存放位置
第二个红框按如上格式填写,只需要修改对应的IP,IP可以改为对应的主机名
4、创建myid文件
在 上一步 dataDir 指定的目录下,创建 myid 文件
然后在该文件添加上一步 server. 的对应数字
比如我们上面的配置:
server.0=192.168.146.200:2888:3888
server.1=192.168.146.201:2888:3888
server.2=192.168.146.202:2888:3888
那么就必须在 192.168.146.200 机器的的 /usr/local/software/zookeeper-3.3.6/data 目录下创建 myid 文件,然后在该文件中写上 0 即可
后面的机器依次在相应目录创建myid文件,写上相应配置数字
5、配置环境变量
vi /etc/profile ,添加相应的配置信息:
#set zookeeper environment
export ZK_HOME=/usr/local/software/zookeeper-3.3.6
export PATH=$PATH:$ZK_HOME/bin
然后通过如下命令使得环境变量生效:
source /etc/profle
6、启动zookeeper
启动命令:
zkServer.sh start
停止命令:
zkServer.sh stop
重启命令:
zkServer.sh restart
查看集群节点状态:
zkServer.sh status
我们分别对集群三台机器执行启动命令。执行完毕后,分别查看集群节点状态:
出现如下即是集群搭建成功:
安装hadoop
1、下载hadoop
从官网或是镜像站下载
http://hadoop.apache.org/
http://mirrors.hust.edu.cn/apache/
2、解压缩
下载hadoop-2.7.5.tar.gz放置于/home/hadoop下并解压,这里我在hadoop1操作
tar –zxvf hadoop-2.7.5.tar.gz
3、修改配置文件
配置文件目录:/home/hadoop/hadoop-2.7.5/etc/hadoop
修改 hadoop-env.sh文件,填写jdk路径
vi hadoop-env.sh
修改core-site.xml
vi core-site.xml
<configuration>
<!-- 指定hdfs的nameservice为myha01 -->
<property>
<name>fs.defaultFS</name>
<value>hdfs://myha01/</value>
</property>
<!-- 指定hadoop临时目录 -->
<property>
<name>hadoop.tmp.dir</name>
<value>/home/hadoop/data/hadoopdata/</value>
</property>
<!-- 指定zookeeper地址 -->
<property>
<name>ha.zookeeper.quorum</name>
<value>hadoop1:2181,hadoop2:2181,hadoop3:2181</value>
</property>
<!-- hadoop链接zookeeper的超时时长设置 -->
<property>
<name>ha.zookeeper.session-timeout.ms</name>
<value>1000</value>
<description>ms</description>
</property>
</configuration>
zookeeper地址填写 主机名:端口号,zookeeper的端口默认是2181
修改hdfs-site.xml
vi hdfs-site.xml
<configuration>
<!-- 指定副本数 -->
<property>
<name>dfs.replication</name>
<value>2</value>
</property>
<!-- 配置namenode和datanode的工作目录-数据存储目录 -->
<property>
<name>dfs.namenode.name.dir</name>
<value>/home/hadoop/data/hadoopdata/dfs/name</value>
</property>
<property>
<name>dfs.datanode.data.dir</name>
<value>/home/hadoop/data/hadoopdata/dfs/data</value>
</property>
<!-- 启用webhdfs -->
<property>
<name>dfs.webhdfs.enabled</name>
<value>true</value>
</property>
<!--指定hdfs的nameservice为myha01,需要和core-site.xml中的保持一致
dfs.ha.namenodes.[nameservice id]为在nameservice中的每一个NameNode设置唯一标示符。
配置一个逗号分隔的NameNode ID列表。这将是被DataNode识别为所有的NameNode。
例如,如果使用"myha01"作为nameservice ID,并且使用"nn1"和"nn2"作为NameNodes标示符
-->
<property>
<name>dfs.nameservices</name>
<value>myha01</value>
</property>
<!-- myha01下面有两个NameNode,分别是nn1,nn2 -->
<property>
<name>dfs.ha.namenodes.myha01</name>
<value>nn1,nn2</value>
</property>
<!-- nn1的RPC通信地址 -->
<property>
<name>dfs.namenode.rpc-address.myha01.nn1</name>
<value>hadoop1:9000</value>
</property>
<!-- nn1的http通信地址 -->
<property>
<name>dfs.namenode.http-address.myha01.nn1</name>
<value>hadoop1:50070</value>
</property>
<!-- nn2的RPC通信地址 -->
<property>
<name>dfs.namenode.rpc-address.myha01.nn2</name>
<value>hadoop2:9000</value>
</property>
<!-- nn2的http通信地址 -->
<property>
<name>dfs.namenode.http-address.myha01.nn2</name>
<value>hadoop2:50070</value>
</property>
<!-- 指定NameNode的edits元数据的共享存储位置。也就是JournalNode列表
该url的配置格式:qjournal://host1:port1;host2:port2;host3:port3/journalId
journalId推荐使用nameservice,默认端口号是:8485 -->
<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://hadoop1:8485;hadoop2:8485;hadoop3:8485/myha01</value>
</property>
<!-- 指定JournalNode在本地磁盘存放数据的位置 -->
<property>
<name>dfs.journalnode.edits.dir</name>
<value>/home/hadoop/data/journaldata</value>
</property>
<!-- 开启NameNode失败自动切换 -->
<property>
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value>
</property>
<!-- 配置失败自动切换实现方式 -->
<property>
<name>dfs.client.failover.proxy.provider.myha01</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>
<property>
<name>ha.failover-controller.cli-check.rpc-timeout.ms</name>
<value>60000</value>
</property>
</configuration>
修改mapred-site.xml
vi mapred-site.xml
<configuration>
<!-- 指定mr框架为yarn方式 -->
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
<!-- 指定mapreduce jobhistory地址 -->
<property>
<name>mapreduce.jobhistory.address</name>
<value>hadoop1:10020</value>
</property>
<!-- 任务历史服务器的web地址 -->
<property>
<name>mapreduce.jobhistory.webapp.address</name>
<value>hadoop1:19888</value>
</property>
</configuration>
修改yarn-site.xml
vi 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>hadoop1</value>
</property>
<property>
<name>yarn.resourcemanager.hostname.rm2</name>
<value>hadoop2</value>
</property>
<!-- 指定zk集群地址 -->
<property>
<name>yarn.resourcemanager.zk-address</name>
<value>hadoop1:2181,hadoop2:2181,hadoop3:2181</value>
</property>
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<property>
<name>yarn.log-aggregation-enable</name>
<value>true</value>
</property>
<property>
<name>yarn.log-aggregation.retain-seconds</name>
<value>86400</value>
</property>
<!-- 启用自动恢复 -->
<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>
</configuration>
修改slaves
vi slaves
hadoop1
hadoop2
hadoop3
4、将hadoop安装包分发到其他集群节点
每台服务器中的hadoop安装包的目录必须一致, 配置还必须保持一致
scp -r /home/hadoop/hadoop-2.7.5 hadoop@hadoop2:/home/hadoop/
scp -r /home/hadoop/hadoop-2.7.5 hadoop@hadoop3:/home/hadoop/
5、配置Hadoop环境变量
如果使用hadoop用户安装,就修改用户变量 vi /etc/profile
如果使用root用户安装,就修改系统变量 vi ~/.bashrc
export HADOOP_HOME=/home/hadoop/apps/hadoop-2.7.5
export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin:
root用户使环境变量生效
source /etc/profile
hadoop用户使环境变量生效
source ~/.bashrc
6、查看hadoop版本
hadoop version
hadoop集群的初始化
1、确保你的zookeeper集群已经正常启动
查看zookeeper状态
zkServer.sh status
2、在你配置的各个journalnode节点启动该进程
按照之前的规划,我的是在hadoop1、hadoop2、hadoop3上进行启动,启动命令如下
在sbin目录下执行该命令
hadoop-daemon.sh start journalnode
3、格式化namenode
选取一个namenode(hadoop1)节点进行格式化
hadoop namenode -format
4、格式化zkfc
注意只能在nameonde节点进行
hdfs zkfc -formatZK
初次启动hadoop集群
1、启动namenode
#启动namenode
#hadoop1
/home/hadoop/hadoop-2.7.5/sbin/hadoop-daemon.sh start namenode
#同步备用namenode、启动备用namenode
#hadoop2
/home/hadoop/hadoop-2.7.5/bin/hdfs namenode -bootstrapStandby
/home/hadoop/hadoop-2.7.5/sbin/hadoop-daemon.sh start namenode
2、启动ZKFC
#hadoop1
/home/hadoop/hadoop-2.7.5/sbin/hadoop-daemon.sh start zkfc
#hadoop2
/home/hadoop/hadoop-2.7.5/sbin/hadoop-daemon.sh start zkfc
3、启动datanode
#这一步会启动所有的datanode
#hadoop1
/home/hadoop/hadoop-2.7.5/sbin/hadoop-daemons.sh start datanode
4、启动yarn
#在hadoop1上启动resouremanager
#hadoop1
/home/hadoop/hadoop-2.7.5/sbin/start-yarn.sh
#在hadoop2上启动备用resouremanager
ssh hadoop2
/home/hadoop/hadoop-2.7.5/sbin/yarn-daemon.sh start resourcemanager
至此,Hadoop 基于zookeeper的高可用集群就安装成功,并且启动了
5、启动任务历史服务器
#hadoop1
/home/hadoop/hadoop-2.7.5/sbin/mr-jobhistory-daemon.sh start historyserver
6、查看状态
HDFS
hadoop@hadoop1 ~]$ hdfs haadmin -getServiceState nn1
standby
[hadoop@hadoop1 ~]$ hdfs haadmin -getServiceState nn2
active
YARN
[hadoop@hadoop1 ~]$ yarn rmadmin -getServiceState rm1
standby
[hadoop@hadoop1 ~]$ yarn rmadmin -getServiceState rm2
active
6、WEB界面进行查看
HDFS
hadoop1
hadoop2
YARN
standby节点会自动跳到avtive节点
任务历史服务器web界面
jobhistory
重启hadoop集群
停止集群
/home/hadoop/hadoop-2.7.5/sbin/stop-all.sh
#停止所有hadoop进程
/home/hadoop/hadoop-2.7.5/sbin/start-all.sh
#启动所有hadoop进程
单独停止或启动某个进程
sbin/hadoop-daemons.sh start namenode 单独启动NameNode守护进程
sbin/hadoop-daemons.sh stop namenode 单独停止NameNode守护进程
sbin/hadoop-daemons.sh start datanode 单独启动DataNode守护进程
sbin/hadoop-daemons.sh stop datanode 单独停止DataNode守护进程
sbin/yarn-daemon.sh start resourcemanager 单独启动ResourceManager
sbin/yarn-daemon.sh stop resourcemanager 单独停止ResourceManager
sbin/yarn-daemons.sh start nodemanager 单独启动NodeManager
sbin/yarn-daemons.sh stopnodemanager 单独停止NodeManager
sbin/mr-jobhistory-daemon.sh start historyserver 手动启动jobhistory
sbin/mr-jobhistory-daemon.sh stop historyserver 手动停止jobhistory
我遇到过的问题
整理以下我遇到的问题及解决办法以供参考
1、hadoop集群无法启动
请先查看报错和日志信息,日志在/home/hadoop/hadoop-2.7.5/logs/下。
我遇到的问题是hadoop 9000端口拒绝访问。
请先查看9000端口监听情况。
netstat -nlp |grep 9000
监听的的如果不是本机ip:9000而是127.0.0.1:9000
解决:修改/etc/hosts 文件
vi /etc/hosts
若发现127.0.0.1 与机器名存在映射关系,需要删除映射关系(如下图红色框所示),否则hadoop 会把机器名映射到127.0.0.1 上去。
2、hadoop集群重启后不正常
我的hadoop集群为3个节点,hadoop集群重启后,在资源管理的web界面出现了4个甚至7个Active Nodes,以及Unhealthy Nodes。
然后我再次使用stop-all.sh命令停止集群,结果发现hadoop2的yarn web界面依然可以访问。
可能停止集群后,有些进程依然存在。
解决:先尝试stop-all.sh命令停止集群。
使用jps命令查看是否还有hadoop的相关进程。(jps命令用于查看java进程,必须安装jdk才能使用)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ACF1cdca-1588842771684)(新建文件夹/15.png)]
如还有hadoop相关进程存在,使用命令单独停止该进程。
然后我按照上文初次启动hadoop集群的方法,再次启动集群,集群成功的正常启动了。
3、datanode没有正常启动
hadoop集群启动后,使用jps命令查看,发现没有datanode。
可能的原因:namenode和datanode的数据不匹配。
hdfs-site.xml
<!-- namenode和datanode的工作目录-数据存储目录 -->
<property>
<name>dfs.namenode.name.dir</name>
<value>/home/hadoop/data/hadoopdata/dfs/name</value>
</property>
<property>
<name>dfs.datanode.data.dir</name>
<value>/home/hadoop/data/hadoopdata/dfs/data</value>
</property>
格式化namenode后,会在我们配置的/dfs/name/下生成数据,而它和/dfs/data/下的数据不匹配,导致datanode没有正常启动
界面出现了4个甚至7个Active Nodes,以及Unhealthy Nodes。
然后我再次使用stop-all.sh命令停止集群,结果发现hadoop2的yarn web界面依然可以访问。
可能停止集群后,有些进程依然存在。
解决:先尝试stop-all.sh命令停止集群。
使用jps命令查看是否还有hadoop的相关进程。(jps命令用于查看java进程,必须安装jdk才能使用)
如还有hadoop相关进程存在,使用命令单独停止该进程。
然后我按照上文初次启动hadoop集群的方法,再次启动集群,集群成功的正常启动了。
3、datanode没有正常启动
hadoop集群启动后,使用jps命令查看,发现没有datanode。
可能的原因:namenode和datanode的数据不匹配。
hdfs-site.xml
<!-- namenode和datanode的工作目录-数据存储目录 -->
<property>
<name>dfs.namenode.name.dir</name>
<value>/home/hadoop/data/hadoopdata/dfs/name</value>
</property>
<property>
<name>dfs.datanode.data.dir</name>
<value>/home/hadoop/data/hadoopdata/dfs/data</value>
</property>
格式化namenode后,会在我们配置的/dfs/name/下生成数据,而它和/dfs/data/下的数据不匹配,导致datanode没有正常启动
解决:删除/dfs/data/下的所有文件,再次启动datanode
安装过程中如遇到什么问题,请扫关注公众号:架构师Plus