本文将从安装一台虚拟机开始,一步步的搭建一个hadoop集群。期间遇到了很多坑,我也把解决方案都写在文章中了,如果按照本文中的过程进行配置,还遇到了其他问题,欢迎各位提出~
1.单台虚拟机的配置
1.1. 安装一台 ubuntu20.04 虚拟机
上图中选择 15.X 是因为 Ubuntu20.04 是较新的版本,防止兼容性出问题。
标号 1 处将为你在 VMware Workstation 中看到的虚拟机名字;
标号 2 处选择的位置最好是一个空文件夹,因为在创建虚拟机时不会产生一个包含所有文件的文件夹,位置处即为所有文件的根目录。
这里的选择无所谓,以后还能调。
同样无所谓,可调。
如果你的网络是学校的校园网,建议选NAT,如果是家庭局域网,那么NAT和桥接都可以。不要选主机模式网络!!!否则hadoop将无法使用。
当然,这里的模式以后也可以重新选择。
标号1、2处看你机器的具体情况。
双击打开 CD/DVD(SATA)
选择已经事先准备好的 Ubuntu20.04 的 ISO文件,下载地址:https://ubuntu.com/download/desktop/thank-you?version=20.04.1&architecture=amd64
启动虚拟机,稍微等待一会儿。
将左侧的导航条拉到底选择中文,并选择安装Ubuntu。
Linux 新手不建议自己分配分区,容易后期用着用着发现有坑。。
选择时区
标号1,要设置的用户名
标号2,将要显示的计算机名
标号3-5,设置对应用户的用户名和密码
安装完成,进入桌面。
1.2. 安装VMTools工具
为了可以向虚拟机内传输文件和调节虚拟机的窗口大小,需要安装VMTools。
打开一个终端,依次输入命令:
sudo apt upgrade
sudo apt install open-vm-tools-desktop -y
sudo reboot
1.3.固定IP
首先确认要修改的网卡号,在终端输入命令
ip addr
我的虚拟机中显示如下:
接下来查看和修改网络配置信息。
我们创建的普通用户权限不足,不能修改网络配置信息,要先为普通用户赋予root权限,这需要切换到root用户下。首先为root用户设置一个密码并切换到root用户:
sudo passwd root
su root
gedit /etc/sudoers
新增一行,修改一行:
为用户增加权限的过程就完成了,下次sudo可以不用密码。
编辑网络配置信息文件
sudo gedit /etc/netplan/01-network-manager-all.yaml
PS:其中01-network-manager-all.yaml文件是我机器上的配置信息,不同的机器可能不太一样,可以使用:
cd /etc/netplan
ls
查看本机的文件:
在使用vi /etc/netplan/01-network-manager-all.yaml 命令后进入文件,需要把配置文件修改为以下内容:
假设IP地址修改为192.168.1.124,子网掩码24位即255.255.255.0,网关设置为192.168.1.2,DNS1:8.8.8.8。
dhcp4:no 代表不再动态分配IP。
network:
ethernets:
ens33:
dhcp4: no
addresses: [192.168.1.124/24]
optional: true
gateway4: 192.168.1.2
nameservers:
addresses: [8.8.8.8,223.6.6.6]
version: 2
renderer: NetworkManager
应用新的网络配置
sudo netplan apply
再次查看ip
ip addr
IP固定成功。
1.4.修改主机名与IP的映射
sudo gedit /etc/hosts
我将搭建一个三台机器的集群,分配的ip如下:
主机名 | ip |
---|---|
hadoop01 | 192.168.1.124 |
hadoop01 | 192.168.1.125 |
hadoop01 | 192.168.1.126 |
在文件的最后加入:
192.168.1.124 hadoop01
192.168.1.125 hadoop02
192.168.1.126 hadoop03
同时注释掉
#127.0.1.1 hadoop01
1.5.安装配置必要工具
1.5.1.SSH-Server
安装ssh-server
sudo apt-get install openssh-server
修改 /etc/ssh/ssh_config 文件
gedit /etc/ssh/ssh_config
将PermitRootLogin prohibit-password
改为 PermitRootLogin yes
后重启ssh服务
/etc/init.d/ssh restart
1.5.2.安装JDK
在windows上下载一个8以上版本的JDK,直接拖到linux虚拟机桌面上。
在桌面上打开一个终端,解压
tar -zvxf jdk-8u121-linux-x64.tar.gz
创建一个environments文件夹,以后专门用来放各种环境的包,并把解压好的jdk移动到这个文件夹中
mkdir ~/environments
mv jdk1.8.0_121 ~/environments/
编辑本用户的配置文件
gedit ~/.profile
在文件的最后加入
#Java
export JAVA_HOME=/home/jan/environments/jdk1.8.0_121
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib:$CLASSPATH
export PATH=${JAVA_HOME}/bin:${JRE_HOME}/bin:$PATH
在终端输入reboot重启,重启后验证是否生效。出现下面的提示则证明生效。
(这里有个小坑,按理说在修改配置文件之后重新开启一个终端配置文件应该就能生效,但是我测试的时候却没有,重启后才生效)
1.6.对hadoop进行初步的配置
首先计划集群做一个功能的分配:
hadoop01 | hadoop02 | hadoop03 |
---|---|---|
namenode | ||
datanode | datanode | datanode |
secondarynode | ||
resourcemanager | ||
nodemanager | nodemanager | nodemanager |
1.6.1.安装hadoop-2.7.2
还是,下载一个linux版 hadoop tar 包拖进虚拟机
解压之后移动得到用户根目录下
tar -zvxf hadoop-2.7.2.tar.gz
mv hadoop-2.7.2 ~/
1.6.2.修改环境变量
gedit ~/.profile
在文件末尾添加
# hadoop
export HADOOP_HOME=/home/jan/hadoop-2.7.2
export PATH=$PATH:${HADOOP_HOME}/bin:${HADOOP_HOME}/sbin
1.6.3.修改hadoop的配置文件:
进入配置文件目录
cd /home/jan/hadoop-2.7.2/etc/hadoop/
(其中jan是自己起的用户名)
修改以下4个文件
1.core-site.xml
gedit core-site.xml
<configuration>
<property>
<name>fs.defaultFS</name>
<!-- 告诉 NN 在那个机器,NN 使用哪个端口号接收客户端和 DN 的RPC请求-->
<value>hdfs://hadoop01:9000</value>
</property>
<property>
<name>hadoop.tmp.dir</name>
<value>/opt/zhw/module/hadoop-2.7.2/data/tmp</value>
<description>A base for other temporary directories.</description>
</property>
</configuration>
2.hdfs-site.xml
gedit hdfs-site.xml
<configuration>
<property>
<name>dfs.namenode.secondary.http-address</name>
<value>hadoop03:50090</value>
<description>
The secondary namenode http server address and port.
</description>
</property>
</configuration>
3.mapred-site.xml
复制一个 mapred-site.xml.template 文件
cp mapred-site.xml.template mapred-site.xml
在mapred-site.xml中加入内容:
gedit hdfs-site.xml
<configuration>
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
<description>The runtime framework for executing MapReduce jobs.
Can be one of local, classic or yarn.
</description>
</property>
<!-- MR运行时,向10020端口请求存放历史日志-->
<property>
<name>mapreduce.jobhistory.address</name>
<value>0.0.0.0:10020</value>
<description>MapReduce JobHistory Server IPC host:port</description>
</property>
<!-- 在浏览器上使用19888可以看历史日志-->
<property>
<name>mapreduce.jobhistory.webapp.address</name>
<value>0.0.0.0:19888</value>
<description>MapReduce JobHistory Server Web UI host:port</description>
</property>
</configuration>
4.yarn-site.xml
gedit yarn-site.xml
<configuration>
<!-- Site specific YARN configuration properties -->
<property>
<description>A comma separated list of services where service name should only
contain a-zA-Z0-9_ and can not start with numbers</description>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<property>
<description>The hostname of the RM.</description>
<name>yarn.resourcemanager.hostname</name>
<value>hadoop02</value>
</property>
<property>
<description>The http address of the RM web application.</description>
<name>yarn.resourcemanager.webapp.address</name>
<value>${yarn.resourcemanager.hostname}:8088</value>
</property>
<!-- 日志聚集功能,这里原本默认false-->
<property>
<name>yarn.log-aggregation-enable</name>
<value>true</value>
</property>
<!-- 日志保留时间设置7天 -->
<property>
<name>yarn.log-aggregation.retain-seconds</name>
<value>604800</value>
</property>
</configuration>
1.7.编写两个脚本以便于之后文件的分发和命令的传输
以下两个脚本源自尚硅谷的大数据课程,有兴趣去看看明白一下含义,这里我们仅仅说配置和用法。
1.xsync
新建一个文件
gedit xsync
此脚本用于虚拟机之间通过scp传送文件
#!/bin/bash
#校验参数是否合法
if(($#==0))
then
echo 请输入要分发的文件!
exit;
fi
#获取分发文件的绝对路径
dirpath=$(cd `dirname $1`; pwd -P)
filename=`basename $1`
echo 要分发的文件的路径是:$dirpath/$filename
#循环执行rsync分发文件到集群的每条机器
for((i=1;i<=3;i++))
do
echo ---------------------hadoop0$i---------------------
rsync -rvlt $dirpath/$filename hadoop0$i:$dirpath
done
2.xcall
新建一个文件
gedit xcall
此脚本用于对所有声明的虚拟机进行命令的传输
#!/bin/bash
#在集群的所有机器上批量执行同一个命令
if(($#==0))
then
echo 请输入要操作的命令!
exit;
fi
echo 要执行的命令是$*
#循环执行此命令
for((i=1;i<=3;i++))
do
echo --------------------hadoop0$i--------------------
ssh hadoop0$i $*
done
修改权限,并将它们移到 ~/bin/ 目录下
chmod 777 xsync
chmod 777 xcall
mkdir ~/bin
mv xsync ~/bin
mv xcall ~/bin/
这里先不测试了,因为测试需要配置ssh,我们会在克隆虚拟机之后配置ssh。
至此,单台虚拟机上所需要的内容基本上配置完毕,我们只需要将虚拟机克隆两台然后配置各自的固定IP、主机名,重新生成ssh密匙即可。
2.配置分布式集群
2.1.虚拟机的克隆
在终端输入命令关闭虚拟机
shutdown -h now
克隆
标号2,这里和之前一样,最好建一个新的空文件夹。
等待完成
完成后关闭窗口即可
找到克隆虚拟机的文件夹,选择.vmx文件后打开
完成克隆。
重复上面克隆的步骤,再克隆一台 hadoop03 。
将3台虚拟机开机。
2.2.修改主机名
在两台被克隆的虚拟机上分别修改
sudo gedit /etc/hostname
在hadoop02上:
在hadoop03上:
2.3.修改网络配置信息
与标题 1.3 修改网络的流程一样,只不过在修改的时候只修改IP地址的一行
addresses: [192.168.1.122/24]
对应三台虚拟机的地址分配为:
主机名 | ip |
---|---|
hadoop01 | 192.168.1.124 |
hadoop02 | 192.168.1.125 |
hadoop03 | 192.168.1.126 |
2.4.配置ssh免密登录
在三台虚拟机上分别执行:
ssh-keygen -t rsa
一直回车就可以了
这里是生成了rsa密钥
然后将这三个密钥在三台虚拟机上相互传输
首先,在hadoop01上向hadoop02、hadoop03发送
ssh-copy-id hadoop02
标号1,输入yes后回车
标号2,输入hadoop02的密码
完成后使用
ssh hadoop02
可以看到成功登录到了hadoop02上,且没有输入hadoop02 的jan用户密码的过程。
(PS:这里写的ssh hadoop02
省略了用户名,默认登录远端的用户名和本地当前用户名一致,也就是说相当于在用ssh jan@hadoop02
在进行远程ssh连接。)
使用命令exit
从hadoop02登出,继续执行
ssh-copy-id hadoop03
重复上面的过程完成hadoop01到hadoop03的免密ssh登录。然后,还没有结束,对于hadoop01本身也要进行ssh免密登录的设置
ssh-copy-id hadoop01
以上配置的免密过程是单向的,也就是说可以从hadoop01免密登录到hadoop02、hadoop03,而02和03不能免密登录到hadoop01,同时,hadoop02和hadoop03之间也不能免密登录。
切换到hadoop02虚拟机上,用相同的过程完成hadoop02到hadoop01、hadoop02、hadoop03的免密登录。
继续切换到hadoop03虚拟机上,用相同的过程完成hadoop03到hadoop01、hadoop02、hadoop03的免密登录。
至此,ssh的免密登录过程完成。
2.5.测试xcall和xsync命令
2.5.1.xcall
使用xcall来关闭三台虚拟机上的防火墙,在hadoop01的终端上输入(起始任意一台虚拟机都可以)
xcall ufw disable
可以看到三台虚拟机的防火墙都被禁用了,成功!
2.5.2.xsync
起始刚才在配置hadoop文件时,还有一个文件被落下没有修改。为hadoop2.7.2/etc/hadoop/slaves
在任意一台虚拟机上修改这个文件
cd ~/hadoop-2.7.2/etc/hadoop/
gedit slaves
将文件内容修改为
hadoop01
hadoop02
hadoop03
使用xsync脚本将修改的文件分发到另外两台虚拟机上
cd ~/hadoop-2.7.2/etc/
xsync hadoop/
即完成了文件的分发。
2.6.设置non-login环境变量
我们使用的xcall脚本是以non-login的方式打开一个bash执行命令的,此时不会读取配置文件~/.profile,而是读取 ~/.bashrc。
因此需要配置~/.bashrc
2.6.1.方式一
先在hadoop01上修改配置文件
gedit ~/.bashrc
在文件的首行加入
source ~/.profile
上面这条命令可以使~/.profile
文件立即生效
但如果此时我们使用ssh hadoop01 jps
来执行远程命令,会发现ssh卡住,并且一会儿就会自动退出,也没有成功登录的提示。
因为在 ~/.profile
有这么一块内容
if [ -n "$BASH_VERSION" ]; then
# include .bashrc if it exists
if [ -f "$HOME/.bashrc" ]; then
. "$HOME/.bashrc"
fi
fi
意思是在 ~/.profile
文件被加载后,它还会自动的加载~/.bashrc
。而我们在~/.bashrc
文件中又加载了 ~/.profile
文件,如此以来就形成了一个死循环,会一直处于配置文件的加载过程,自然无法执行命令。
因此,只需要将以上的内容每行开头加一个#
注释掉即可。
#if [ -n "$BASH_VERSION" ]; then
# include .bashrc if it exists
# if [ -f "$HOME/.bashrc" ]; then
# . "$HOME/.bashrc"
# fi
#fi
保存后再次测试
成功。
接着将修改过的 ~/.profile
和~/.bashrc
文件分发到另外两台虚拟机上
xsync ~/.profile
xsync ~/.bashrc
测试
xcall jps
成功。
2.6.2.方式二
还可以将~/.profile
中定义过的JAVA_HOME以及HADOOP_HOME复制到~/.bashrc
中,然后注释掉~/.bashrc
的如下内容即可
# If not running interactively, don't do anything
case $- in
*i*) ;;
*) return;;
esac
至此就完成了进行hadoop初始化之前的内容,此时可以将虚拟机再次克隆一份以备之后使用。
3.hadoop的初次使用
3.1.hadoop初始化
在hadoop01中输入
hadoop namenode -format
3.2.开启HDFS
在hadoop01上开启hdfs
start-dfs.sh
在物理机上访问192.168.1.124:50070
,此为HDFS的web页面
标号2,可以看到hdfs三个datanode成功启动 !
3.3.开启YARN
在hadoop02上开启YARN
start-yarn.sh
接着访问192.168.1.125:8088
,此为YARN的web页面
可以看到三台节点均启动成功!
3.4.开启历史日志服务
在hadoop01上开启
mr-jobhistory-daemon.sh start historyserver
使用xcall jps
查看所有节点的运行i情况
开启成功~
集群搭建完毕。
本文基本上把所有在从0搭建新的Hadoop集群时可能碰到的问题都提前解决了,有几个需要注意的问题。
注意
1.集群分配
如果你的 namenode,resourcemanager,secondarynamonoe在不同的机器上,那么一定一定不要忘记把所有机器之间的ssh免密登录配置好,否则大概率resourcemanager无法启动。
2.java API 读写HDFS
想用java API对HDFS读写,那么一定要在装载虚拟机的物理机或者三台虚拟机内,否则就没法使用,因为datanode的 ip 是虚拟局域网的,而外网读到这个虚拟局域网的 IP 是无法解析的,所以没法传输数据。
写博客好慢,竟然用了一整天。。。