【版本】
当前版本号v20230608
版本 | 修改说明 |
---|---|
v20230608 | 新增常见问题 |
v20230605 | 新增步骤修改authorized_keys文件的权限,避免无法实现免密登录的问题 |
v20220413 | 修改为 Hadoop 3 |
v20210516 | 初始化版本 |
【实验名称】
实验2 - 部署 Hadoop 完全分布模式
【实验目的】
- 掌握搭建 Hadoop 完全分布模式
- 熟练掌握Linux命令(vi、tar、mv等等)的使用
- 掌握VirtualBox、FinalShell等客户端的使用
【实验环境】
- 内存:至少4G
- 硬盘:至少空余40G
- 操作系统: 64位 Windows系统。
【实验资源】
- FinalShell
- CentOS 7
- VirtualBox
- Hadoop 3 安装包 资源下载
【实验内容】
- 完成模板机的克隆
- 完成Hadoop 完全分布模式的部署
【实验步骤】
克隆模板机
- 关闭 Part1 完成的 HadoopTmpl 模板机。依次克隆出3台虚拟机,名称,主机名和 IP 地址如下表所示,注意替换为你的学号后3位。
虚拟机名称 | hostname | IP地址 |
---|---|---|
节点A主机(Namenode) | nodea+你学号后3位 | 10.0.0.71 |
节点B主机(Datanode) | nodeb+你学号后3位 | 10.0.0.72 |
节点C主机(Datanode) | nodec+你学号后3位 | 10.0.0.73 |
依次启动克隆的虚拟机,修改为对应的 hostname 和 IP。以下以
节点A主机(Namenode)
为例。使用
hadoop
用户登录节点A,密码为123456
。修改 hostname。
sudo vim /etc/hostname
- 修改为
nodea+你学号后3位
如果你学号是123,则命名为
nodea123
,相应的节点B和节点C分别命名为nodeb123
和nodec123
。
- 修改 IP。
sudo vim /etc/sysconfig/network-scripts/ifcfg-enp0s3
- 修改`IPADDR=“10.0.0.71”
- 重启克隆的3台虚拟机,配置 FinalShell 分别连接3台虚拟机,使用
hadoop
用户登录,密码为123456
,测试是否能够正常登录。
配置免密登录
免密登录,顾名思义就是不需要输入密码即可登录。免密登录的大致原理,就是在客户端 client 生成一对密钥(包括公钥和私钥),然后将公钥传到服务器 server。当 client 通过 ssh 登录 server 时,不用再输入密码就能直接登进去,这就是 ssh 免密登录。
Hadoop 的 NameNode 是通过SSH 来启动和停止各个节点上的各种守护进程的,这就需要在节点之间执行指令的时候是不需要输入密码的方式,故我们需要配置SSH使用免密登录。
注意此阶段命令如无特殊说明,均在 NodeA 的 hadoop 用户下执行!
- 使用 Hadoop 用户登录 NodeA 节点。如果使用root登录的可以使用以下命令切换到hadoop用户。
su hadoop
- 使用 ping 命令检查是否能够连通 NodeB 和 NodeC。
ping nodeb+你学号后3位 -c 3
ping nodec+你学号后3位 -c 3
- 正常情况下应该有类似返回信息如下:
64 bytes from nodeb (10.0.0.72): icmp_seq=1 ttl=64 time=0.373 ms
- 如果没有看到以上返回消息,请检查
/etc/hosts
是否修改正确,参考 Part1 步骤55。
- 配置免密登录。首先生成密钥对,运行以下命令。直接回车(Enter)3次。
ssh-keygen -t rsa
- 在返回的对话文字中,直接回车(Enter)3次,输出内容类似以下。
Generating public/private rsa key pair.
Enter file in which to save the key (/home/hadoop/.ssh/id_rsa):
Created directory '/home/hadoop/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/hadoop/.ssh/id_rsa.
Your public key has been saved in /home/hadoop/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:MSUbr5VaCY4KSpsCM0l8uhYWkr5R9iNI05SFuF00jLA hadoop@nodea999
The key's randomart image is:
+---[RSA 2048]----+
|.+=.B+ + . |
|+B.O o.o B o |
|OE% o . = * |
|o%o+ + B |
|+o= o . S |
|.+ |
|. |
| |
| |
+----[SHA256]-----+
- 查看目录下是否有公钥
id_rsa.pub
和私钥id_rsa
。
cd ~/.ssh
ls
- 可以看到以下2个文件。其中
id_rsa
是私钥,id_rsa.pub
是公钥。
id_rsa id_rsa.pub
- 执行以下命令,把公钥写入本机授权文件。
cat id_rsa.pub >> authorized_keys
- 查看授权文件内的公钥内容。
cd ~/.ssh
cat authorized_keys
- 可以看到类似以下内容
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC1Df9cM8NVGURMj3I86EoiO4Jy6LuuHOc+MC3vnZPJX9ISSXDZ9Qx+a5CCdoZJyySG3IlvAFBLv2Wnv60tDZ9xHEQ0WbkAV/IeDrdRk1OI51/bEGfdPqTLBtic1eXsFC6luc7kbQYuxQRoeovl2UwHNgzAX/xTyUV0uAuvTeggyGWq05I9OiantybrumNUJO8gFO3R9CA/zvNrJbuvVDKT9AAqQpn57jDsHkTiAlGoubKUcgAWy1EbYk7hVCL1gFkMcxDMvSOBoY23oqEFSNrkuho2Cj2fNUinaDNDPPzoqbDwvU9IUCGhgfiNYb4Ub/hoabJRjlcNiEgoD+G79lNd hadoop@nodea你的学号后3位
- 修改 authorized_keys 的权限为400,让
NodeA
能够免密登录自身。
chmod 400 authorized_keys
ls -al authorized_keys
- 使用
hadoop
用户在NodaB
和NodeC
分别运行以下命令。该命令目的是打开写的权限,允许NodaA
把公钥写入NodeB
和NodeC
。
chmod 777 ~/.ssh/authorized_keys
- 确认
NodeB
和NodeC
2个节点都已经启动。在NodaA
上面运行以下命令,把公钥拷贝到NodeB
和NodeC
。
ssh-copy-id -i ~/.ssh/id_rsa.pub nodeb+你学号后3位 -f
ssh-copy-id -i ~/.ssh/id_rsa.pub nodec+你学号后3位 -f
- 系统询问是否连接,输入yes
Are you sure you want to continue connecting (yes/no)? yes
- 输入 hadoop 登录密码
hadoop@nodeb你学号后3位's password:
- 使用
hadoop
用户在NodaB
和NodeC
分别运行以下命令,关闭写入权限。
chmod 400 ~/.ssh/authorized_keys
- 使用以下方法测试免密登录是否配置成功,在NodeA上面分别 SSH 登录
NodeA
、NodeB
、NodeC
。
- 例如:在 NodeA 执行以下命令,使用 SSH 协议登录 NodeB。
ssh hadoop@nodeb+你的学号后3位
- 如果能够成功登录 NodeB 节点,而且不需要输入密码,则表示免密登录成功。输入以下命令退出登录。
exit
修改 Hadoop 配置文件
注意此阶段命令如无特殊说明,均在 NodeA 的 hadoop 用户下执行!
- 备份和编辑 Hadoop 的 core-site.xml 配置文件。在configuration 标签内添加配置,注意替换为你的学号后3位。
cp /opt/hadoop/etc/hadoop/core-site.xml{,.bak}
vim /opt/hadoop/etc/hadoop/core-site.xml
<configuration>
<!-- HDFS 访问地址 -->
<property>
<name>fs.defaultFS</name>
<value>hdfs://nodea+你学号后3位:8020</value>
</property>
<property>
<name>hadoop.tmp.dir</name>
<value>/opt/hadoop/tmp</value>
</property>
<property>
<name>fs.trash.interval</name>
<value>1440</value>
</property>
<property>
<name>hadoop.http.staticuser.user</name>
<value>hadoop</value>
</property>
</configuration>
- 备份和编辑 Hadoop 的 hdfs-site.xml 配置文件。请注意替换为你的学号。
cp /opt/hadoop/etc/hadoop/hdfs-site.xml{,.bak}
vim /opt/hadoop/etc/hadoop/hdfs-site.xml
<configuration>
<!-- secondary namenode 访问地址-->
<property>
<name>dfs.secondary.http.address</name>
<value>nodea+你学号后3位:50090</value>
</property>
<!-- HDFS 副本数量 -->
<property>
<name>dfs.replication</name>
<value>2</value>
</property>
</configuration>
- 新建一个 masters 配置文件,写入 Secondary NameNode 的主机名。
vim /opt/hadoop/etc/hadoop/masters
写入以下内容,注意替换为你的学号后3位。
nodea+你的学号后3位
- 备份和编辑 Hadoop 的 mapred-site.xml 配置文件。注意替换为你的学号后3位。
cp /opt/hadoop/etc/hadoop/mapred-site.xml{,.bak}
vim /opt/hadoop/etc/hadoop/mapred-site.xml
<configuration>
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
<property>
<name>mapreduce.jobhistory.address</name>
<value>nodea+你学号后3位:10020</value>
<description>Host and port for Job History Server (default 0.0.0.0:10020)</description>
</property>
<property>
<name>mapreduce.application.classpath</name>
<value>$HADOOP_HOME/share/hadoop/mapreduce/*,$HADOOP_HOME/share/hadoop/mapreduce/lib/*,$HADOOP_HOME/share/hadoop/common/*,$HADOOP_HOME/share/hadoop/common/lib/*,$HADOOP_HOME/share/hadoop/yarn/*,$HADOOP_HOME/share/hadoop/yarn/lib/*,$HADOOP_HOME/share/hadoop/hdfs/*,$HADOOP_HOME/share/hadoop/hdfs/lib/*</value>
</property>
</configuration>
- 备份和编辑 Hadoop 的 yarn-site.xml 配置文件。注意替换为你的学号后3位。
cp /opt/hadoop/etc/hadoop/yarn-site.xml{,.bak}
vim /opt/hadoop/etc/hadoop/yarn-site.xml
<configuration>
<property>
<name>yarn.resourcemanager.hostname</name>
<value>nodea+你学号后3位</value>
</property>
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
</configuration>
- 编辑 workers ,清除原来的所有内容,增加配置 DataNode 节点信息。注意替换为你的学号后3位。
vim /opt/hadoop/etc/hadoop/workers
nodeb+你学号后3位
nodec+你学号后3位
从Hadoop 3.0 开始,slaves 已经启用,改用 workers 来进行替代配置数据节点信息。
- 修改 hadoop-env.sh,在第1行加入以下代码。
vim /opt/hadoop/etc/hadoop/hadoop-env.sh
export JAVA_HOME=/opt/jdk8
- 把
NodeA
节点的 Hadoop /opt/hadoop/etc/hadoop 下所有配置文件发送到NodeB
和NodeC
。如果上面的配置文件有修改,也需要同步发送到NodeB
和NodeC
节点。
cd /opt/hadoop/etc/
scp -r hadoop hadoop@nodeb+你学号后3位:/opt/hadoop/etc/
scp -r hadoop hadoop@nodec+你学号后3位:/opt/hadoop/etc/
- 格式化 HDFS。
注意此命令请勿重复执行,因为会导致 DataNode 和 NameNode 的集群ID不一致,造成HDFS出错。
hdfs namenode -format
- 在输出的内容中,如果能看到以下这句信息,说明格式化成功。
2022-01-24 14:32:54,209 INFO common.Storage: Storage directory /opt/hadoop/tmp/dfs/name has been successfully formatted.
- 创建 Hadoop 启动脚本,注意替换为你的学号后3位。
vim /opt/hadoop/sbin/start-hdp.sh
#!/usr/bin/env bash
echo "Start Hadoop by 你的学号后3位"
start-dfs.sh
start-yarn.sh
mapred --daemon start historyserver
- 创建 Hadoop 停止脚本,注意替换为你的学号后3位。
vim /opt/hadoop/sbin/stop-hdp.sh
#!/usr/bin/env bash
echo "Stop Hadoop by 你的学号后3位"
mapred --daemon stop historyserver
stop-yarn.sh
stop-dfs.sh
- 创建 Hadoop 重启脚本,注意替换为你的学号后3位。
vim /opt/hadoop/sbin/restart-hdp.sh
#!/usr/bin/env bash
stop-hdp.sh
start-hdp.sh
- 修改创建的脚本的权限。
cd /opt/hadoop/sbin/
chmod 744 start-hdp.sh stop-hdp.sh restart-hdp.sh
- 使用脚本启动 Hadoop。
start-hdp.sh
验证免密登录
- 在
NodeB
和NodeC
2个节点分别执行以下命令,查看是否包含来自NodeA
的公钥。
cd ~/.ssh
cat authorized_keys
验证时间是否同步
- 在
NodeB
和NodeC
2个节点分别执行以下命令,查看时间是否与NodeA
同步。
date
如果时间不同步,可以执行以下语句,尝试强制同步时间。
chronyc -a makestep
验证 Hadoop 是否正常启动
- 在
NodeA
输入jps
命令,观察是否有以下进程。
jps
- 正常应该有类似以下信息返回:
NameNode
Jps
ResourceManager
SecondaryNameNode
JobHistoryServer
- 在
NodeA
输入以下命令查看机架拓扑是否有NodeB
和NodeC
的信息
hdfs dfsadmin -printTopology
- 正常应该有类似以下信息返回:
Rack: /default-rack
10.0.0.72:9866 (nodeb你的学号后3位)
10.0.0.73:9866 (nodec你的学号后3位)
- 在
NodeB
和NodeC
分别输入jps
命令,观察是否有以下进程。
jps
- 正常应该有类似以下信息返回:
DataNode
NodeManager
Jps
验证 HDFS 是否正常工作
打开宿主机浏览器,访问 HDFS Web界面 http://10.0.0.71:9870/
查看 NameNode 是否 Active
查看2个节点 DataNode 服务状态是否正常。
上传
countryroad.txt
到NodeA
的/home/hadoop
把
countryroad.txt
从 CentOS 文件系统上传到 HDFS 文件系统。
hdfs dfs -mkdir /part2
hdfs dfs -put /home/hadoop/countryroad.txt /part2
hdfs dfs -ls /part2
验证 MapReduce 是否正常工作
- 运行 Hadoop 自带的 Wordcount 程序,观察输出的内容。
cd $HADOOP_HOME/share/hadoop/mapreduce
hadoop jar hadoop-mapreduce-examples-3.3.1.jar wordcount /part2/countryroad.txt /output
- 如果输出的日志内容包含类似以下信息,则表示执行成功
2022-01-24 15:48:51,712 INFO mapreduce.Job: Job job_xxxxxxx completed successfully
- 程序执行过程中,可以访问 Yarn Web 界面查看任务进展。http://10.0.0.71:8088/cluster/apps
- 等待程序运行完毕,观察输出的内容
hdfs dfs -cat /output/part-r-00000
【常见问题】
1. NodeA
节点NameNode
或SecondaryNameNode
无法启动。并且日志提示“/opt/hadoop/tmp/dfs/namesecondary is in an inconsistent state”。
答:可能是因为多次格式化或者配置文件没有同步导致的错误。
- (1) 首先把
NodeA
节点的 Hadoop /opt/hadoop/etc/hadoop 下所有配置文件发送到NodeB
和NodeC
。
cd /opt/hadoop/etc/
scp -r hadoop hadoop@nodeb+你学号后3位:/opt/hadoop/etc/
scp -r hadoop hadoop@nodec+你学号后3位:/opt/hadoop/etc/
- (2) 删除/opt/hadoop/tmp 下的所有内容。
- (3) 再次执行 HDFS 格式化。
hdfs namenode -format
2. Hadoop 执行 MapReduce 任务失败,并且日志伴有“Note: System times on machines may be out of sync. Check system time and time zones.”
答:可能是由于虚拟机节点之间的时间不同步导致的。
- (1) 在
NodeB
和NodeC
执行以下语句,尝试强制与NodeA
同步时间。
chronyc -a makestep
- (2) 重启 Hadoop。
3. HDFS 命令执行出现 SLF4J 错误,显示以下信息。
SLF4J: Failed to load class “org.slf4j.impl.StaticLoggerBinder”.
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
答:
- (1) 请下载 slf4j-nop-1.7.36.jar 包,放到
/opt/hadoop/share/hadoop/common/lib
下。可以通过以下 Maven 来下载,下载好的包会放在Maven本地仓库\org\slf4j\slf4j-nop\1.7.36
下。
mvn dependency:get -DgroupId=org.slf4j -DartifactId=slf4j-nop -Dversion=1.7.36
- (2) 重启 Hadoop。