资讯动态

Hadoop伪分布式实验:Linux环境、HDFS与WordCount排错

发布时间:2026/10/27 2:12:15 来源:尧图企业网站定制
简介这份大数据实验一指导文档面向刚接触大数据课程的学生与自学者围绕 Linux 虚拟机搭建、常用 Shell 命令和 Hadoop 伪分布式环境三条主线展开帮助读者在单机上补齐后续实验所需的基础操作能力。压缩包仅含 1 个 docx 文件约 289KB篇幅集中便于按实验目的、实验平台、内容要求与结果总结逐项查阅。文档覆盖 VirtualBox 与 Ubuntu 18.04/16.04 的安装准备cd、ls、mkdir、rmdir、cp、mv、rm、cat、tac、more、head、tail、touch、chown、find、tar、grep 等命令练习以及 Hadoop 3.1.3 伪分布式安装、环境变量配置、WordCount 实例验证和 HDFS 目录创建、文件复制与查看等常用操作。已有 978 人学习适合作为课程实验参考、操作清单和复习提纲也可用于对照检查基础环境是否搭建完整。1. 实验一真正在考什么从 Linux 命令行到 HDFS 的一次贯通“大数据实验 实验一熟悉常用的 Linux 操作和 Hadoop 操作”标题看起来像一份命令清单实际考的是四层依赖能不能一次串起来操作系统的账户与权限、SSH 的免密登录、Java 运行时、Hadoop 自己的四个配置文件。这四层里任何一层没打牢最后都会以hadoop fs -ls抛出一堆看不懂的异常收场而报错信息往往指向一个你从没直接动过的路径——这是最典型的黑匣子体验。下面按真实搭建顺序走一遍先立环境再练命令再改配置再跑 HDFS 和 WordCount最后把最容易翻车的地方逐条拆开。第一次接触伪分布式的人可以照着做带实验的人也可以拿它对照排查。2. Linux 基础环境四步立住账户、SSH 免密、目录规划与常用命令2.1 专用账户与目录规划为什么不该用 root 跑守护进程拿到实验指导书之后很多人的第一反应是su root然后一路装下去装完能跑交完报告就忘。问题在于 Hadoop 的每个守护进程都以“启动它的那个用户”的身份写日志、写数据目录。你只要用 root 启动过一次后面换成普通账户就会在/tmp或数据目录上撞到Permission denied而那条报错指向的路径你根本没直接操作过。我一般在开跑前定三条约定一个专用普通账户习惯叫hadoop、一个统一安装根目录/opt/module、一个独立数据目录/data/hadoop。账户负责权限边界目录负责路径可预期权限负责让守护进程能写进去。三件事十分钟能做完却能省掉后面两小时的排查。# 1. 建专用账户别用 root 跑守护进程 sudo useradd -m -s /bin/bash hadoop sudo passwd hadoop # 2. 统一安装根目录与数据目录后续所有路径都从这里展开 sudo mkdir -p /opt/module sudo mkdir -p /data/hadoop/{name,data,tmp} sudo chown -R hadoop:hadoop /opt/module /data/hadoop # 3. 给普通账户临时提权避免脚本执行到一半停下来等密码 echo hadoop ALL(ALL) NOPASSWD:ALL | sudo tee /etc/sudoers.d/hadoop sudo chmod 440 /etc/sudoers.d/hadoopuseradd -m会同时建家目录-s /bin/bash保证登录后有正常 shell否则ssh localhost会直接退出、什么提示都不给。/opt/module是社区里常见的安装惯例好处是所有组件Hadoop、JDK都放在一层里后面写JAVA_HOME和HADOOP_HOME时路径短、不容易写错。chown -R的递归很关键只改父目录的话子目录仍然属于 rootDataNode 写块文件时会失败。/etc/sudoers.d/下单独放文件比直接改sudoers安全440权限是 sudo 的硬性要求写成644会直接拒绝加载。把/data/hadoop/tmp单独分出来是因为 Hadoop 的hadoop.tmp.dir默认落在/tmp下而/tmp在多数发行版里会被系统清理任务定期清空。临时文件被清掉之后NameNode 的元数据和 DataNode 的块就对不上症状是“昨天还能跑今天启动就报错”——这种玄学问题十有八九源于此。2.2 SSH 免密登录start-dfs.sh 能不能一键起来全看这一步start-dfs.sh的工作方式是在本机通过 ssh 分别拉起 NameNode、DataNode、SecondaryNameNode。它没有别的进程管理机制就是循环调用ssh。所以免密没配好脚本要么卡在反复输密码要么直接Permission denied退出而且三个进程可能只起来一个jps看上去“起了一半”。# 切到专用账户再操作密钥要生成在正确的人的家目录下 su - hadoop # -P 表示空口令-f 指定路径避免覆盖已有密钥 ssh-keygen -t rsa -b 4096 -P -f ~/.ssh/id_rsa # 公钥写入授权列表 cat ~/.ssh/id_rsa.pub ~/.ssh/authorized_keys # 权限必须收紧sshd 的 StrictModes 会拒绝过宽的权限 chmod 700 ~/.ssh chmod 600 ~/.ssh/authorized_keys # 验证能不带密码直接登进去才算通过 ssh localhost血泪经验在最后两行。~/.ssh必须是700authorized_keys必须是600很多发行版的 sshd 默认开启StrictModes权限一旦放宽到组或其他用户可读就会静默忽略这个文件然后回头找你要密码。更隐蔽的一种情况是密钥生成在 root 账户下、却用hadoop去启动服务ssh localhost单独测试能过因为当时是 rootstart-dfs.sh就过不去。ssh-keygen -t rsa -b 4096里-t是算法、-b是密钥长度-P 给空口令是为了让脚本调用时不被口令交互拦住不是省略安全设置——这台机器只是本地实验环境私钥也不要往外拷。2.3 文件与文本命令的最小可用集find、grep、awk、sed、tail实验指导书里的 Linux 命令通常列几十个但真正天天用、且能组合起来解决问题的是五六个。练的时候不要孤立地敲要带着“我要在 Hadoop 目录里找点什么”的目的去用。# 定位限制深度避免在几十万文件的目录里全盘扫描 find /opt/module -maxdepth 3 -type f -name *.xml # 过滤从日志里捞出异常行-n 带上行号方便定位 grep -n ERROR\|Exception /opt/module/hadoop/logs/*namenode*.log | tail -n 50 # 截字段-F 指定分隔符取第 1、3 列 awk -F\t {print $1 \t $3} /data/hadoop/tmp/sample.tsv | head -n 20 # 批量替换-i 原地改改之前先不加 -i 看一遍输出 sed -i s#hdfs://oldhost:9000#hdfs://localhost:9000#g /opt/module/hadoop/etc/hadoop/core-site.xml # 跟踪实时看 DataNode 启动过程中的反馈 tail -f /opt/module/hadoop/logs/*datanode*.logfind的-maxdepth是性能开关不限深度在/下跑一次能卡住好几分钟-type f排除目录否则-name会匹配到同名目录。grep -n的行号在对照日志上下文时尤其有用tail -n 50只取最后 50 行是因为 Hadoop 日志动辄几万行全量输出反而看不见关键那几行。awk -F\t里的-F是字段分隔符默认是任意空白。处理 HDFS 导出的数据时制表符和空格混用非常常见显式指定分隔符能避免整行被当成一列。sed -i是原地修改第一次用建议先不加-i确认替换结果正确再落盘——我见过把core-site.xml里fs.defaultFS的值整体替换掉、导致文件结构损坏的例子改之前备份一份cp core-site.xml core-site.xml.bak是最便宜的安全保障。注意sed用#而不是/作分隔符是因为替换内容里本身含//。2.4 权限与进程chmod、chown、jps、ss 的判断顺序启动失败时判断顺序比命令本身更重要。我的习惯是先看进程在不在再看端口通不通最后看权限对不对。顺序反了就容易在权限上折腾半天结果发现进程压根没起来。命令典型场景容易踩的点jps -l确认 Java 进程与主类只显示当前用户的进程用 root 敲会“看不到”ss -lntp看 9000/9870/8088 是否监听需要权限才能显示进程名chmod调整脚本可执行位不要图省事给 777chown -R修数据目录属主漏掉-R导致子目录仍是旧属主kill结束残留进程先 TERM 后 KILL直接-9会丢元数据# 进程层先确认守护进程真的起来了 jps -l # 网络层9000 是 RPC9870 是 NameNode Web UI8088 是 YARN ss -lntp | grep -E 9000|9870|8088|9864 # 权限层只给必要的执行位别用 777 chmod 755 /opt/module/hadoop/bin/*.sh chown -R hadoop:hadoop /data/hadoop # 收尾先温和终止给进程写元数据的机会 kill $(jps | awk /DataNode/{print $1})jps的一个坑是它只列当前用户启动的 JVM。用 root 敲jps看不到hadoop用户起的 NameNode很容易误判成“没起来”。ss -lntp里-l是监听状态、-n不做域名解析、-t是 TCP、-p显示进程四个参数一起用才够快。至于kill先发默认的 TERM 信号让进程有机会把内存里的元数据落盘直接kill -9在 NameNode 上用过一次就够记一辈子——恢复起来要么靠 SecondaryNameNode 的检查点要么重新格式化两条路都不好走。3. Hadoop 伪分布式配置四个 XML 文件和一个 env 文件逐项改3.1 单机模式、伪分布式与完全分布式实验一为什么选中间那个Hadoop 有三种运行模式选错模式是白折腾两小时的常见原因。单机模式standalone开箱即用、不需要任何配置但它根本不启动 HDFS 和 YARN所有程序在本地 JVM 里跑hdfs dfs -ls这类命令会直接告诉你“没有文件系统”。完全分布式至少三台机器涉及主机名解析、跨机免密、时间同步属于实验二之后的内容。伪分布式是折中所有守护进程都在一台机器上但彼此通过 RPC 通信走完整的 HDFS 读写路径和 YARN 调度路径。它的价值在于你能用一台机器观察到真实集群里的所有角色——NameNode、DataNode、ResourceManager、NodeManager能看懂进程之间的关系也能踩到 90% 的配置坑。模式需要改配置是否启动 HDFS/YARN适用阶段单机否否只验证 MapReduce 逻辑伪分布式是4 个 XML env是单机多进程实验一标准形态完全分布式是另加主机与免密是多机实验二及之后判断自己当前在哪个模式最简单的办法是看core-site.xml里有没有fs.defaultFS。没有这一项Hadoop 就走本地文件系统你 put 进去的文件压根没进 HDFS后面hdfs dfs -ls /空空如也就是必然的。3.2 core-site.xml 与 hdfs-site.xml两个必改项和默认值陷阱四个配置文件都在$HADOOP_HOME/etc/hadoop/下。改之前全部备份一遍出错能一分钟回滚这比事后回忆改了哪一行靠谱得多。!-- core-site.xml入口地址与临时目录 -- configuration property namefs.defaultFS/name valuehdfs://localhost:9000/value /property property namehadoop.tmp.dir/name value/data/hadoop/tmp/value /property /configuration!-- hdfs-site.xml副本数与元数据/数据落盘位置 -- configuration property namedfs.replication/name value1/value /property property namedfs.namenode.name.dir/name valuefile:///data/hadoop/name/value /property property namedfs.datanode.data.dir/name valuefile:///data/hadoop/data/value /property /configurationfs.defaultFS是整套配置的中枢客户端靠它决定连哪个 NameNode写错端口或主机名所有hdfs dfs命令都会连不上。用localhost还是主机名取决于/etc/hosts里有没有把主机名解析到127.0.0.1如果解析不到NameNode 启动时会抛UnknownHostException而报错里通常只显示一个主机名不看/etc/hosts很难联想到。dfs.replication默认是 3伪分布式只有一台 DataNode副本数设成 3 会导致块永远处于“副本不足”状态hdfs fsck报一堆 under-replicated虽然不影响读写但看着闹心也容易让人误以为集群坏了。设成 1 是伪分布式的标准做法。hadoop.tmp.dir是第二个陷阱。不显式配置时HDFS 的元数据默认落在/tmp/hadoop-${user.name}下系统清理任务一动手NameNode 的fsimage就没了下次启动直接报“目录不存在请格式化”。把name.dir和data.dir用file://绝对路径写死等于给集群上了个保险。3.3 mapred-site.xml、yarn-site.xml 与 hadoop-env.sh让作业真的落在 YARN 上只改前两个文件HDFS 能起来但提交 MapReduce 作业会走本地模式jps里看不到 ResourceManager也体验不到 YARN 调度。剩下两个文件和 env 脚本补的就是这一块。!-- mapred-site.xml指定计算框架为 YARN -- configuration property namemapreduce.framework.name/name valueyarn/value /property /configuration!-- yarn-site.xmlNodeManager 的附属服务与 ResourceManager 地址 -- configuration property nameyarn.nodemanager.aux-services/name valuemapreduce_shuffle/value /property property nameyarn.resourcemanager.hostname/name valuelocalhost/value /property property nameyarn.nodemanager.resource.memory-mb/name value2048/value /property /configurationyarn.nodemanager.aux-services的值必须是mapreduce_shuffle少一个下划线、多一个 sNodeManager 能起来但 MapReduce 作业会卡在 map 100% reduce 0% 不动这个症状极具迷惑性。resource.memory-mb默认取机器物理内存的一个比例在只有 4G 内存的虚拟机里常常导致容器申请不到资源作业一直处于 ACCEPTED 状态显式调小到 2048 是常用做法。# hadoop-env.sh 里追加注意不要覆盖原有的 export export JAVA_HOME/usr/lib/jvm/java-11-openjdk-amd64 export HDFS_NAMENODE_USERhadoop export HDFS_DATANODE_USERhadoop export HDFS_SECONDARYNAMENODE_USERhadoop export YARN_RESOURCEMANAGER_USERhadoop export YARN_NODEMANAGER_USERhadoopJAVA_HOME要写绝对路径用readlink -f $(which java)反推最稳因为很多发行版把java放在/usr/bin的软链上直接写/usr/bin/java会被当成目录。Hadoop 3 里那几个*_USER变量是启动脚本检查用的不写会看到ERROR: Attempting to operate on hdfs namenode as root之类的提示或者提示用户变量未定义——这个报错信息说得含糊第一次见很难定位到是 env 脚本缺行。3.4 格式化与启动一次成功该看到哪几个进程# 只执行一次重复执行会引发 clusterID 不一致 hdfs namenode -format # 启动 HDFS 与 YARN start-dfs.sh start-yarn.sh # 期望看到 6 个进程 jpshdfs namenode -format会初始化dfs.namenode.name.dir目录生成fsimage和VERSION文件。格式化成功时控制台会打印Storage directory ... has been successfully formatted同时给出一个 clusterID记下这一行。伪分布式环境里我建议把“只格式化一次”写在便利贴上贴屏幕边——这不是夸张重复 format 是实验一最高频的翻车原因处理方式在第 5 章展开。jps期望看到 6 个进程NameNode、DataNode、SecondaryNameNode、ResourceManager、NodeManager、Jps。少任何一个都别急着往下走先去看$HADOOP_HOME/logs/下对应角色的日志.log结尾的是运行日志.out结尾的是标准输出多数启动失败的原因在.out的最后 20 行里写得明明白白。注意start-dfs.sh和start-yarn.sh的返回码是 0 并不代表进程起来了它们只是把 ssh 命令发出去。必须用jps或ss -lntp二次确认。4. HDFS 与 WordCount 跑通从 put 一个文件到读出 part-r-000004.1 HDFS 的八个动作一次完整的本地与集群往返HDFS 命令分两套写法hadoop fs和hdfs dfs前者能操作更广的文件系统后者专指 HDFS。做实验时用hdfs dfs语义更清楚也不容易误操作到本地目录。# 建目录-p 递归创建父目录不存在也不报错 hdfs dfs -mkdir -p /user/hadoop/input # 上传本地路径在前HDFS 路径在后 hdfs dfs -put /opt/module/hadoop/etc/hadoop/*.xml /user/hadoop/input # 列出-R 递归看子目录时用 hdfs dfs -ls /user/hadoop/input # 查看内容小文件直接 cat大文件用 -tail hdfs dfs -cat /user/hadoop/input/core-site.xml # 看容量-h 人类可读-s 显示总计 hdfs dfs -du -h -s /user/hadoop/input # 下载回本地 hdfs dfs -get /user/hadoop/input/core-site.xml /tmp/ # 改权限目录给 755脚本类文件才需要执行位 hdfs dfs -chmod -R 755 /user/hadoop # 删除-r 递归-f 跳过确认生产上慎用 -f hdfs dfs -rm -r /user/hadoop/input-put会把本地文件复制到 HDFS源文件保留-moveFromLocal则是剪切语义本地文件会消失两个命令在实验报告里经常被混写。-du -h -s里-s是 summary不加它会把每个子文件都列一遍看总量时反而累赘。-rm -r和-rm -f组合使用要小心-f会跳过确认提示在 HDFS 上删掉的东西没有回收站除非单独配置了 Trash删了就是删了。一个常被忽略的点HDFS 的路径是逻辑路径/user/hadoop会映射到dfs.namenode.name.dir下的实际目录结构但这个映射不是一对一的文件对应关系块文件blk_*和.meta校验文件是分开存的。所以不要试图在 Linux 里直接catHDFS 的块文件读出来是二进制。4.2 WordCount 的最小输入与提交命令跑通 HDFS 之后WordCount 是验证 MapReduce 链路最快的例子。它不需要自己写代码Hadoop 自带示例 jar 包里就有。# 1. 造一份最小输入三行文本足够看出词频 echo -e hadoop mapreduce hdfs\nyarn hdfs hadoop\nmapreduce yarn hdfs /tmp/wc-input.txt # 2. 建输入目录并上传输出目录不要预先创建 hdfs dfs -mkdir -p /user/hadoop/wc/input hdfs dfs -put /tmp/wc-input.txt /user/hadoop/wc/input # 3. 提交作业jar 用通配符避免记版本号 hadoop jar /opt/module/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.*.jar \ wordcount /user/hadoop/wc/input /user/hadoop/wc/output # 4. 看结果 hdfs dfs -ls /user/hadoop/wc/output hdfs dfs -cat /user/hadoop/wc/output/part-r-00000hadoop jar会自动把作业提交到mapreduce.framework.name指定的框架配置成yarn就走 YARN配置成local就在当前 JVM 里跑完。所以前面mapred-site.xml那一项没改的话这里能出结果但jps里看不到 ResourceManager作业执行时间也短得可疑——这是判断“到底走没走 YARN”的一个土办法。输入输出路径都是 HDFS 路径。输出目录必须不存在这是 MapReduce 的保护机制作业失败重跑时如果直接覆盖上一次的部分结果就没法对比了。所以第二次跑同一条命令必须先hdfs dfs -rm -r /user/hadoop/wc/output。提示作业提交后控制台会打印Job job_xxxx submitted、map 100% reduce 100%、Job job_xxxx completed successfully。卡在map 0% reduce 0%通常是 YARN 资源不足卡在map 100% reduce 0%则优先查aux-services配置。4.3 读懂输出目录part-r-00000、_SUCCESS 与 .crc 各是什么第一次ls输出目录看到三四个陌生文件容易发懵。它们的含义其实很规整文件含义说明part-r-00000第 0 个 reducer 的输出r表示 reduce 阶段产物编号从 0 开始part-m-00000第 0 个 mapper 的输出没有 reducer 或 reduce 数为 0 时出现_SUCCESS作业成功标记零字节空文件供调度系统判断是否完成.part-r-00000.crc校验文件HDFS 侧生成不要手动改part-r-00000里的内容是单词\t词频的制表符分隔格式。上一步的三行输入跑完能读到hadoop 2、hdfs 3、mapreduce 2、yarn 2这样的结果词按字典序排列。文件名的数字是分区编号reduce 任务数设为 2 时会同时出现part-r-00000和part-r-00001这一点在做多 reduce 实验时会用到。_SUCCESS是个零字节文件用hdfs dfs -cat读出来什么都没有别以为出错了。它的存在本身就是信号很多调度工具就靠这个文件判断上游作业是否完成。.crc文件是 HDFS 的校验和用来检测块在磁盘上的损坏。它们由 DataNode 自动维护-put和-get时校验一次。手动删掉不会影响读取但下次校验周期会重新生成属于“看着碍眼但别动”的那类文件。5. 避坑与排查实验一里五个高频翻车点配置做完、命令也敲完剩下的时间基本都花在排查上。下面五条是我见过频率最高、且报错信息最容易误导人的。5.1 反复格式化之后 NameNode 起不来clusterID 不一致现象jps里只有Jps没有NameNode看logs/*namenode*.log最后几行写着java.io.IOException: Incompatible clusterIDs in /data/hadoop/data/current: namenode clusterID CID-xxxx; datanode clusterID CID-yyyy。原因hdfs namenode -format执行了不止一次。每次格式化都会给 NameNode 目录生成新的 clusterID而 DataNode 目录里还留着上一次的 ID两边对不上NameNode 拒绝启动。也可能是只删了name目录没删data目录或者反过来。解决停掉所有进程把dfs.namenode.name.dir和dfs.datanode.data.dir指向的两个目录整体删空重新格式化一次。这是一次“后悔药”代价是 HDFS 上的数据全丢所以只适合实验环境。stop-dfs.sh rm -rf /data/hadoop/name/* /data/hadoop/data/* hdfs namenode -format start-dfs.sh根治办法其实更简单格式化之前先ls一下 name 目录非空就别格。真需要重来走上面三步不要指望 NameNode 自己在两个 ID 之间挑一个。5.2 SSH 免密“看着配了”start-dfs.sh 还是要密码现象单独敲ssh localhost能直接进去敲start-dfs.sh却提示Permission denied (publickey,password)或者卡在Starting namenodes on [localhost]一直没动静。原因有三种。第一种是~/.ssh或authorized_keys权限过宽sshd 的StrictModes静默忽略了这个文件——注意是静默日志里只有一行Authentication refused: bad ownership or modes很容易被跳过。第二种是密钥生成在 root 家目录下而服务是用hadoop用户启动的。第三种是/etc/ssh/sshd_config里PubkeyAuthentication被关掉了虽然少见但确实存在。解决先确认当前用户再查权限最后看 sshd 配置。whoami ls -ld ~/.ssh ~/.ssh/authorized_keys # 期望输出 drwx------ 和 -rw------- chmod 700 ~/.ssh chmod 600 ~/.ssh/authorized_keys sudo grep -E PubkeyAuthentication|StrictModes /etc/ssh/sshd_config改完 sshd 配置要sudo systemctl restart sshd。这台机器上还有一个细节ssh localhost走的是127.0.0.1而start-dfs.sh里用的可能是主机名如果/etc/hosts没把主机名映射到本地回环两条路径的认证结果可能不一样。5.3 JAVA_HOME 没写死脚本报找不到 Java现象手动敲hadoop version正常输出但start-dfs.sh报ERROR: JAVA_HOME is not set and could not be found或者作业提交时抛Could not find or load main class。原因JAVA_HOME只在交互式 shell 的.bashrc里 export 过。ssh 非交互登录start-dfs.sh内部就是这种默认不读.bashrc只读.bash_profile或.profile。另一种情况是hadoop-env.sh里export JAVA_HOME那行还带着#注释。解决把JAVA_HOME写死在$HADOOP_HOME/etc/hadoop/hadoop-env.sh里这是所有启动脚本都会 source 的文件不受登录方式影响。路径用readlink -f $(which java)反推再去掉末尾的/bin/java。readlink -f $(which java) # 输出类似 /usr/lib/jvm/java-11-openjdk-amd64/bin/java grep -n JAVA_HOME /opt/module/hadoop/etc/hadoop/hadoop-env.sh改完不需要重启任何东西下次启动脚本生效。这条坑的特点是“手动能跑、脚本不能跑”如果只按交互式经验判断会一直在.bashrc里找原因。5.4 jps 里没有 ResourceManager 或 NodeManager现象start-yarn.sh打印Starting resourcemanager和Starting nodemanagers返回码 0但jps里就是没有这两个进程。原因最常见的是yarn-site.xml里yarn.nodemanager.aux-services拼写错误或者值写成了mapreduce-shuffle多了个连字符。其次是内存不足NodeManager 启动时按yarn.nodemanager.resource.memory-mb申请资源虚拟机内存不够会被系统 OOM 杀掉。第三是yarn.resourcemanager.hostname写了个解析不到的名字。解决先看日志尾部再改配置。tail -n 40 /opt/module/hadoop/logs/*resourcemanager*.log tail -n 40 /opt/module/hadoop/logs/*nodemanager*.log free -h日志里Exiting with status 1之前那几行才是真正原因。内存不够就先stop-yarn.sh把resource.memory-mb调到 1024 再起。aux-services 拼写错误在日志里体现为InvalidAuxServiceException比较显眼改完重启即可。5.5 作业提交被拦安全模式与输出目录已存在现象一hdfs dfs -put报Cannot create file ... Name node is in safe mode。原因是 NameNode 启动后处于安全模式等 DataNode 上报足够的块才自动退出。如果 DataNode 压根没起来它会一直卡着。这时候hdfs dfsadmin -safemode leave能临时放行但根因没解决下次重启照样卡。现象二WordCount 报org.apache.hadoop.mapred.FileAlreadyExistsException: Output directory hdfs://localhost:9000/user/hadoop/wc/output already exists。原因是 MapReduce 不覆盖已有输出目录这是设计如此不是 bug。解决安全模式先查 DataNodejps里没有就去看 DataNode 日志多数是data.dir权限或 clusterID 问题回到 5.1。确认 DataNode 正常后再hdfs dfsadmin -safemode get看状态一般几秒内会自己退出。输出目录直接删掉重跑hdfs dfs -rm -r /user/hadoop/wc/output hadoop jar /opt/module/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.*.jar \ wordcount /user/hadoop/wc/input /user/hadoop/wc/output养成习惯每次重跑作业前先删输出目录比看到报错再删快得多。6. 把环境自检写成一个脚本一次跑完比反复重启省半小时排查次数多了会发现五成问题出在“没确认环境就往下走”。与其每次启动失败后凭记忆一条条敲不如把检查项固化成一个脚本改完配置先跑它通过再提交作业。#!/usr/bin/env bash # check_env.sh伪分布式环境自检任一项失败即退出 set -e echo [1/5] 当前用户与 Java whoami readlink -f $(which java) echo [2/5] SSH 免密 ssh -o BatchModeyes -o ConnectTimeout3 localhost echo ssh-ok echo [3/5] 守护进程 jps -l | grep -E NameNode|DataNode|ResourceManager|NodeManager || { echo 进程缺失去看 \$HADOOP_HOME/logs/*.out; exit 1; } echo [4/5] 端口监听 ss -lntp | grep -E 9000|9870|8088 echo [5/5] HDFS 健康度 hdfs dfsadmin -report | head -n 12 hdfs fsck / -files -blocks | tail -n 3set -e让脚本遇到第一个失败就停避免“后面全是连锁报错”的噪音。ssh -o BatchModeyes是关键它禁止任何交互式提问免密没配好会立刻失败而不是卡住等密码正好把第 5.2 条那类问题提前暴露。ConnectTimeout3防止在网络不通时挂太久。hdfs dfsadmin -report输出里Live datanodes (1)这一行是伪分布式的标准形态如果显示 0说明 DataNode 没注册上后面的操作全都不必做。hdfs fsck只看最后三行是因为正常集群的输出有几千行你要的信息只有“块数、副本状态、健康状况”这三个数。这个脚本我一般放在~/bin/下加进PATH改完任何一个 XML 就跑一次三十秒出结果比启动失败后翻日志快得多。用了两年多最大的体会是环境类问题的排查成本几乎全部来自“不确定自己在哪一层”而不是“不知道解法”。把层次固定下来剩下的就是查表。有一点提醒脚本里不要用hdfs dfs -ls /当健康检查——空目录也会返回 0看起来一切正常实际 DataNode 可能一个都没起来。用dfsadmin -report里的 Live datanodes 数量判断才是有意义的信号。我自己在这上面翻过一次车写进脚本之后就没再犯。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑