简介:这份资源面向大数据入门学习者与高校云计算课程学生,提供在Ubuntu系统上从零搭建Hadoop分布式环境的完整教程,覆盖虚拟机安装、SSH免密登录、共享文件夹挂载、JDK环境配置、Hadoop安装与参数调优、环境变量设置等关键环节,帮助读者构建可运行的大数据处理平台。压缩包共93个文件,约222.16MB,包含xml与iml工程配置、class与java源码、jar依赖包、png操作截图、docx与doc实验报告及txt说明文档,并附赠Cloud-Computing-course-design-master课程设计项目,内含InvertedIndex、MatrixMultiply、Dijkstra、SecondarySort等实验案例与数据。已有112人学习下载。读者可借助分步截图与实验报告,掌握集群节点通信、HDFS存储与Java环境配置方法,同时获得课程设计参考与排错思路,适合初学者按图索骥,也便于有经验开发者查漏补缺。
1. 从一台裸 Ubuntu 虚拟机到能跑 MapReduce 的 Hadoop 平台:这套流程到底在解决什么
很多人第一次接触大数据,卡住的地方不是 MapReduce 编程,也不是 HDFS 原理,而是环境根本跑不起来。你手上只有一台刚装好的 Ubuntu 虚拟机,网络能通、终端能敲命令,但 Hadoop 的安装包解压完,start-dfs.sh一执行就报JAVA_HOME is not set,或者 SSH 连本机还要输密码,NameNode 直接起不来。这套「Ubuntu + 虚拟机 + SSH 免密 + 共享文件夹 + JDK + Hadoop」的搭建流程,解决的就是从零到「伪分布式集群能正常启动、Web UI 能打开、能提交一个 WordCount 任务」这一段路。
它适合三类人:一是大数据课程设计要交作业的学生,二是刚转行想在自己电脑上把 Hadoop 跑通再去看面试题的开发者,三是需要一套可反复重建的实验环境、不想每次重装都翻旧笔记的工程师。核心思路很朴素:用虚拟机隔离出一台干净的 Ubuntu,把主机和虚拟机之间的文件通道打通,再把 JDK 和 Hadoop 的依赖关系、环境变量、SSH 信任链一次性配到位。下面按真实搭建顺序拆开讲,每一步都给出可复制的命令和参数含义。
2. 虚拟机装 Ubuntu 与共享文件夹挂载:先把「地基」和「文件通道」铺好
2.1 虚拟机选型与 Ubuntu 版本选择
虚拟机软件常见的是 VMware Workstation 和 VirtualBox,两者都能满足 Hadoop 伪分布式搭建。我一般用 VMware,原因是共享文件夹挂载在 Linux 端更省事,vmhgfs-fuse挂载后路径稳定,不容易出现重启掉盘。Ubuntu 版本建议选 22.04 LTS,长期支持、软件源稳定,社区里针对 22.04 的 Hadoop 踩坑记录也最多,遇到问题好搜。内存分配上,伪分布式至少给 4GB,低于这个数 NameNode 和 DataNode 同时跑容易 OOM;磁盘给 40GB 以上,HDFS 副本虽然伪分布式只存一份,但日志和临时文件会持续增长。
安装时有一个容易忽略的点:虚拟机网络模式。NAT 模式下虚拟机能上网,但主机访问虚拟机的 Web UI 需要端口转发;桥接模式则虚拟机和主机在同一网段,直接用虚拟机 IP 就能访问 9870 端口。做 Hadoop 实验我推荐桥接,省去端口映射的麻烦。安装过程中设置的用户名不要用hadoop以外的特殊字符,后面 SSH 和权限配置会少很多事。
2.2 共享文件夹挂载的完整命令与 fstab 持久化
共享文件夹的作用是把主机上的 JDK 压缩包、Hadoop 安装包、数据集直接拖进虚拟机,不用每次用 U 盘或 scp 来回传。VMware 里先在虚拟机设置中启用共享文件夹,指定主机目录,比如D:\bigdata_share,名称设为share。进入 Ubuntu 后执行挂载:
# 安装 VMware Tools 提供的挂载工具,若已安装可跳过 sudo apt update sudo apt install open-vm-tools open-vm-tools-desktop -y # 创建挂载点 sudo mkdir -p /mnt/hgfs/share # 手动挂载共享文件夹 sudo vmhgfs-fuse .host:/share /mnt/hgfs/share -o allow_other -o uid=1000 -o gid=1000 # 验证挂载结果 ls /mnt/hgfs/shareallow_other让非 root 用户也能访问挂载目录,uid=1000和gid=1000对应 Ubuntu 默认第一个用户的 UID/GID,这样当前用户读写共享文件不会出现权限拒绝。如果vmhgfs-fuse命令不存在,说明 open-vm-tools 没装好,先确认软件包状态。
手动挂载重启后会失效,写入/etc/fstab实现开机自动挂载:
# 编辑 fstab,追加一行 echo '.host:/share /mnt/hgfs/share fuse.vmhgfs-fuse allow_other,uid=1000,gid=1000,defaults 0 0' | sudo tee -a /etc/fstab # 测试 fstab 配置是否正确,不重启验证 sudo mount -amount -a不报错说明配置有效。这里有个血泪经验:fstab 写错会导致系统启动进入 emergency mode,所以改完一定先mount -a验证,别直接重启。共享文件夹挂载好之后,后面 JDK 和 Hadoop 的安装包直接从/mnt/hgfs/share拷贝到/opt或用户目录,效率高很多。
2.3 主机名与 hosts 映射配置
Hadoop 集群内部节点之间通过主机名通信,伪分布式虽然只有一台机器,但 NameNode 注册、DataNode 上报都会用到主机名。先设置主机名:
# 设置主机名为 hadoop01 sudo hostnamectl set-hostname hadoop01 # 编辑 hosts 文件,建立主机名与 IP 的映射 sudo tee -a /etc/hosts <<EOF 192.168.1.100 hadoop01 EOF192.168.1.100换成你虚拟机实际的 IP,用ip addr查看。hosts 映射不做的话,后面start-dfs.sh启动时会出现Connection refused或者 NameNode 一直处于 safe mode,因为 Hadoop 解析主机名失败。这一步是很多教程跳过但实际必做的,配置 host 映射与 SSH 免密登录要放在一起做,顺序不能反。
3. SSH 免密登录与 JDK 环境配置:把 Hadoop 的依赖链打通
3.1 SSH 免密登录的原理与三步配置
Hadoop 的启动脚本start-dfs.sh和stop-dfs.sh会在本地通过 SSH 连接到 NameNode 和 DataNode 所在节点执行命令。伪分布式下就是连本机,但如果不配免密,每启动一次就要输好几次密码,脚本还会因为等待输入而卡住。免密登录的原理是:本机生成一对密钥,把公钥追加到目标机器的~/.ssh/authorized_keys文件,之后 SSH 连接时用私钥验证,不再需要密码。
配置步骤:
# 1. 生成 RSA 密钥对,-t 指定算法,-P 指定空密码,-f 指定密钥文件路径 ssh-keygen -t rsa -P '' -f ~/.ssh/id_rsa # 2. 将公钥追加到本机的授权文件 cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys # 3. 设置权限,SSH 对权限要求严格,权限不对免密会失效 chmod 700 ~/.ssh chmod 600 ~/.ssh/authorized_keys # 4. 测试免密登录 ssh hadoop01-P ''表示私钥不设密码,这是 Hadoop 自动化脚本的要求,设了密码反而会导致脚本卡在密码输入。chmod 700和chmod 600是必须的,SSH 会检查~/.ssh目录和authorized_keys文件的权限,如果组用户或其他用户有写权限,SSH 会拒绝使用该密钥,表现为免密配置了但还是要输密码。测试时ssh hadoop01能直接进入不需要密码,说明配置成功,exit退出。
3.2 JDK 安装与环境变量设置
Hadoop 3.x 依赖 JDK 8 或 JDK 11,推荐 JDK 8,兼容性最好。从共享文件夹拷贝 JDK 压缩包到/opt目录:
# 拷贝 JDK 安装包到 /opt sudo cp /mnt/hgfs/share/jdk-8uXXX-linux-x64.tar.gz /opt/ # 解压 cd /opt sudo tar -zxvf jdk-8uXXX-linux-x64.tar.gz # 重命名目录,方便后续引用 sudo mv jdk1.8.0_XXX jdk8jdk-8uXXX中的 XXX 换成你实际下载的小版本号。解压后目录名带版本号,重命名为jdk8是为了环境变量路径固定,以后换小版本不用改配置。
环境变量配置有两种方式:修改/etc/profile全局生效,或修改~/.bashrc当前用户生效。Hadoop 实验我一般改~/.bashrc,避免污染系统全局环境:
# 追加 JDK 环境变量 cat >> ~/.bashrc <<EOF export JAVA_HOME=/opt/jdk8 export JRE_HOME=\${JAVA_HOME}/jre export CLASSPATH=.:\${JAVA_HOME}/lib:\${JRE_HOME}/lib export PATH=\${JAVA_HOME}/bin:\${PATH} EOF # 使配置立即生效 source ~/.bashrc # 验证 java -version echo $JAVA_HOMEJAVA_HOME是 Hadoop 启动时必须读取的变量,CLASSPATH里的.表示当前目录,保证 Java 能找到当前目录下的类文件。source ~/.bashrc让配置在当前终端立即生效,新开终端会自动加载。java -version输出 1.8 版本信息,echo $JAVA_HOME输出/opt/jdk8,两个都对才算配置成功。如果java -version报 command not found,检查PATH是否包含$JAVA_HOME/bin,以及source是否执行。
3.3 Hadoop 安装与核心配置文件修改
Hadoop 从官网下载 tar.gz 包,同样拷贝到/opt解压:
sudo cp /mnt/hgfs/share/hadoop-3.x.x.tar.gz /opt/ cd /opt sudo tar -zxvf hadoop-3.x.x.tar.gz sudo mv hadoop-3.x.x hadoop sudo chown -R $USER:$USER /opt/hadoopchown把 Hadoop 目录所有权给当前用户,否则后续启动时写日志和临时文件会权限不足。Hadoop 3.x 的配置文件在$HADOOP_HOME/etc/hadoop/下,伪分布式需要改五个文件。
hadoop-env.sh指定 JAVA_HOME:
# 在 hadoop-env.sh 中找到 export JAVA_HOME 行,改为实际路径 echo 'export JAVA_HOME=/opt/jdk8' >> /opt/hadoop/etc/hadoop/hadoop-env.shcore-site.xml配置 HDFS 的默认文件系统和临时目录:
<configuration> <property> <name>fs.defaultFS</name> <value>hdfs://hadoop01:9000</value> </property> <property> <name>hadoop.tmp.dir</name> <value>/opt/hadoop/tmp</value> </property> </configuration>fs.defaultFS指定 NameNode 的通信地址,hadoop01是前面配的主机名,9000 是 NameNode 端口。hadoop.tmp.dir是 Hadoop 运行时临时目录,默认在/tmp下,系统重启可能被清理,导致 NameNode 元数据丢失,所以显式指定到/opt/hadoop/tmp。
hdfs-site.xml配置副本数和 NameNode/DataNode 数据目录:
<configuration> <property> <name>dfs.replication</name> <value>1</value> </property> <property> <name>dfs.namenode.name.dir</name> <value>/opt/hadoop/data/namenode</value> </property> <property> <name>dfs.datanode.data.dir</name> <value>/opt/hadoop/data/datanode</value> </property> </configuration>伪分布式只有一台机器,dfs.replication必须设为 1,设成 3 会一直提示副本不足。dfs.namenode.name.dir和dfs.datanode.data.dir分别指定元数据和块数据的存储路径,提前建好目录并确保当前用户有写权限。
mapred-site.xml指定 MapReduce 运行框架:
<configuration> <property> <name>mapreduce.framework.name</name> <value>yarn</value> </property> </configuration>yarn-site.xml配置 YARN 的 ResourceManager 和 NodeManager:
<configuration> <property> <name>yarn.nodemanager.aux-services</name> <value>mapreduce_shuffle</value> </property> <property> <name>yarn.resourcemanager.hostname</name> <value>hadoop01</value> </property> </configuration>yarn.nodemanager.aux-services设为mapreduce_shuffle是 MapReduce 跑在 YARN 上的必要配置,少了这个 Shuffle 阶段会失败。yarn.resourcemanager.hostname指定 ResourceManager 所在主机。
最后配置 Hadoop 环境变量:
cat >> ~/.bashrc <<EOF export HADOOP_HOME=/opt/hadoop export HADOOP_CONF_DIR=\${HADOOP_HOME}/etc/hadoop export PATH=\${HADOOP_HOME}/bin:\${HADOOP_HOME}/sbin:\${PATH} EOF source ~/.bashrcHADOOP_CONF_DIR让 Hadoop 命令能找到配置文件,PATH里加入bin和sbin后,hdfs、hadoop、start-dfs.sh等命令可以直接敲,不用写全路径。
4. 避坑与排查:Hadoop 启动失败时先看这五个地方
4.1 NameNode 启动报 JAVA_HOME is not set
现象:执行start-dfs.sh后终端输出JAVA_HOME is not set,NameNode 进程没起来。原因:hadoop-env.sh里的JAVA_HOME没配,或者配的路径不对。Hadoop 启动脚本读的是hadoop-env.sh里的变量,不是~/.bashrc里的。解决:打开$HADOOP_HOME/etc/hadoop/hadoop-env.sh,找到export JAVA_HOME=那一行,改成export JAVA_HOME=/opt/jdk8,保存后重新启动。
4.2 SSH 免密配置了但还是要输密码
现象:ssh-keygen和authorized_keys都做了,ssh hadoop01仍然提示输入密码。原因:权限不对,或者 hosts 里主机名映射的 IP 和实际 IP 不一致。解决:先ls -ld ~/.ssh确认是drwx------,ls -l ~/.ssh/authorized_keys确认是-rw-------,不对就chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys。再cat /etc/hosts确认hadoop01对应的 IP 和ip addr输出一致,不一致就改 hosts。
4.3 DataNode 启动后立刻消失
现象:jps能看到 NameNode,但 DataNode 一闪而过,Web UI 上 Live Nodes 为 0。原因:dfs.datanode.data.dir指定的目录不存在或权限不足,或者多次format后 DataNode 的 clusterID 和 NameNode 不一致。解决:先确认目录存在且当前用户可写,mkdir -p /opt/hadoop/data/datanode && chown -R $USER:$USER /opt/hadoop/data。如果是 clusterID 不一致,删掉 NameNode 和 DataNode 的数据目录,重新hdfs namenode -format,再启动。注意 format 只能执行一次,多次 format 会导致 clusterID 不匹配。
4.4 Web UI 打不开 9870 端口
现象:浏览器访问http://hadoop01:9870连接超时。原因:虚拟机网络模式是 NAT,主机访问不到虚拟机端口;或者 Ubuntu 防火墙拦截。解决:确认虚拟机网络是桥接模式,ip addr拿到 IP 后直接在主机浏览器访问http://虚拟机IP:9870。如果还不行,检查防火墙sudo ufw status,临时关闭sudo ufw disable测试。生产环境不要关防火墙,实验环境可以。
4.5 共享文件夹挂载后重启失效
现象:重启 Ubuntu 后/mnt/hgfs/share目录为空。原因:手动挂载没写入 fstab,或者 fstab 里的配置有误导致挂载失败。解决:按 2.2 节的 fstab 配置写入,执行sudo mount -a验证不报错。如果 fstab 写错导致系统进 emergency mode,在 emergency 模式下用mount -o remount,rw /重新挂载根分区为可写,然后编辑/etc/fstab删掉错误行,重启。
5. 验证集群可用性与一个可复现的 WordCount 技巧
环境搭好之后,怎么确认它真的能用,而不是「进程起来了但一跑任务就挂」?我一般用三步验证:先看进程,再跑 HDFS 命令,最后提交一个 WordCount。jps应该看到 NameNode、DataNode、ResourceManager、NodeManager、SecondaryNameNode 五个进程。少任何一个都说明对应组件没起来,回到第 4 章排查。
HDFS 基础操作验证:
# 创建测试目录 hdfs dfs -mkdir -p /user/$USER/input # 上传本地文件到 HDFS echo "hello hadoop hello mapreduce" > /tmp/test.txt hdfs dfs -put /tmp/test.txt /user/$USER/input/ # 查看 HDFS 上的文件 hdfs dfs -ls /user/$USER/input/ # 查看文件内容 hdfs dfs -cat /user/$USER/input/test.txthdfs dfs -mkdir -p的-p表示递归创建目录,父目录不存在会自动建。-put把本地文件上传到 HDFS,-ls和-cat分别列出和查看。这些命令能正常执行,说明 HDFS 读写通路没问题。
跑 WordCount 用 Hadoop 自带的示例 jar:
# 提交 WordCount 任务 hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.x.x.jar wordcount /user/$USER/input /user/$USER/output # 查看输出结果 hdfs dfs -cat /user/$USER/output/part-r-00000hadoop-mapreduce-examples-3.x.x.jar的版本号要和你的 Hadoop 版本一致,在$HADOOP_HOME/share/hadoop/mapreduce/下ls能看到实际文件名。wordcount后面两个参数分别是输入目录和输出目录,输出目录必须不存在,否则任务会报Output directory already exists。任务跑完后part-r-00000里是词频统计结果,能看到hello 2、hadoop 1、mapreduce 1就说明整个 MapReduce 链路通了。
一个实用技巧:如果任务卡在map 0% reduce 0%不动,先看yarn-site.xml里yarn.nodemanager.aux-services是否配了mapreduce_shuffle,再看 NodeManager 日志$HADOOP_HOME/logs/yarn-*-nodemanager-*.log有没有报错。大部分卡住都是 Shuffle 配置缺失或者内存不够,伪分布式下把yarn.nodemanager.resource.memory-mb设成 2048 以上能解决多数内存问题。
这套环境我反复搭过很多次,最大的教训是:不要跳过 hosts 映射和权限设置,这两个地方省一步,后面要花十倍时间排查。每次重装虚拟机,我都先把共享文件夹和 SSH 免密配好,再动 JDK 和 Hadoop,顺序对了基本一次过。希望帮到你。
本文还有配套的精品资源,点击获取