搭建Hadoop集群流程
环境准备
1、基础环境的搭建(内网封火墙关闭、主机名、规划好静态ip、hosts映射、时间同步ntp、jdk、ssh免密等)
2、Hadoop源码编译(为了适应不同操作系统间适配本地库、本地环境等)
3、Hadoop配置文件的修改(shell文件、4个xml文件、workers文件)
4、配置文件集群同步(scp进行分发)
具体流程如下:
常用命令(这部分看情况而定)
vim /etc/sysconfig/network-scripts/ifcfg-ens33
# 做出如下修改
BOOTPROTO=static # 改为静态
# 末尾添加如下内容
IPADDR=192.168.188.128
GATEWAY=192.168.188.2
NETMASK=255.255.255.0
DNS1=114.114.114.114
# 重启网卡
systemctl restart network.service
# 修改主机名
vim /etc/hostname
# 配置hosts映射
vim /etc/hosts
192.168.188.128 kk01
192.168.188.129 kk02
192.168.188.130 kk03
# 修改window的主机映射文件(hosts)
# 进入C:\Windows\System32\drivers\etc
# 添加如下内容
192.168.188.128 kk01
192.168.188.129 kk02
192.168.188.130 kk03
# 查看防火墙状态
firewall-cmd --state
# 或
systemctl status firewalld.service
systemctl stop firewalld.service # 关闭当前防火墙
systemctl disable firewalld.service # 关闭防火墙开机自启动
创建普通用户,并让其具有root权限(如果使用root用户可以忽略该步骤)
# 创建用户 (如果安装Linux时已经创建了,这一步骤可以忽略)
useradd nhk
passwd 123456
# 配置普通用户(nhk)具有root权限,方便后期加sudo执行root权限的命令
vim /etc/sudoers
# 在%wheel这行下面添加一行 (大概是在100行左右位置)
## Allow root to run any commands anywhere
root ALL=(ALL) ALL
## Allows members of the 'sys' group to run networking, software,
## service management apps and more.
# %sys ALL = NETWORKING, SOFTWARE, SERVICES, STORAGE, DELEGATING, PROCESSES, LOCATE, DRIVERS
## Allows people in group wheel to run all commands
%wheel ALL=(ALL) ALL
## Same thing without a password
# %wheel ALL=(ALL) NOPASSWD: ALL
nhk ALL=(ALL) NOPASSWD: ALL
注意:
nhk ALL=(ALL) NOPASSWD: ALL 这行内容要放在%wheel下面,千万不能放在root下面
创建统一工作目录
(后续在集群的多台机器之间都需要创建)
# 个人习惯
mkdir -p /opt/software/ # 软件安装目录、安装包存放目录
mkdir -p /opt/data/ # 数据存储路径
# 修改文件夹所有者和所属组 (如果是使用root用户搭建集群可以忽略)
chown nhk:nhk /opt/software
chown nhk:nhk /opt/data
# 黑马推荐
mkdir -p /export/server/ # 软件安装目录
mkdir -p /export/data/ # 数据存储路径
mkdir -p /export/software/ # 安装包存放目录
SSH免密登录
# 只需配置(kk01 --> kk01 kk02 kk03 即可 )
ssh-keygen # kk01生成公钥、私钥
# 配置免密 kk01 --> kk01 kk02 kk03
ssh-copy-id kk01
ssh-copy-id kk02
ssh-copy-id kk03
集群时间同步
# 在集群的每台集群
yum -y install ntpdate
ntpdate ntp4.aliyun.com
# 或
ntpdate ntp5.aliyum.com
# 查看时间
date
卸载Linux自带的jdk
(如果Linux这没有自带open jdk,则忽略此步骤)
# 查看jdk命令
rpm -qa | grep -i java # -i 忽略大小写
# 删除
rpm -e –nodeps 待删除的jdk
# 也可以使用以下命令删除
rpm -qa | grep -i java | xargs -n1 rpm -e --nodeps
# 其中 xargs -n1表示每次只传递一个参数
# -e --nodeps表强制卸载软件
# 删除完后,使用以下命令查看jdk是否还在
java -version
配置JDK环境变量
注意:在安装jdk之前,一定要确保Linux自带的jdk已经被卸载
# 上传jdk压缩包(使用rz命令或者ftp工具)
# 解压jdk
tar -zxvf jdk-8u152-linux-x64.tar.gz -C /opt/software/
# 配置JDK环境(如果是普通用户进入需要加sudo)
sudo vim /etc/profile
export JAVA_HOME=/opt/software/jdk1.8.0_152
export PATH=$PATH:$JAVA_HOME/bin
export CLASSPATH=.:$JAVA_HOME/lib:$JAVA_HOME/jre/lib/rt.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
# 重新加载环境变量文件
source /etc/profile
Hadoop安装
解压Hadoop压缩包
# 上传Hadoop压缩包
cd /opt/software/
rz
# 解压
tar -xvzf hadoop-3.2.2.tar.gz
# 在每个节点中创建用于存放数据的data目录
配置文件描述
第一类1个:hadoop-env.sh
第二类4个:xxxx-site.xml,site表示是用户自定义的配置,会默认覆盖default默认配置
core-site.xml 核心模块配置
hdfs-site.xml hdfs文件系统模块配置
mapred-site.xml mapreduce模块配置
yarn-site.xml yarn模块配置
第三类1个:workers
所有的配置文件目录文件:/opt/software/haoop-3.2.2/etc/hadoop
配置NameNode(core-site.xml)
cd /opt/software/hadoop-3.2.2/etc/hadoop
vim core-site.xml
# 添加如下内容
<!-- 数组默认使用的文件系统 Hadoop支持file、HDFS、GFS、ali|Amazon云等文件系统-->
<property>
<name>fs.defaultFS</name>
<value>hdfs://kk01:8020</value>
<description>指定NameNode的URL</description>
</property>
<!-- 设置hadoop本地保存数据路径-->
<property>
<name>hadoop.tmp.dir</name>
<!--可以配置在/opt/data/hadoop-3.2.2,但是我们建议配置在${HADOOP_HOME}/data下面-->
<value>/opt/data/hadoop-3.2.2</value>
</property>
<!-- 设置HDFS web UI用户身份为 root,如果使用的是普通用户,配置成普通用户即可-->
<property>
<name>hadoop.http.staticuser.user</name>
<value>root</value>
</property>
<!-- 缓冲区大小,实际工作中根据服务器性能动态调整 -->
<property>
<name>io.file.buffer.size</name>
<value>4096</value>
</property>
配置HDFS路径(hdfs-site.xml)
vim hdfs-site.xml
# 添加如下内容
<!-- 设置SNN进程运行时机器位置的信息-->
<!--2nn web端访问地址 -->
<property>
<name>dfs.namenode.secondary.http-address</name>
<value>kk02:9868</value>
</property>
<!-- nn web端访问地址-->
<!--hadoop3默认该端口为9870,不配也行-->
<property>
<name>dfs.namenode.http-address</name>
<value>kk01:9870</value>
</property>
配置YARN(yarn-site.xml)
vim yarn-site.xml
# 添加如下内容
<!-- 设置yarn集群主角色rm运行机器位置-->
<property>
<name>yarn.resourcemanager.hostname</name>
<value>kk01</value>
</property>
<!--nodemanager上运行的附属程序。需配置成mapreduce_shuffle,才可运行mr程序-->
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<!-- 是否将对容器实施物理内存限制 生产中可产生改配置-->
<property>
<name>yarn.nodemanager.pmem-check-enabled</name>
<value>false</value>
</property>
<!-- 是否将对容器实施虚拟内存限制 生产中可产生改配置-->
<property>
<name>yarn.nodemanager.vmem-check-enabled</name>
<value>false</value>
</property>
<!--日志聚集功能好处:可以方便的查看到程序运行详情,方便开发调试-->
<!-- 开启日志聚集-->
<property>
<name>yarn.log-aggregation-enable</name>
<value>true</value>
</property>
<!-- 设置yarn历史服务器地址-->
<property>
<name>yarn.log.server.url</name>
<value>http://kk01:19888/jobhistory/logs</value>
</property>
<!-- 历史日志保存的时间 7天-->
<property>
<name>yarn.log-aggregation.retain-seconds</name>
<value>604800</value>
</property>
配置MapReduce(mapred-site.xml)
vim mapred-site.xml
# 添加如下内容
<!-- 设置MR程序默认运行方式:yarn集群模式 local本地模式-->
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
<!--为了查看程序的历史运行情况,需要配置一下历史服务器-->
<!-- MR程序历史服务地址-->
<property>
<name>mapreduce.jobhistory.address</name>
<value>kk01:10020</value>
</property>
<!-- MR程序历史服务器web端地址-->
<property>
<name>mapreduce.jobhistory.webapp.address</name>
<value>kk01:19888</value>
</property>
<!-- mr app master环境变量-->
<property>
<name>yarn.app.mapreduce.am.env</name>
<value>HADOOP_MAPRED_HOME=${HADOOP_HOME}</value>
</property>
<!-- mr maptask环境变量-->
<property>
<name>mapreduce.map.env</name>
<value>HADOOP_MAPRED_HOME=${HADOOP_HOME}</value>
</property>
<!-- mr reducetask环境变量-->
<property>
<name>mapreduce.reduce.env</name>
<value>HADOOP_MAPRED_HOME=${HADOOP_HOME}</value>
</property>
workers文件(该文件是为了群起集群)
vim /opt/software/hadoop-3.2.2/etc/hadoop/workers
# 将文件内容替换为如下
kk01
kk02
kk03
# 注意:该文件中添加的内容结尾不允许有空格,文件中不允许有空行。
修改hadoop-env环境变量
如果是使用root用户搭建Hadoop则需要配置,否则忽略
vim /opt/software/hadoop-3.2.2/etc/hadoop/hadoop-env.sh
# 添加如下内容
export JAVA_HOME=/opt/software/jdk1.8.0_152
# 如果是root用户,需要指明,如下所示
export HDFS_NAMENODE_USER=root
export HDFS_DATANODE_USER=root
export HDFS_SECONDARYNAMENODE_USER=root
export YARN_RESOURCEMANAGER_USER=root
export YARN_NODEMANAGER_USER=root
配置环境变量
# 如果使用的是普通用户需要加sudo,root用户,则不需要,后续不再赘述
sudo vi /etc/profile
# Hadoop environment variables
export HADOOP_HOME=/opt/software/hadoop-3.2.2
export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin
# 重新加载配置文件
source /etc/profile
分发配置好的Hadoop安装包
(这里我们演示的是采用root用户搭建的集群,普通用户稍稍修改即可)
# 使用$PWD时,记得先切换进相应目录(/opt/software/)
scp -r /opt/software/hadoop-3.2.2 root@kk02:$PWD
scp -r /opt/software/hadoop-3.2.2 root@kk03:$PWD
# 如果其他节点没有jdk记得也要分发
scp -r /opt/software/jdk1.8.0_152 root@kk02:$PWD
scp -r /opt/software/jdk1.8.0_152 root@kk03:$PWD
#分发配置文件
scp /etc/profile root@kk02:/etc/profile
scp /etc/profile root@kk03:/etc/profile
# 在被分发节点上执行
source /etc/profile
rsync主要用于备份和镜像。具有速度快、避免复制相同内容和支持符号链接的优点。
rsync和scp区别:用rsync做文件的复制要比scp的速度快,rsync只对差异文件做更新。scp是把所有文件都复制过去。
基本语法
rsyns -av 待拷贝文件路径/名称 目的主机用户@主机名:目的地路径/名称
# 参数说明
# -a 归档拷贝
# -v 显示拷贝过程
下面演示使用普通用户分到普通用户
rsync -av /opt/software/hadoop-3.2.2 nhk@kk02:/opt/software/
rsync -av /opt/software/hadoop-3.2.2 nhk@kk03:/opt/software/
rsync -av /opt/software/jdk1.8.0_152 nhk@kk02:/opt/software/
rsync -av /opt/software/jdk1.8.0_152 nhk@kk03:/opt/software/
# 为了方便分发,我们可以编写脚本 (可选)
vim xsync
#!/bin/bash
#1. 判断参数个数
if [ $# -lt 1 ]
then
echo Not Enough Arguement!
exit;
fi
#2. 遍历集群所有机器
for host in kk01 kk02 kk03
do
echo ==================== $host ====================
#3. 遍历所有目录,挨个发送
for file in $@
do
#4. 判断文件是否存在
if [ -e $file ]
then
#5. 获取父目录
pdir=$(cd -P $(dirname $file); pwd)
#6. 获取当前文件的名称
fname=$(basename $file)
ssh $host "mkdir -p $pdir"
rsync -av $pdir/$fname $host:$pdir
else
echo $file does not exists!
fi
done
done
# 让脚本具有可执行权限
chmod +x xsync
# 将脚本复制到/bin,以便全局调用
sudo cp xsync /bin/ # 普通用户需sudo
# 同步环境变量
[nhk@kk01 ~]$ sudo ./bin/xsync # 普通用户情况下
# 注意:如果用了sudo,那么xsync一定要给它的路径补全。
# 让环境变量生效
source /etc/profile
# 使用自定义脚本分发
xsync /opt/software/hadoop-3.2.2/
HDFS格式化
首次启动HDFS时,必须对其进行格式化操作。本质上是一些清理和准备工作,因为此时的HDFS在物理上还是不存在的。
cd /opt/software/hadoop-3.1.4
bin/hdfs namenode -format
# 因为我们配置了环境变量,其实格式化操作也可以简化为如下操作:
hdfs namenode -format
# 若出现 successfully formatted 字样则说明格式化成功
集群启动
# HDFS集群启动
start-dfs.sh
# YARN集群启动
start-yarn.sh
web端查看HDFS的NameNode
http://kk01:9870
Web端查看YARN的ResourceManager
http://kk01:8088
编写hadoop集群常用脚本
Hadoop集群启停脚本
vim hdp.sh
#!/bin/bash
if [ $# -lt 1 ]
then
echo "No Args Input..."
exit ;
fi
case $1 in
"start")
echo " =================== 启动 hadoop集群 ==================="
echo " --------------- 启动 hdfs ---------------"
ssh kk01 "/opt/software/hadoop-3.2.2/sbin/start-dfs.sh"
echo " --------------- 启动 yarn ---------------"
ssh kk01 "/opt/software/hadoop-3.2.2/sbin/start-yarn.sh"
echo " --------------- 启动 historyserver ---------------"
ssh kk01 "/opt/software/hadoop-3.2.2/bin/mapred --daemon start historyserver"
;;
"stop")
echo " =================== 关闭 hadoop集群 ==================="
echo " --------------- 关闭 historyserver ---------------"
ssh kk01 "/opt/software/hadoop-3.2.2/bin/mapred --daemon stop historyserver"
echo " --------------- 关闭 yarn ---------------"
ssh kk01 "/opt/software/hadoop-3.2.2/sbin/stop-yarn.sh"
echo " --------------- 关闭 hdfs ---------------"
ssh kk01 "/opt/software/hadoop-3.2.2/sbin/stop-dfs.sh"
;;
*)
echo "Input Args Error..."
;;
esac
# 赋予脚本执行权限
chmod +x hdp.sh
查看三台服务器Java进程脚本:jpsall
vim jpsall
#!/bin/bash
for host in kk01 kk02 kk03
do
echo "=========$host========="
ssh $host "source /etc/profile; jps"
done
# 赋予脚本执行权限
chmod +x jpsall
分发自定义脚本,让三台服务器都能正常使用脚本
xsync 脚本放置的目录
搭建集群注意事项常见问题
如果使用root用户操作的话,需要在hadoop-env.sh文件下加入以下配置
在hadoop-env.sh文件下添加一下信息
export HDFS_NAMENODE_USER="root"
export HDFS_DATANODE_USER="root"
export HDFS_SECONDARYNAMENODE_USER="root"
export YARN_RESOURCEMANAGER_USER="root"
export YARN_NODEMANAGER_USER="root"
使用root操作,需要再core-site.xml文件,修改以下配置
<!-- Web UI访问HDFS的用户名-->
<!-- 配置HDFS登录使用的静态用户为root -->
<property>
<name>hadoop.http.staticuser.user</name>
<value>root</value>
</property>
防火墙未关闭、或者没有启动YARN
INFO client.RMProxy:Connecting to ResourceManager at kk01/192.168.188.128:8032
解决:
在/etc/hosts文件中添加192.168.188.128 kk01
主机名称配置错误
解决:
更改主机名,主机名称不要起hadoop hadoop000等特殊名称
不识别主机名称
java.net.UnknownHostException: kk01: kk01
at java.net.InetAddress.getLocalHost(InetAddress.java:1475)
at org.apache.hadoop.mapreduce.JobSubmitter.submitJobInternal(JobSubmitter.java:146)
at org.apache.hadoop.mapreduce.Job$10.run(Job.java:1290)
at org.apache.hadoop.mapreduce.Job$10.run(Job.java:1287)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAs(Subject.java:415)
解决:
在/etc/hosts文件中添加192.168.188.128 kk01
主机名称不要起hadoop hadoop000等特殊名称
DataNode和NameNode进程同时只能工作一个
解决:
在格式化之前,先删除DataNode里面的信息(默认在/tmp目录,如果配置了该目录,那就去配置的目录下删除数据)
jps发现进程已经没有,但是重新启动集群,提示进程已经开启
解决:
原因是在Linux的根目录下/tmp目录中存在启动的进程临时文件,将集群相关进程删除掉,再重新启动集群。
jps不生效
解决:
原因:全局变量hadoop java没有生效。解决办法:需要source /etc/profile文件。
8088端口连接不上
解决:
cat /etc/hosts
# 注释掉如下信息
#127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
#::1 kk01
Hadoop集群总结
- format操作只在hadoop集群初次启动时执行一次
- format多次会造成我们数据的丢失,还可能会造成Hadoop集群主从角色之间相互不识别(解决方法:将所以节点的hadoop.tmp.dir目录删除,删除所有机器的data和logs目录删除,后重新格式化)
Hadoop集群启动关闭
每台机器手动逐个开启/关闭进程
优点:利于精准的控制每一个进程的开启和关闭
HDFS集群
hdfs --daemon start namenode|datanode|secondarynamenode
hdfs --daemon stop namenode|datanode|secondarynamenode
YARN集群
yarn --daemon start resourcemanager|nodemanager
yarn --daemon stop resourcemanager|nodemanager
shell脚本一键启停
使用Hadoop自带的shell脚本一键启动
前提:配置好机器之间的ssh免密登录和workers文件
HDFS集群
start-dfs.sh
stop-dfs.sh
YARN集群
start-yarn.sh
stop-yarn.sh
Hadoop集群
start-all.sh
stop-all.sh
Hadoop集群启动日志
启动完成后,可以使用jps命令查看进程是否启动
若发现某些进程无法正常启动或者是启动后又闪退,可以查看logs目录下的日志文件(.log)查看
hadoop启动日志:日志路径:在Hadoop安装目录下的logs目录下
HDFS基准测试
实际生产环境当中,hadoop的环境搭建完成之后,第一件事情就是进行压力测试,测试Hadoop集群的读取和写入速度,测试网络带宽是否足够等一些基准测试。
测试写入速度
向HDFS文件系统中写入数据,10个文件,每个文件10MB,文件存放到/benchmarks/TestDFSIO中
# 启动Hadoop集群
start-all.sh
# 在确保HDFS集群和YARN集群成功启动情况下,执行下面命令
hadoop jar /opt/software/hadoop-3.2.2/share/hadoop/mapreduce/hadoop-mapreduce-client-jobclient-3.2.2-tests.jar TestDFSIO -write -nrFiles 10 -fileSize 10MB
# 说明:向HDFS文件系统中写入数据,10个文件,每个文件10MB,文件存放到/benchmarks/TestDFSIO中
Throughput:吞吐量、Average IO rate:平均IO率、IO rate std deviation:IO率标准偏差
2023-04-01 11:12:56,880 INFO fs.TestDFSIO: ----- TestDFSIO ----- : write
2023-04-01 11:12:56,880 INFO fs.TestDFSIO: Date & time: Sat Apr 01 11:12:56 EDT 2023
2023-04-01 11:12:56,880 INFO fs.TestDFSIO: Number of files: 10
2023-04-01 11:12:56,880 INFO fs.TestDFSIO: Total MBytes processed: 100
2023-04-01 11:12:56,880 INFO fs.TestDFSIO: Throughput mb/sec: 4.81
2023-04-01 11:12:56,880 INFO fs.TestDFSIO: Average IO rate mb/sec: 7.58
2023-04-01 11:12:56,880 INFO fs.TestDFSIO: IO rate std deviation: 7.26
2023-04-01 11:12:56,880 INFO fs.TestDFSIO: Test exec time sec: 34.81
2023-04-01 11:12:56,880 INFO fs.TestDFSIO:
我们看到目前在虚拟机上的IO吞吐量约为:4.81MB/s
测试读取速度
测试hdfs的读取文件性能,在HDFS文件系统中读入10个文件,每个文件10M
hadoop jar /opt/software/hadoop-3.2.2/share/hadoop/mapreduce/hadoop-mapreduce-client-jobclient-3.2.2-tests.jar TestDFSIO -read -nrFiles 10 -fileSize 10MB
# 说明:在HDFS文件系统中读入10个文件,每个文件10M
Throughput:吞吐量、Average IO rate:平均IO率、IO rate std deviation:IO率标准偏差
2023-04-01 11:16:44,479 INFO fs.TestDFSIO: ----- TestDFSIO ----- : read
2023-04-01 11:16:44,479 INFO fs.TestDFSIO: Date & time: Sat Apr 01 11:16:44 EDT 2023
2023-04-01 11:16:44,479 INFO fs.TestDFSIO: Number of files: 10
2023-04-01 11:16:44,479 INFO fs.TestDFSIO: Total MBytes processed: 100
2023-04-01 11:16:44,479 INFO fs.TestDFSIO: Throughput mb/sec: 33.8
2023-04-01 11:16:44,479 INFO fs.TestDFSIO: Average IO rate mb/sec: 93.92
2023-04-01 11:16:44,479 INFO fs.TestDFSIO: IO rate std deviation: 115.03
2023-04-01 11:16:44,479 INFO fs.TestDFSIO: Test exec time sec: 25.72
2023-04-01 11:16:44,479 INFO fs.TestDFSIO:
可以看到读取的吞吐量为:33.8Mb/s
清除测试数据
测试期间,会在HDFS集群上创建 /benchmarks目录,测试完毕后,我们可以清理该目录。
# 查看
hdfs dfs -ls -R /benchmarks
# 执行清理
hadoop jar /opt/software/hadoop-3.2.2/share/hadoop/mapreduce/hadoop-mapreduce-client-jobclient-3.2.2-tests.jar TestDFSIO -clean
# 说明 删除命令会将 /benchmarks目录中内容删除