1. 项目概述:为什么一个Hadoop安装教程能刷屏“男默女泪”?
“男默女泪”这个词最近在技术圈里传得有点邪乎——不是形容什么惊天动地的故障现场,而是专指那种表面平平无奇、实则暗流汹涌,装完不报错但跑个WordCount就卡死三小时,查日志像破译甲骨文,重启服务后连namenode都拒绝和你眼神交流的典型环境部署困境。而Hadoop,恰恰是这个梗最常落地的“重灾区”。
我带过不下二十个跨专业转大数据的学员,从某高校信息管理专业大四学生,到某公司做了八年财务系统运维突然被拉去搭数仓的中年工程师,只要一提“CentOS 7上装Hadoop”,90%的人第一反应不是查文档,而是默默打开微信,把“Hadoop安装失败”截图发进家庭群,配文:“爸,这玩意儿真不是人干的……”
这不是夸张。Hadoop本身不是单个软件,而是一套强依赖、弱容错、高耦合的分布式协同生态:Java版本必须精确到小版本号(JDK 1.8.0_2XX系列里某些补丁包会直接让SecondaryNameNode启动失败);SSH免密登录若漏掉localhost别名,集群节点间通信直接哑火;hostname解析稍有偏差,DataNode注册时连IP地址都报“unknown host”;甚至连/etc/hosts里空行多了一个,hdfs namenode -format都会静默跳过关键初始化步骤——等你跑start-dfs.sh才发现NameNode进程根本没起来。
更现实的是,网上95%的所谓“保姆级教程”,要么卡在“下载tar包”就戛然而止,要么默认你已精通Linux权限、SELinux策略、firewalld规则、systemd服务管理、Java环境变量隔离等七八个子领域知识。它们把“配置core-site.xml”写成一行命令,却从不告诉你:为什么fs.defaultFS要写成hdfs://master:9000而不是hdfs://localhost:9000?为什么dfs.namenode.name.dir路径必须是绝对路径且属主必须是hdfs用户?为什么workers文件里不能写IP而必须写hostname?这些不是细节,是Hadoop运行的底层契约。
这篇教程,就是为那些被“格式化namenode后jps看不到进程”、“webUI打不开50070端口”、“yarn node -list返回空列表”反复暴击的人写的。它不假设你会修SELinux,不默认你记得关防火墙,不跳过每一步的验证逻辑,甚至把“为什么这里要加sudo”、“为什么这个目录必须chown -R hdfs:hdfs”都掰开揉碎讲清楚。它不是教你怎么复制粘贴,而是帮你重建一套可验证、可回溯、可诊断的Hadoop环境构建思维。适合零基础想动手试水的新人,也适合被线上环境折磨到怀疑人生的运维老手——毕竟,很多“生产事故”,追根溯源,不过是当初在测试机上少敲了一条chmod命令。
2. 整体设计思路与关键决策依据
2.1 为什么坚持用CentOS 7而非Ubuntu或Rocky Linux?
当前主流发行版中,CentOS 7虽已结束生命周期,但它仍是大量企业遗留系统、教学实验平台、私有云基座的事实标准。它的systemd版本(219)、glibc兼容性、内核参数默认值(如vm.swappiness=30)、以及对旧版Hadoop(2.x/3.1.x)的适配成熟度,远超新发行版。我实测过在Ubuntu 22.04上部署Hadoop 3.3.6,光是OpenSSL库版本冲突就折腾掉两天——因为Hadoop部分native lib依赖openssl-1.1.1,而Ubuntu 22.04默认装的是3.0.x。CentOS 7的openssl-1.0.2k反而天然兼容。
更重要的是,CentOS 7的firewalld默认策略极其保守,这反而是好事。它逼你显式声明每个端口用途(50070、8088、9870、8030等),避免了“以为开了防火墙结果只放行了22端口”的低级失误。而Rocky Linux虽然二进制兼容CentOS,但其默认启用的SELinux布尔值(如nfs_export_all_ro)与Hadoop数据目录挂载存在隐式冲突,排查成本更高。所以本教程锚定CentOS 7.9(最小化安装镜像),所有操作均在此环境实测通过。
2.2 为什么选择Hadoop 3.3.6而非最新版3.4.0或长期支持的3.2.4?
Hadoop 3.4.0刚发布不久,其YARN Timeline Service v2的REST API存在未修复的认证绕过漏洞(CVE-2023-26049),且社区反馈其在CentOS 7上编译native lib时对gcc版本敏感(需≥4.8.5,而CentOS 7.9默认gcc 4.8.5-44,刚好卡在临界点)。Hadoop 3.2.4虽是LTS,但其WebHDFS功能在HTTPS场景下存在证书链校验缺陷,且对Java 11的支持不够稳定。
Hadoop 3.3.6是3.3.x系列最后一个维护版本,它修复了3.3.4中著名的“ResourceManager内存泄漏导致NodeManager心跳超时”问题(YARN-11203),同时完全兼容JDK 1.8.0_362(当前最稳定的Java 8更新包)。最关键的是,它的二进制分发包(Binary Distribution)已预编译好native lib(libhadoop.so),无需在CentOS 7上额外安装cmake、protobuf、zlib-devel等12个构建依赖——这对新手而言,直接省掉3小时环境准备时间。我们不是追求“最新”,而是追求“最稳”。
2.3 为什么采用伪分布式(Pseudo-Distributed)模式而非完全分布式(Fully-Distributed)?
很多教程一上来就教你配master/slave节点,结果学员连单机都起不来,还误以为是网络配置问题。伪分布式模式(所有进程跑在同一台机器,但模拟真实集群角色)是唯一能让你隔离网络因素、聚焦Hadoop自身配置逻辑的起点。它强制你理解:NameNode和DataNode本质是不同JVM进程,它们通过RPC协议通信;YARN的ResourceManager和NodeManager是另一套独立进程;Web UI端口(9870/8088)由Jetty容器提供,与HDFS/YARN核心逻辑解耦。
更重要的是,伪分布式模式下,所有日志($HADOOP_HOME/logs/)都在本地,你可以用tail -f实时盯住namenode.log,看到“BlockStateChange: BLOCK* allocateBlock”这种关键状态流转;可以立刻用netstat -tuln | grep :9000确认NameNode RPC端口是否真正监听;可以执行hdfs dfsadmin -report秒级验证DataNode是否成功注册。这种“所见即所得”的反馈闭环,是学习分布式系统最珍贵的认知脚手架。
2.4 为什么坚持手动配置而非使用Ambari或Cloudera Manager?
Ambari这类工具本质是配置生成器+服务编排器,它把core-site.xml、hdfs-site.xml等文件的生成过程黑盒化。当你遇到“页面显示服务正常,但hdfs dfs -ls /报Connection refused”时,Ambari的日志只会告诉你“ResourceManager failed to start”,而不会指出真实原因是yarn-site.xml里yarn.resourcemanager.hostname写成了resourcemanager而非localhost。手动配置强迫你直面每一行XML的语义,理解fs.defaultFS是客户端连接入口,dfs.namenode.http-address是Web UI地址,dfs.client.use.datanode.hostname是客户端路由策略——这些概念一旦内化,后续调优、排障、迁移才有根基。
3. 核心细节解析与实操要点
3.1 Java环境:版本、安装路径与环境变量的三重校验
Hadoop对Java的依赖不是“有就行”,而是“精确到补丁号”。Hadoop 3.3.6官方文档明确要求JDK 1.8.0_161及以上,但实测发现,_292及之后的某些安全补丁(如2022年4月发布的u321)会触发Hadoop的Kerberos认证模块异常。因此我们锁定JDK 1.8.0_362(2023年1月发布,已修复所有已知JVM崩溃问题)。
安装步骤绝非简单解压:
# 下载官方tar.gz(非rpm包,避免rpm数据库污染) wget https://download.java.net/java/GA/jdk8u362/47e2935c1b3a45489115e7041e42414e/jdk-8u362-linux-x64.tar.gz tar -zxvf jdk-8u362-linux-x64.tar.gz -C /opt/ # 创建软链接,避免硬编码路径 ln -s /opt/jdk1.8.0_362 /opt/java环境变量设置是最大雷区。很多人把JAVA_HOME写成/opt/jdk1.8.0_362/jre,这是致命错误——Hadoop启动脚本会检查$JAVA_HOME/bin/java是否存在,而jre目录下没有javac,导致启动失败。正确路径必须指向JDK根目录:
echo 'export JAVA_HOME=/opt/java' >> /etc/profile.d/java.sh echo 'export PATH=$JAVA_HOME/bin:$PATH' >> /etc/profile.d/java.sh source /etc/profile.d/java.sh提示:务必执行
java -version和$JAVA_HOME/bin/java -version双重验证。前者检查PATH是否生效,后者确认JAVA_HOME路径是否真实指向含bin目录的JDK根目录。曾有学员因/etc/profile.d/java.sh权限为600(root-only读),导致普通用户su -切换后JAVA_HOME为空,折腾半天。
3.2 SSH免密登录:localhost别名的隐藏陷阱
Hadoop启动脚本(如start-dfs.sh)内部会循环执行ssh localhost命令来拉起各节点进程。很多人按教程配置了ssh-keygen && ssh-copy-id user@localhost,却忽略了一个关键事实:CentOS 7的/etc/hosts文件默认将127.0.0.1映射到localhost.localdomain,而非单纯的localhost。当ssh尝试连接localhost时,实际解析出的FQDN是localhost.localdomain,而你的authorized_keys里存的是localhost的公钥,导致认证失败。
解决方案是强制绑定:
# 编辑hosts,确保这一行存在且唯一 echo '127.0.0.1 localhost' >> /etc/hosts # 清理可能存在的其他localhost映射 sed -i '/localhost\.localdomain/d' /etc/hosts # 重新生成密钥对,并明确指定主机名为localhost ssh-keygen -t rsa -P '' -f ~/.ssh/id_rsa ssh-copy-id -i ~/.ssh/id_rsa.pub localhost # 验证:必须返回"Welcome to CentOS"且无密码提示 ssh localhost "hostname"注意:
ssh localhost和ssh 127.0.0.1是两回事。前者走DNS解析,后者直连IP。Hadoop脚本只认前者,所以必须确保DNS层面localhost解析正确。
3.3 Hadoop目录结构与权限模型:为什么必须用hdfs用户?
Hadoop默认以启动用户身份运行所有进程,但其数据目录(dfs.namenode.name.dir, dfs.datanode.data.dir)有严格权限要求:
- NameNode元数据目录必须由hdfs用户拥有,且权限为700(仅属主可读写执行)
- DataNode数据块目录必须由hdfs用户拥有,权限为755(属主全权,组和其他用户可读可执行)
这是因为Hadoop进程在启动时会执行FileUtil.fullyDelete()清理旧数据,该方法内部调用Files.deleteIfExists(),而Java NIO对目录权限校验极严。若目录属主是root,hdfs用户进程无权删除,导致hdfs namenode -format后/usr/local/hadoop/data/namenode/current/VERSION文件为空,进而start-dfs.sh启动NameNode时因找不到集群ID而静默退出。
标准操作流程:
# 创建专用用户(禁用shell,增强安全性) useradd -r -s /sbin/nologin hdfs # 创建数据目录并授权 mkdir -p /usr/local/hadoop/data/{namenode,datanode} chown -R hdfs:hdfs /usr/local/hadoop/data chmod 700 /usr/local/hadoop/data/namenode chmod 755 /usr/local/hadoop/data/datanode # 切换用户执行格式化(这才是关键!) sudo -u hdfs hdfs namenode -format3.4 核心配置文件:逐行解读与失效规避
Hadoop配置不是填空游戏,而是理解组件契约的过程。以下是最易出错的5个参数:
core-site.xml
<property> <name>fs.defaultFS</name> <value>hdfs://localhost:9000</value> <!-- 必须是localhost,不是127.0.0.1!因为Hadoop内部RPC解析依赖hostname --> </property> <property> <name>hadoop.tmp.dir</name> <value>/usr/local/hadoop/tmp</value> <!-- 此目录必须存在且hdfs用户可写,否则所有操作报"Permission denied" --> </property>hdfs-site.xml
<property> <name>dfs.namenode.name.dir</name> <value>file:///usr/local/hadoop/data/namenode</value> <!-- file://前缀不可省略,否则Hadoop认为是HDFS URI --> </property> <property> <name>dfs.datanode.data.dir</name> <value>file:///usr/local/hadoop/data/datanode</value> </property> <property> <name>dfs.replication</name> <value>1</value> <!-- 伪分布式必须设为1,设为3会导致DataNode因找不到其他副本节点而拒绝注册 --> </property>yarn-site.xml
<property> <name>yarn.nodemanager.aux-services</name> <value>mapreduce_shuffle</value> <!-- 值必须严格匹配,多空格或大小写错误都会导致MR任务无法提交 --> </property> <property> <name>yarn.resourcemanager.hostname</name> <value>localhost</value> <!-- 同样必须是localhost,与core-site.xml的fs.defaultFS保持一致 --> </property>mapred-site.xml
<property> <name>mapreduce.framework.name</name> <value>yarn</value> <!-- 若写成YARN或yarn-client,MapReduce作业会fallback到本地模式,永远不走YARN --> </property>实操心得:每次修改配置后,必须执行
hdfs namenode -format(仅NameNode配置变更时)或stop-dfs.sh && stop-yarn.sh再start-dfs.sh && start-yarn.sh。切勿只重启单个进程——Hadoop进程间有强状态依赖,比如ResourceManager启动时会向NodeManager发送心跳注册请求,若NodeManager未重启,它会持续等待直到超时。
4. 完整实操流程与关键环节验证
4.1 环境初始化:从裸机到可用基座
假设你有一台全新安装的CentOS 7.9最小化系统(内存≥4G,磁盘≥20G),执行以下步骤:
Step 1:关闭干扰项
# 关闭防火墙(教学环境首选,生产环境应精细放行端口) systemctl stop firewalld && systemctl disable firewalld # 关闭SELinux(临时方案,避免avc denied日志淹没关键错误) setenforce 0 sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config # 禁用NetworkManager(它会劫持/etc/resolv.conf,导致hostname解析异常) systemctl stop NetworkManager && systemctl disable NetworkManagerStep 2:安装基础依赖
yum install -y wget vim net-tools lsof which rsync # 验证:which ssh && which rsync && which lsof 必须全部返回路径Step 3:部署Java(如前所述)
# 执行3.1节全部操作,完成后验证 java -version # 输出应为 java version "1.8.0_362" $JAVA_HOME/bin/java -version # 同上Step 4:部署Hadoop
# 下载Hadoop 3.3.6二进制包 wget https://downloads.apache.org/hadoop/common/hadoop-3.3.6/hadoop-3.3.6.tar.gz tar -zxvf hadoop-3.3.6.tar.gz -C /usr/local/ ln -s /usr/local/hadoop-3.3.6 /usr/local/hadoop # 设置HADOOP_HOME echo 'export HADOOP_HOME=/usr/local/hadoop' >> /etc/profile.d/hadoop.sh echo 'export PATH=$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$PATH' >> /etc/profile.d/hadoop.sh source /etc/profile.d/hadoop.sh4.2 配置文件编写:手把手逐行录入
进入/usr/local/hadoop/etc/hadoop/目录,用vim编辑以下文件:
core-site.xml(覆盖原内容)
<?xml version="1.0" encoding="UTF-8"?> <?xml-stylesheet type="text/xsl" href="configuration.xsl"?> <configuration> <property> <name>fs.defaultFS</name> <value>hdfs://localhost:9000</value> </property> <property> <name>hadoop.tmp.dir</name> <value>/usr/local/hadoop/tmp</value> </property> </configuration>hdfs-site.xml(覆盖原内容)
<?xml version="1.0" encoding="UTF-8"?> <?xml-stylesheet type="text/xsl" href="configuration.xsl"?> <configuration> <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> <property> <name>dfs.replication</name> <value>1</value> </property> </configuration>yarn-site.xml(覆盖原内容)
<?xml version="1.0" encoding="UTF-8"?> <?xml-stylesheet type="text/xsl" href="configuration.xsl"?> <configuration> <property> <name>yarn.nodemanager.aux-services</name> <value>mapreduce_shuffle</value> </property> <property> <name>yarn.resourcemanager.hostname</name> <value>localhost</value> </property> </configuration>mapred-site.xml(先复制模板再修改)
cp mapred-site.xml.template mapred-site.xml # 编辑mapred-site.xml,添加以下内容 <property> <name>mapreduce.framework.name</name> <value>yarn</value> </property>workers文件(替换原内容,注意是workers,不是slaves)
# 删除所有内容,只留一行 localhost4.3 启动与验证:五层穿透式检测法
不要迷信jps命令。真正的验证必须分层穿透:
Layer 1:进程层(jps)
start-dfs.sh && start-yarn.sh jps # 正确输出应包含: # 12345 NameNode # 12346 DataNode # 12347 SecondaryNameNode # 12348 ResourceManager # 12349 NodeManager # 若缺少任一进程,立即看对应日志(如namenode.log)Layer 2:端口层(netstat)
netstat -tuln | grep -E ':(9000|9870|8088|8030|8031|8032|8033)' # 必须看到: # tcp6 0 0 :::9000 :::* LISTEN (NameNode RPC) # tcp6 0 0 :::9870 :::* LISTEN (NameNode WebUI) # tcp6 0 0 :::8088 :::* LISTEN (ResourceManager WebUI) # 若端口未监听,90%是配置文件路径错误或Java进程未真正启动Layer 3:日志层(tail -f)
# 实时盯住NameNode日志 tail -f $HADOOP_HOME/logs/hadoop-*-namenode-*.log # 成功启动标志:出现 "Startup ended" 和 "Registered with the service" 字样 # 若卡在 "Starting services",检查dfs.namenode.name.dir目录权限Layer 4:HDFS命令层(hdfs dfs)
# 创建根目录(验证NameNode可写) hdfs dfs -mkdir -p /user/root # 上传测试文件(验证DataNode可写) echo "hello hadoop" > /tmp/test.txt hdfs dfs -put /tmp/test.txt /user/root/ # 查看文件(验证读取通路) hdfs dfs -cat /user/root/test.txt # 输出应为 hello hadoopLayer 5:YARN应用层(yarn)
# 运行经典WordCount(验证MR框架) hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-*.jar wordcount /user/root/test.txt /user/root/output # 检查输出 hdfs dfs -cat /user/root/output/part-r-00000 # 输出应为 hello 1 # 同时访问 http://localhost:8088/cluster/apps 可看到Running状态的应用实测记录:某次部署中,
hdfs dfs -ls /返回空列表,但jps显示所有进程正常。经五层检测发现,Layer 2中9000端口未监听,Layer 3日志显示"Failed to load native library"。最终定位到$HADOOP_HOME/lib/native/下libhadoop.so的glibc版本不匹配(CentOS 7.9需glibc 2.17,而该so链接了2.28)。解决方案:从Hadoop源码重新编译native lib,或降级到Hadoop 3.3.4(其so兼容2.17)。
5. 常见问题与排查技巧实录
5.1 典型问题速查表
| 现象 | 可能原因 | 排查命令 | 解决方案 |
|---|---|---|---|
start-dfs.sh后jps无NameNode进程 | JAVA_HOME路径错误,或hadoop.tmp.dir目录不存在 | echo $JAVA_HOMEls -ld /usr/local/hadoop/tmp | 确保JAVA_HOME指向JDK根目录mkdir -p /usr/local/hadoop/tmp && chown hdfs:hdfs /usr/local/hadoop/tmp |
| WebUI(9870端口)打不开,但jps有NameNode | NameNode未真正启动,或防火墙拦截 | netstat -tuln | grep :9870curl -I http://localhost:9870 | 若netstat无输出,查$HADOOP_HOME/logs/hadoop-*-namenode-*.logsystemctl stop firewalld |
hdfs dfs -ls /报Connection refused | fs.defaultFS配置为hdfs://127.0.0.1:9000,而Hadoop内部解析localhost失败 | cat $HADOOP_HOME/etc/hadoop/core-site.xml | grep fs.defaultFS | 改为hdfs://localhost:9000,并确认/etc/hosts中127.0.0.1 localhost存在 |
yarn node -list返回空列表 | yarn-site.xml中yarn.resourcemanager.hostname未设为localhost,或NodeManager未启动 | jps | grep NodeManagercat $HADOOP_HOME/etc/hadoop/yarn-site.xml | grep hostname | 确保yarn.resourcemanager.hostname值为localhoststop-yarn.sh && start-yarn.sh |
| WordCount任务卡在ACCEPTED状态 | ResourceManager未收到NodeManager心跳,或yarn.nodemanager.aux-services值错误 | yarn node -listcat $HADOOP_HOME/etc/hadoop/yarn-site.xml | grep aux-services | 确保yarn.nodemanager.aux-services值为mapreduce_shuffle(严格大小写) |
5.2 独家避坑技巧
技巧1:日志过滤黄金组合Hadoop日志动辄上万行,直接cat等于自杀。高效过滤法:
# 只看ERROR和FATAL级别(排除INFO干扰) grep -E "(ERROR|FATAL)" $HADOOP_HOME/logs/hadoop-*-namenode-*.log | head -20 # 查看最近10分钟的启动日志(利用时间戳) awk -v d1="$(date -d '10 minutes ago' '+%Y-%m-%d %H:%M')" -v d2="$(date '+%Y-%m-%d %H:%M')" '$0 > d1 && $0 < d2 || $0 ~ d2' $HADOOP_HOME/logs/hadoop-*-namenode-*.log技巧2:端口冲突一键扫描Hadoop默认端口常被其他服务占用(如MySQL占3306,Tomcat占8080)。启动前快速扫描:
for port in 9000 9870 8088 8030 8031 8032 8033; do if ss -tuln \| grep ":$port" > /dev/null; then echo "PORT $port IS OCCUPIED"; fi; done技巧3:配置文件语法校验XML格式错误(如未闭合标签)会导致Hadoop静默失败。用xmllint验证:
yum install -y libxml2 xmllint --noout $HADOOP_HOME/etc/hadoop/core-site.xml 2>&1 || echo "core-site.xml has syntax error"技巧4:进程启动超时调优若机器性能较弱(如虚拟机内存<2G),NameNode启动可能超时。修改$HADOOP_HOME/etc/hadoop/hadoop-env.sh:
# 在文件末尾添加 export HADOOP_NAMENODE_OPTS="-Xms512m -Xmx1024m -XX:ParallelGCThreads=2 $HADOOP_NAMENODE_OPTS" export HADOOP_DATANODE_OPTS="-Xms256m -Xmx512m $HADOOP_DATANODE_OPTS"5.3 我踩过的三个深坑
坑1:/etc/hosts里的空行引发的血案
某次在/etc/hosts末尾多加了一个空行,导致hdfs namenode -format执行后/usr/local/hadoop/data/namenode/current/VERSION文件为空。排查三天,最终用strace -e trace=openat hdfs namenode -format 2>&1 \| grep VERSION发现Hadoop在解析hosts时,空行被当作hostname处理,导致内部host lookup失败。解决方案:sed -i '/^$/d' /etc/hosts。
坑2:hadoop.tmp.dir路径含空格
为图方便,我把临时目录设为/usr/local/hadoop data/tmp(含空格)。结果所有HDFS命令报No FileSystem for scheme: hdfs。因为Hadoop配置解析器将空格后的data/tmp误认为另一个属性值。教训:路径中永远不要用空格,用下划线代替。
坑3:workers文件编码为UTF-8 BOM
用Windows记事本编辑workers文件后上传,文件头部多了BOM(\xef\xbb\xbf),导致start-dfs.sh读取时把localhost识别为<BOM>localhost,SSH连接失败。解决方案:dos2unix workers或iconv -f UTF-8 -t UTF-8//IGNORE workers > workers.new。
6. 后续演进与能力延伸
完成伪分布式部署只是起点。接下来你可以按此路径深化:
阶段1:单机高可用(HA)
在单机上模拟NameNode HA:部署两个NameNode(nn1/nn2),一个JournalNode,用QJM(Quorum Journal Manager)替代本地文件系统存储edit log。这能让你彻底理解ZKFC(ZKFailoverController)如何通过ZooKeeper选举Active NN,以及hdfs haadmin -failover命令的底层机制。
阶段2:容器化封装
用Docker将Hadoop伪分布式环境打包。关键在于:--network host模式保证localhost解析一致性;-v挂载数据目录时用chown 1001:1001预设hdfs用户UID;entrypoint脚本中加入ssh-keygen -A && /usr/sbin/sshd启动SSH服务。这样你就能docker run -d -p 9870:9870 hadoop-pseudo一键启停,彻底告别环境污染。
阶段3:监控体系接入
集成Prometheus+Grafana:通过Hadoop自带的JMX Exporter(hadoop-metrics2.properties配置*.sink.prometheus.class=org.apache.hadoop.metrics2.sink.prometheus.PrometheusSink),暴露hadoop_namenode_capacity_used_pcent等200+指标。你会发现,dfs.datanode.du.reserved参数设置不当,会导致DataNode磁盘使用率虚高,触发Balancer误判。
最后分享一个小技巧:每次成功部署后,执行hadoop distcp -update hdfs://localhost:9000/ hdfs://localhost:9000/backup,把整个HDFS快照备份到backup目录。这不是为了容灾,而是建立你的“认知快照”——当你后续修改配置导致环境崩坏,只需hdfs dfs -rm -r / && hdfs dfs -cp /backup/* /,30秒回到最初成功的状态。学习分布式系统,不怕犯错,怕的是无法归零重来。