Hadoop完全分布式HA高可用集群搭建
写在前面的:
本人也是初学者一枚,该集群是通过网上学习自行搭建,如有错误,欢迎指正讨论😊
文件配置:
VMWare 15.5.0,ubuntu18.04.3,Xftp5,hadoop-2.7.1,jdk-8u231-linux-x64,Xshell6,Python-2.7.10
节点分配:
节点名称 | NN1 | NN2 | DN1 | DN2 | DN3 |
---|---|---|---|---|---|
namenode | ✔ | ✔ | |||
datanode | ✔ | ✔ | ✔ | ||
resoursemanager | ✔ | ✔ | |||
nodemanager | ✔ | ✔ | ✔ | ||
zookeeper | ✔ | ✔ | ✔ | ||
journalnode | ✔ | ✔ | ✔ | ✔ |
1. 修改主机名
终端输入:sudo vim /etc/hostname,在vim端,输入i进入编辑模式,将主机名修改为Master按esc退出编辑模式,按wq保存并退出重启虚拟机生效。
192.168.111.154 NameNode1
192.168.111.155 NameNode2
192.168.111.156 DataNode1
192.168.111.157 DataNode2
192.168.111.157 DataNode3
2. 创建另外4台虚拟机
- 右击虚拟机,管理->克隆,选择完整克隆。分别进入系统将其主机名改为hostname中对应的名字。
- 在所有节点终端输入sudo vim /etc/hosts 将三个节点的名称和IP地址添加进去(在终端ifconfig完成各节点IP地址的查询)
- 验证:在Master节点上分别ping 四台虚拟机的主机名,ping通则表示成功(只ping3次就会停止,否则按Ctrl+C中断)
3. 下载安装SSH
目的:为了Master远程连接和免密登录Slave
步骤:
1.在主节点安装openssh-server
sudo apt-get install openssh-server (每个节点都要操作)
ssh localhost 登陆本机(测试是否安装成功),exit退出
SSH-keygen 生成密钥并加入授权(在Master节点上)exit返回到用户端
cd ~/.ssh
rm ./id_rsa*删除旧的密钥(若存在)
ssh-keygen -t rsa(执行命令后一直按回车)
cat ./id_rsa.pub >>. /authorized_keys
2.将Master节点上的公钥传给其他节点
scp ~/.ssh/id_rsa.pub 用户名@ Slave1:/home/用户名/
scp ~/.ssh/id_rsa.pub 用户名@ Slave2:/home/用户名/
3.在从节点上将SSH公钥加入授权
mkdir ~/.ssh
cat ~/id_rsa.pub >> ~/.ssh/authorized_keys
rm ~/id_rsa.pub
4.将Master节点上的公钥传给其他节点并在其他节点授权
主节点:
scp ~/.ssh/id_rsa.pub 用户名@ NameNode2:/home/用户名/
scp ~/.ssh/id_rsa.pub 用户名@ DataNode1:/home/用户名/
scp ~/.ssh/id_rsa.pub 用户名@ DataNode2:/home/用户名/
scp ~/.ssh/id_rsa.pub 用户名@ DataNode3:/home/用户名/
各从节点:
mkdir ~/.ssh
cat ~/id_rsa.pub >> ~/.ssh/authorized_keys
rm ~/id_rsa.pub
4. 安装Xftp,Xshell
目的:连通linux和windows,可以将文件在二者之间传输
步骤:安装成功后文件->新建,输入名称和IP地址,登陆的地方填写客户端的名称和密码。完成后只要打开并连接即可。
5. 安装Java
将java压缩包通过xftp传至节点并解压到指定目录(所有节点必须一致)
vim ~/.bashrc //进入环境变量
在文件的最后加入三行配置PATH,添加绝对路径
exoprt JAVA_HOME=java路径
export HADOOP_HOME=hadoop文件路径
export PATH=$PATH:$JAVA_HOME/bin
source ~/.bashrc //变量设置生效
java -version //查看java版本号
6. 安装,配置zookeeper
利用xftp将zookeeper压缩包传到DataNode1上
-
进入conf目录,复制zoo-sample.cfg重命名为zoo.cfg,通过修改zoo.cfg来对zookeeper进行配置。这个名字固定写死,因为zookeeper启动会检查这个文件,根据这个配置文件里的信息来启动服务。
cp zoo-sample.cfg zoo.cfg vim zoo.cfg
-
到之前配置的zookeeper数据文件所在的目录下生成一个文件叫myid,其中写上一个数字表明当前机器是哪一个编号的机器。
vim myid 1
-
将以上Zookeeper文件夹远程拷贝到另外两台服务器中
scp -r zookeeper-3.4.5 DataNode2:/路径 scp -r zookeeper-3.4.5 DataNode3:/路径
7. 安装配置Hadoop
在windows端将压缩包拖送至Master的/home目录下,解压文件至该路径,将hadoop的路径加入环境变量(同java)
输入Hadoop version查看是否配置成功
hadoop文件目录:
cd /etc/hadoop到该目录下配置6个文件(直接点击文件将以下内容进行添加)
core-site.xml配置
<configuration>
<property>
<name>fs.defaultFS</name>
<value>hdfs://ns1</value>
</property>
<property>
<name>hadoop.tmp.dir</name>
<value>/home/jqt/hadoop-2.7.1/tmp1</value>
<description>Abase for other temporary directories.</description>
</property>
<property>
<name>ha.zookeeper.quorum</name>
<value>DataNode1:2181,DataNode2:2181,DataNode3:2181</value>
</property>
</configuration>
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>192.168.111.154:9001</value>
</property>
<property>
<name>dfs.namenode.http-address.ns1.nn1</name>
<value>192.168.111.154:50070</value>
</property>
<!-- nn2的RPC通信地址 -->
<property>
<name>dfs.namenode.rpc-address.ns1.nn2</name>
<value>192.168.111.155:9001</value>
</property>
<property>
<name>dfs.namenode.http-address.ns1.nn2</name>
<value>192.168.111.155:50070</value>
</property>
<!-- 指定NameNode的元数据在JournalNode上的存放位置 -->
<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://NameNode1:8485;DataNode1:8485;DataNode2:8485;DataNode3:8485/ns1</value>
</property>
<!-- 指定JournalNode在本地磁盘存放数据的位置 -->
<property>
<name>dfs.journalnode.edits.dir</name>
<value>/home/jqt/hadoop-2.7.1/tmp1/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>
<!-- 使用sshfence隔离机制时需要ssh免登陆 -->
<property>
<name>dfs.ha.fencing.ssh.private-key-files</name>
<value>/home/jqt/.ssh/id_rsa</value>
</property>
<!-- 配置隔离机制方法,多个机制用换行分割,即每个机制暂用一行-->
<property>
<name>dfs.ha.fencing.methods</name>
<value>
sshfence
shell(/bin/true)
</value>
</property>
<!-- 配置sshfence隔离机制超时时间 -->
<property>
<name>dfs.permissions.enabled</name>
<value>false</value>
</property>
<property>
<name>dfs.ha.fencing.ssh.connect-timeout</name>
<value>30000</value>
</property>
</configuration>
mapred-site.xml配置
<configuration>
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
</configuration>
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>NameNode1</value>
</property>
<property>
<name>yarn.resourcemanager.hostname.rm2</name>
<value>NameNode2</value>
</property>
<property>
<name>yarn.resourcemanager.webapp.address.rm1</name>
<value>NameNode1:8088</value>
</property>
<property>
<name>yarn.resourcemanager.webapp.address.rm2</name>
<value>NameNode1:8088</value>
</property>
<!-- 指定zk集群地址 -->
<property>
<name>yarn.resourcemanager.zk-address</name>
<value>DataNode1:2181,DataNode2:2181,DataNode3:2181</value>
</property>
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
</configuration>
slves.xml配置
将原内容换成节点名称
DataNode1
DataNode2
DataNode3
hadoop env.sh,yarn-env.sh配置JAVA_HOME
vim进入文件添加或修改java路径 export JAVA_HOME=java目录
全部配置完成后将主节点上的hadoop文件夹拷贝到各个丛节点下:
scp -r /home/jqt/hadoop-2.7.1/ NameNode2:/home/jqt
scp -r /home/jqt/hadoop-2.7.1/ DataNode1:/home/jqt
scp -r /home/jqt/hadoop-2.7.1/ DataNode2:/home/jqt
scp -r /home/jqt/hadoop-2.7.1/ DataNode3:/home/jqt
8. 初始化,启动hadoop/zookeeper
在DataNode1,2,3下依次输入命令完成完成zookeeper的初始化和启动
-
在bin目录下zkServer.sh start 启动,
-
zkServer.sh status查看状态,有1个DN(本文位DN2)会成推举为leader,其他为follow
-
在hadoop的sbin目录下 hadoop-daemon.sh start journalnode启动journalnode
在主节点启动journalnode: hadoop-daemon.sh start journalnode
在NN2开启resourcemanager:yarn-daemon.sh start resourcemanager
在NameNode1依次输入以下命令完成hadoop的初始化和启动
• hdfs namenode -format //初始化名称节点
• start-all.sh
jps可以查看各个节点上进程
在web端查看进程状态:
在firefox浏览器中输http://namenode1:50070/
注:若想在windows端的浏览器进行查看,需要在C:Windows/System32/drivers/etc目录下的hosts文件中添加各节点的IP地址以及映射
9. 遇到的问题
-
jps后发现master上没有namenode
解决方法:在etc/hadoop中将配置文件core-site中清空tmp文件,namenode在初始化一次
有可能没有启动journalnode
-
jps后发现Slave节点上没有datanode和nodemanage
解决方法:在/home/hadoop-7.2.1/logs文件夹中查看datanode的运行日志,发现yarn-site配置出现错误,进行修改后重启hadoop成功;也有可能是端口被占用将core-site中的端口号进行调整例如将Master:9000改为Master:namenode1:9001.
-
主节点网络问题(没有IP地址):
sudo dhclient ens33 sudo ifconfig ens33
10. 执行分布式实例wordcount
hdfs dfs -mkdir -p /data/input(output) //创建输入输出文件
touch my_wordcount.txt //创建my_wordcount文档
vim my_wordcount.txt //编辑文档,输入文本
hdfs dfs -put my_wordcount.txt /data/input //将文档拷贝到输入文件中 (注:可通过hdfs dfs -ls /data/input查看文件是否拷贝成功 )
//向Hadoop提交单词统计任务
hadoop jar /home/jqt/hadoop-2.7.1/share/hadoop/mapreduce/WordCount.jar application /data/input/wordcount.txt /data/output/word
hdfs dfs -cat /data/output/wordcount/part-r-00000 //查看结果
注:WordCount.jar是我上传的,application是主函数名。
默认的jar包在hadoop-2.7.1/share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.1.jar 主函数名:wordcount