简介:本资源是面向大数据初学者的入门级实验指导文档,适用于高校计算机、数据科学相关专业学生及转行学习者,旨在解决Linux环境搭建与Hadoop基础操作能力缺失的问题。文档系统覆盖三大核心环节:Windows平台下VirtualBox虚拟机安装及Ubuntu 18.04/16.04部署、20余条高频Linux命令(cd/ls/mkdir/rm/cat/tac/tar/grep等)的实操示例与验证要求、Hadoop 3.1.3伪分布式环境的全流程配置及WordCount实例运行验证。资源为单个289KB的DOCX文件,内容结构清晰,含实验目的、平台要求、分步操作指令、命令参数说明及关键截图提示,便于边学边练。目前已有980人学习下载,可作为课程实验预习材料、自学打卡手册或教师备课参考,帮助读者扎实建立大数据开发环境认知与动手能力。
1. 这不是“装个虚拟机就完事”的实验:Linux + Hadoop 伪分布式环境,是大数据实操的最小可信单元
你可能已经点开过十份“Hadoop 安装教程”,最后卡在jps不显示 DataNode、hdfs dfs -ls /报错 connection refused、或者server:9870页面上 Live Nodes 永远是 0——这不是你手速慢,而是缺了一块关键拼图:把 Linux 命令、系统级配置、Hadoop 内部状态三者拧成一股绳的闭环验证能力。本实验表面是“熟悉常用命令”,实则是构建一个可诊断、可回滚、可复现的大数据最小运行单元:Ubuntu 虚拟机(非 WSL)+ Hadoop 3.1.3 伪分布式(非单机模式)+ 全流程 Shell 操作链。它不教你怎么配集群,但教会你当start-dfs.sh启动后只有 NameNode 和 SecondaryNameNode 在跑时,第一眼该看哪三个日志、第二步该比对哪两个 UUID、第三步该删哪条路径下的哪个隐藏文件。适合正在啃《大数据技术原理与应用》类教材、用 VMware/VirtualBox 搭环境、被“格式化一次就崩一次”折磨到怀疑人生的初学者;也适合想快速捡起 Hadoop 实操手感、需要一份带血泪排错路径的工程师。这不是理论铺垫,是开机、敲命令、看日志、改配置、再验证的完整工作流。
2. 虚拟机与系统基线:为什么必须用 Ubuntu 18.04 而非 22.04,以及 VirtualBox 的三个硬性配置项
Hadoop 3.1.3 的编译和运行依赖特定版本的 glibc、OpenSSL 和 Java 运行时 ABI 兼容性。Ubuntu 22.04 默认搭载 glibc 2.35,而 Hadoop 3.1.3 编译时链接的是 glibc 2.27(Ubuntu 18.04 标准库),直接在 22.04 上运行会出现undefined symbol: __cxa_thread_atexit_impl类链接错误——这不是 Java 版本问题,是 C 库二进制不兼容。这是选型的第一道硬门槛。
2.1 VirtualBox 必须启用的三项底层设置
很多翻车始于虚拟机本身没调对。以下配置必须在创建虚拟机前或关机状态下修改,开机状态下修改无效:
提示:VirtualBox 设置 → 系统 → 加速选项卡 → 勾选「启用嵌套分页」和「启用 VT-x/AMD-V」;网络 → 网卡1 → 连接方式选「桥接网卡」而非「NAT」。桥接模式让虚拟机获得独立 IP,避免 Hadoop 各进程间通信因 NAT 地址转换失败。
# 验证虚拟机是否真正启用了硬件加速(执行后应返回 'VT-x is enabled') $ grep -E "(vmx|svm)" /proc/cpuinfo若无输出,说明 BIOS 中 Intel VT-x 或 AMD-V 未开启,需重启进 BIOS 手动打开(不同主板按键不同,常见为 F2/F10/Del)。这是后续start-dfs.sh启动失败却查不到原因的高频黑匣子。
2.2 Ubuntu 18.04 最小化安装后的四步加固
不要用桌面版 ISO 直接装——图形界面会占用内存、引入 systemd 冲突、且默认禁用 root 登录,而 Hadoop 伪分布式要求hadoop用户对/usr/local/hadoop有完全控制权。必须用 Server 版 ISO(ubuntu-18.04.6-live-server-amd64.iso),安装时勾选「Install OpenSSH server」,其余全取消。
安装完成后立即执行:
# 1. 创建 hadoop 专用用户(禁止 shell 登录,符合生产安全习惯) $ sudo adduser --disabled-password --gecos "" hadoop $ sudo adduser hadoop sudo # 加入 sudo 组,方便调试 # 2. 关闭 swap(Hadoop 官方强制要求,否则 YARN 会拒绝启动) $ sudo swapoff -a $ echo '# swap disabled for Hadoop' | sudo tee -a /etc/fstab $ sudo sed -i '/swap/d' /etc/fstab # 彻底注释 swap 行 # 3. 配置 hosts(Hadoop 依赖 hostname 解析,localhost 不够用) $ echo "127.0.0.1 $(hostname)" | sudo tee -a /etc/hosts # 验证:ping $(hostname) 应返回 127.0.0.1 # 4. 安装并固定 OpenJDK 8(Hadoop 3.1.3 兼容性最佳) $ sudo apt update && sudo apt install -y openjdk-8-jdk-headless $ sudo update-alternatives --config java # 手动选择 java-1.8.0-openjdk-amd64update-alternatives是关键:Ubuntu 18.04 默认可能装了多个 JDK,java -version显示的版本未必是JAVA_HOME指向的版本。必须用此命令强制绑定,否则hadoop version会报Unsupported Java version。
2.3 SSH 免密登录:不是“配了就行”,而是“必须用 hadoop 用户配”
伪分布式本质是让一台机器模拟多节点,NameNode、DataNode、ResourceManager 等进程需通过 SSH 无密码启动自身。很多人用root或ubuntu用户配 SSH,结果start-dfs.sh报Permission denied (publickey)。
# 切换到 hadoop 用户(注意:su - hadoop,带短横确保加载 .bashrc) $ su - hadoop $ ssh-keygen -t rsa -P '' -f ~/.ssh/id_rsa $ cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys $ chmod 0600 ~/.ssh/authorized_keys # 验证:必须从 hadoop 用户下执行,且目标是本机 hostname $ ssh $(hostname) -o StrictHostKeyChecking=no 'echo success' # 输出 success 即成功。若提示输入密码,说明 authorized_keys 权限不对或 sshd 配置未生效。chmod 0600是铁律:OpenSSH 严格校验authorized_keys权限,755 或 644 会直接拒绝认证。这是新手最常忽略的玄学坑。
3. Linux 命令实战链:从cd到tar,每条命令都绑定 Hadoop 环境初始化上下文
本节不罗列命令手册,而是构建一条真实工作流:用 Linux 命令为 Hadoop 准备干净的家、安放二进制包、解压、建立符号链接、配置环境变量。所有操作均以hadoop用户身份在/home/hadoop下完成,路径可追溯、权限可审计。
3.1 目录结构即架构:为什么/usr/local/hadoop是唯一合法路径
Hadoop 官方文档明确要求安装路径不含空格、中文、特殊字符,且需由运行用户完全控制。/usr/local/hadoop是社区约定俗成的路径,因为:
/usr/local是 Unix 系统存放第三方软件的标准位置;hadoop子目录名与用户同名,避免混淆;- 后续配置文件中
HADOOP_HOME变量将直接引用此路径。
# 创建目录并授予权限(必须用 hadoop 用户执行) $ mkdir -p /usr/local/hadoop $ sudo chown -R hadoop:hadoop /usr/local/hadoop $ ls -ld /usr/local/hadoop # 输出应为:drwxr-xr-x 2 hadoop hadoop 4096 ... /usr/local/hadoopchown -R中的-R不是可选:Hadoop 启动时会在该目录下自动生成logs/、data/、pid/等子目录,若父目录权限不对,子目录创建失败导致进程静默退出。
3.2tar命令的两个致命参数:-C和--strip-components
下载hadoop-3.1.3.tar.gz后,解压位置和目录层级决定后续配置复杂度。错误做法:tar -zxvf hadoop-3.1.3.tar.gz→ 生成hadoop-3.1.3/目录 → 再mv hadoop-3.1.3 /usr/local/hadoop。正确做法一步到位:
# 进入下载目录(假设在 ~/Downloads) $ cd ~/Downloads # 解压到 /usr/local/ 并自动去掉顶层目录(--strip-components=1) $ sudo tar -zxvf hadoop-3.1.3.tar.gz -C /usr/local/ --strip-components=1 # 验证:/usr/local/hadoop 下应直接出现 bin/、etc/、lib/ 等目录,而非嵌套在 hadoop-3.1.3/ 内 $ ls /usr/local/hadoop | head -5 # 输出:bin etc include lib libexec LICENSE.txt NOTICE.txt README.txt sbin share--strip-components=1参数删除压缩包内顶层目录名,避免路径冗余。若漏掉,HADOOP_HOME就得写成/usr/local/hadoop-3.1.3,一旦升级版本就得全局替换配置,违背运维原则。
3.3 环境变量配置:.bashrc里三行代码的执行顺序陷阱
很多教程教你在~/.bashrc末尾追加export JAVA_HOME=...,但忽略了.bashrc的加载时机:仅对交互式非登录 shell 生效。而start-dfs.sh内部调用hadoop-daemon.sh时,启动的是非交互式 shell,不会 source.bashrc,导致JAVA_HOME为空。
# 正确做法:在 ~/.bashrc 中添加(注意 export 顺序!) export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64 export HADOOP_HOME=/usr/local/hadoop export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin # 然后,必须让所有子 shell 都能继承——重写 /etc/environment(系统级) $ echo "JAVA_HOME=\"/usr/lib/jvm/java-8-openjdk-amd64\"" | sudo tee -a /etc/environment $ echo "HADOOP_HOME=\"/usr/local/hadoop\"" | sudo tee -a /etc/environment/etc/environment是 PAM 模块读取的系统级环境变量文件,所有进程(包括非交互式 shell)启动时都会加载。这是绕过.bashrc加载限制的工业级方案。
3.4find+grep组合技:快速定位配置文件中的硬编码路径
当 Hadoop 启动失败,日志里报Cannot create directory /opt/module/hadoop-3.1.3/data,而你根本没配过/opt/module——说明某处配置文件残留了旧路径。手动翻core-site.xml太慢,用命令链秒杀:
# 在 HADOOP_HOME 下搜索所有含 'opt/module' 的文件(-l 只显示文件名,-n 显示行号) $ grep -rl "opt/module" /usr/local/hadoop/etc/hadoop/ # 输出:/usr/local/hadoop/etc/hadoop/core-site.xml # 查看具体哪一行(-n 显示行号,-A1 显示匹配行后1行) $ grep -n -A1 "opt/module" /usr/local/hadoop/etc/hadoop/core-site.xml # 输出:12: <value>/opt/module/hadoop-3.1.3/data</value>-r递归、-l列文件、-n标行号、-A显示上下文,四参数组合是排查配置污染的后悔药。
4. Hadoop 伪分布式安装:namenode -format 不是万能钥匙,而是 UUID 锁定器
伪分布式(Pseudo-Distributed Mode)不是“单机模式”,而是NameNode、DataNode、SecondaryNameNode 作为独立 JVM 进程运行在同一台物理机上,并通过 HDFS 协议通信。它的核心在于core-site.xml和hdfs-site.xml的精准配置,任何一项值错误都会导致进程启动后立即退出,且日志里只有一行Exiting due to an error。
4.1 四个 XML 文件的最小必要配置项
Hadoop 3.1.3 默认配置文件位于$HADOOP_HOME/etc/hadoop/。只需修改以下四个文件,其余保持默认即可。严禁复制网上大段配置,只改必需字段:
| 文件名 | 必改项 | 值 | 作用 |
|---|---|---|---|
core-site.xml | fs.defaultFS | hdfs://localhost:9000 | HDFS 的默认文件系统 URI,NameNode 监听地址 |
hdfs-site.xml | dfs.replication | 1 | 伪分布式只需 1 份副本(集群模式通常为 3) |
hdfs-site.xml | dfs.namenode.name.dir | /usr/local/hadoop/data/namenode | NameNode 元数据存储路径 |
hdfs-site.xml | dfs.datanode.data.dir | /usr/local/hadoop/data/datanode | DataNode 数据块存储路径 |
<!-- core-site.xml --> <configuration> <property> <name>fs.defaultFS</name> <value>hdfs://localhost:9000</value> </property> </configuration><!-- hdfs-site.xml --> <configuration> <property> <name>dfs.replication</name> <value>1</value> </property> <property> <name>dfs.namenode.name.dir</name> <value>file:/usr/local/hadoop/data/namenode</value> </property> <property> <name>dfs.datanode.data.dir</name> <value>file:/usr/local/hadoop/data/datanode</value> </property> </configuration>注意file:前缀:dfs.namenode.name.dir和dfs.datanode.data.dir必须带file:协议,否则 Hadoop 会尝试走 HDFS 协议写入自身,形成死循环。
4.2namenode -format的本质:生成 ClusterID 并写入所有 data 目录
执行hadoop namenode -format不是清空数据,而是生成一个全局唯一的 ClusterID,并将其写入dfs.namenode.name.dir和dfs.datanode.data.dir下的VERSION文件。DataNode 启动时会读取自己的VERSION文件,比对其中的clusterID是否与 NameNode 的一致。不一致则拒绝注册,jps就看不到 DataNode。
这就是实验报告里提到的“多次 format 导致 Cluster-Id 不一致”的根源。解决方案不是删整个data/目录(太粗暴),而是精准清理:
# 1. 停止所有 Hadoop 进程 $ stop-dfs.sh # 2. 删除 NameNode 和 DataNode 的 VERSION 文件(保留目录结构) $ rm /usr/local/hadoop/data/namenode/current/VERSION $ rm /usr/local/hadoop/data/datanode/current/VERSION # 3. 重新格式化(此时会生成新的、一致的 ClusterID) $ hadoop namenode -format # 4. 启动(DataNode 将读取新 VERSION 并注册) $ start-dfs.shrm .../VERSION比rm -rf /usr/local/hadoop/data安全得多:前者只重置集群标识,后者会连带删除已上传的 HDFS 文件(如果之前传过)。
4.3 验证伪分布式是否存活:三步终端检测法
不要依赖jps一个命令。jps只显示 Java 进程,但进程可能已启动却无法提供服务。必须组合验证:
# 步骤1:检查进程是否存在(NameNode, DataNode, SecondaryNameNode) $ jps | grep -E "(NameNode|DataNode|SecondaryNameNode)" # 应输出三行,如:12345 NameNode, 12346 DataNode, 12347 SecondaryNameNode # 步骤2:检查端口监听(9000 是 RPC 端口,9870 是 WebUI 端口) $ ss -tuln | grep -E ":9000|:9870" # 应看到 0.0.0.0:9000 和 0.0.0.0:9870 均处于 LISTEN 状态 # 步骤3:curl 检查 WebUI 返回 HTTP 200(绕过浏览器,直击服务) $ curl -I http://localhost:9870 2>/dev/null | head -1 # 应输出:HTTP/1.1 200 OKss -tuln比netstat更快更准,curl -I获取响应头比打开浏览器更可靠。这三步缺一不可,是判断“活着”还是“假死”的黄金标准。
5. HDFS 操作避坑:hdfs dfs命令链中的五个反直觉现象与根因
HDFS Shell 命令(hdfs dfs -xxx)看似和 Linuxls/cp/mv一样,但底层是 RPC 调用,存在大量隐式行为。新手常因忽略这些而反复失败。
5.1hdfs dfs -mkdir不创建父目录?-p参数是救命稻草
Linuxmkdir -p /a/b/c会逐级创建,但hdfs dfs -mkdir /a/b/c默认不创建父目录,报错No such file or directory。必须显式加-p:
# 错误:/a/b 不存在时,此命令失败 $ hdfs dfs -mkdir /a/b/c # 正确:-p 参数启用父目录创建 $ hdfs dfs -mkdir -p /a/b/c-p不是可选开关,是 HDFS 的强制要求。因为 HDFS 的目录创建是原子操作,不支持“先建父再建子”的两阶段提交。
5.2hdfs dfs -put的路径解析规则:本地路径必须绝对,HDFS 路径可相对
hdfs dfs -put local_path hdfs_path中:
local_path:必须是绝对路径(如/home/hadoop/.bashrc)或相对于当前 shell 工作目录的路径(如./.bashrc);hdfs_path:若不以/开头,则是相对于 HDFS 中当前用户的 home 目录(即/user/$USER)。
# 当前用户是 hadoop,其 HDFS home 是 /user/hadoop $ hdfs dfs -put ~/.bashrc test # 等价于:hdfs dfs -put ~/.bashrc /user/hadoop/test # 文件最终存放在 HDFS 的 /user/hadoop/test 路径下这是最容易混淆的点:test看似是相对路径,实则是 HDFS 的相对路径,解析基准是/user/hadoop,不是 Linux 的/home/hadoop。
5.3hdfs dfs -ls不显示隐藏文件?-a参数揭开面纱
HDFS 也遵循 Unix 隐藏文件规则(以.开头),但hdfs dfs -ls默认不显示隐藏文件,就像 Linuxls默认不显示.bashrc。要查看 HDFS 中的.Trash(回收站)等系统目录,必须加-a:
# 查看 /user/hadoop 下所有文件,包括 .Trash $ hdfs dfs -ls -a /user/hadoop-a是排查“文件明明 put 了却 ls 不见”的第一检查项。
5.4hdfs dfs -get失败却无提示?-f强制覆盖是静默杀手
hdfs dfs -get hdfs_path local_path时,若local_path已存在且是目录,命令会静默失败(无报错,但文件没下载)。必须用-f强制覆盖:
# 若 /usr/local/hadoop/test 已存在,此命令可能无反应 $ hdfs dfs -get /user/hadoop/test /usr/local/hadoop/ # 加 -f 确保覆盖 $ hdfs dfs -get -f /user/hadoop/test /usr/local/hadoop/-f不是“可选优化”,是避免本地文件状态混乱的必需参数。
5.5hdfs dfs -du和hdfs dfs -dus的区别:字节 vs 可读大小
hdfs dfs -du /path输出字节数(如123456789),而hdfs dfs -dus /path输出人类可读格式(如117.7 M)。新手常拿-du结果去df -h对比,发现数字对不上——因为df -h显示的是磁盘使用量(含副本、元数据),而hdfs dfs -du显示的是逻辑文件大小(未乘副本数)。
# 查看 /user/hadoop/test 的逻辑大小(1份副本) $ hdfs dfs -du -s /user/hadoop/test # 输出:123456789 /user/hadoop/test # 查看实际磁盘占用(1份副本 = 逻辑大小 * 1) $ hdfs dfs -dus /user/hadoop/test # 输出:117.7 M /user/hadoop/test-s参数汇总子目录,-dus自动格式化,二者配合才能看清真实存储压力。
6. WordCount 实战验证:从本地文件到 HDFS 再到 MapReduce,一条命令链的全链路诊断
WordCount 是 Hadoop 的 “Hello World”,但它的价值不在结果,而在暴露整个数据流链条中每一环是否健康:本地文件能否读、HDFS 是否可写、MapReduce 框架是否就绪、YARN 是否调度成功。本节用一条命令链完成端到端验证,并给出每个环节失败时的精准定位方法。
6.1 构建最小测试数据集:三行文本足够验证一切
不要用大文件测试。三行纯文本即可覆盖所有路径:
# 在 /home/hadoop 下创建测试文件 $ echo -e "hello world\nhello hadoop\nworld hadoop" > /home/hadoop/input.txt # 验证内容(确保无空行、无乱码) $ cat /home/hadoop/input.txt | od -c # 输出应显示三行,每行末尾有 \nod -c用十六进制查看原始字节,避免cat隐藏的不可见字符(如 Windows 换行符\r\n)干扰 MapReduce。
6.2 全链路命令:put→run→get→check
所有命令必须在hadoop用户下执行,且确保start-dfs.sh和start-yarn.sh已运行:
# 步骤1:上传输入文件到 HDFS(-f 强制覆盖,-p 创建父目录) $ hdfs dfs -mkdir -p /user/hadoop/input $ hdfs dfs -put -f /home/hadoop/input.txt /user/hadoop/input/ # 步骤2:运行 WordCount(指定输入输出路径,-D 参数覆盖默认配置) $ hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.1.3.jar \ wordcount \ -D mapreduce.job.reduces=1 \ /user/hadoop/input /user/hadoop/output # 步骤3:下载输出结果(-f 强制覆盖,-d 创建本地目录) $ hdfs dfs -get -f /user/hadoop/output /home/hadoop/ # 步骤4:检查结果(part-r-00000 是 Reduce 输出文件) $ cat /home/hadoop/output/part-r-00000 # 应输出:hadoop 2 # hello 2 # world 2-D mapreduce.job.reduces=1是关键:强制 Reduce 数为 1,确保输出只有一个文件part-r-00000,避免因多个 Reduce 文件导致cat命令失效。
6.3 每个环节失败的精准定位表
| 环节 | 失败现象 | 根本原因 | 快速诊断命令 |
|---|---|---|---|
hdfs dfs -put | put: Operation failed | HDFS 未启动或dfs.datanode.data.dir权限不足 | hdfs dfsadmin -report查看 Live Nodes 数量;ls -ld /usr/local/hadoop/data/datanode检查权限 |
hadoop jar | Application application_XXX not found | YARN 未启动或 ResourceManager 未注册 | yarn node -list查看 NodeManager 状态;jps | grep ResourceManager |
hadoop jar | java.io.IOException: Failed to replace a bad datanode | DataNode 磁盘满或dfs.datanode.data.dir下空间不足 | df -h /usr/local/hadoop/data/datanode;hdfs dfsadmin -report查看容量 |
hdfs dfs -get | get: Fatal internal error | 输出目录/user/hadoop/output已存在(HDFS 不允许覆盖) | hdfs dfs -rm -r /user/hadoop/output清理后重试 |
cat output/part-r-00000 | No such file or directory | Reduce 任务失败,输出目录为空 | yarn logs -applicationId application_XXX查看 Application 日志 |
yarn logs -applicationId是终极武器:它拉取 YARN 上该 Application 的所有 Container 日志,比翻logs/目录快十倍。
6.4 从那以后我每次部署 Hadoop,都强制走一遍这三步验证
第一次在某高校实验室带学生做这个实验时,我花了 3 小时帮 A同学解决Live Nodes 0问题,最后发现是 VirtualBox 网络模式设成了 NAT;第二次在某公司内部培训,B同学的hadoop jar一直卡在ACCEPTED,查日志发现yarn.nodemanager.resource.memory-mb设成了 1024,而虚拟机只分配了 2GB 内存,YARN 认为资源不足拒绝调度。从此我养成了铁律:只要 Hadoop 环境重建,必跑三步:
hdfs dfs -mkdir -p /tmp/test && hdfs dfs -put /etc/hosts /tmp/test/ && hdfs dfs -ls /tmp/test—— 验证 HDFS 读写通路;yarn jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-client-jobclient-3.1.3-tests.jar TestDFSIO -write -nrFiles 1 -fileSize 1MB—— 验证 MapReduce I/O 性能;curl -s http://localhost:9870/jmx?qry=Hadoop:service=NameNode,name=NameNodeInfo \| jq '.beans[0].LiveNodes'—— 验证 JMX 接口可用性(需提前sudo apt install jq)。
这三步耗时不到 1 分钟,却能筛掉 90% 的配置型故障。希望帮到你。
本文还有配套的精品资源,点击获取