最近在学习大数据技术,第一个拦路虎就是搭建Hadoop集群。说实话,刚开始我觉得这有什么难的,跟着教程一步步敲命令不就完了?结果这一敲就是整整一天,踩了无数坑,从“Permission denied”到“Connection refused”,从“JAVA_HOME not set”到“NameNode format失败”,简直是把所有能踩的坑都踩了一遍。
但回过头来看,这些坑反而是最宝贵的经验。今天就把我这一天的心路历程记录下来,希望能帮助同样在学习Hadoop的朋友们少走弯路。
问题一:权限问题,永远的Permission denied
遇到的情况
我按照教程,用hadoop用户执行命令:
bash
hadoop fs -mkdir -p /input
结果给我返回:
text
mkdir: Permission denied: user=hadoop, access=WRITE, inode="/":root:supergroup:drwxr-xr-x
当时我就懵了,明明是按照教程一步步来的,怎么就没权限了呢?
问题分析
这个问题暴露了我对Linux权限机制理解的不足。HDFS虽然是一个分布式文件系统,但它依然遵循Linux的权限模型。根目录/是root用户的,普通用户hadoop当然没有写入权限。
更深一层想,这说明我对HDFS的目录结构理解不够。HDFS有自己的用户目录体系,就像Linux的/home一样,普通用户应该在/user目录下有自己的空间。
解决过程
刚开始我的解决思路很粗暴:把根目录权限改成777:
bash
hdfs dfs -chmod 777 /
但仔细一想,这太危险了,而且治标不治本。正确的做法是:
创建用户目录
把用户目录的owner改成hadoop用户
让用户在自己的目录下操作
bash
# root用户执行
hdfs dfs -mkdir -p /user/hadoop
hdfs dfs -chown -R hadoop:hadoop /user/hadoop
hdfs dfs -chmod 755 /user/hadoop
# 然后hadoop用户就可以愉快地操作了
hdfs dfs -mkdir -p /user/hadoop/input
hdfs dfs -put test.txt /user/hadoop/input/
心得
这件事给我的启发很大:不要用root用户跑应用,这是基本的安全原则。每个用户应该有自己的独立空间,这不仅是为了安全,也是为了更好的资源隔离。
另外,遇到权限问题第一反应不应该是“把权限放大”,而是要思考“合理的权限分配应该是怎样的”。这不仅是技术问题,更是一种思维方式。
问题二:服务启动成功,但jps看不到进程
遇到的情况
执行完./start-dfs.sh和./start-yarn.sh后,看到一堆输出,感觉应该是成功了。结果一查:
bash
jps
656 Jps
只有一个Jps进程?其他进程呢?
问题分析
开始我以为是自己操作错了,反复启动停止了好几次。直到仔细看启动日志才发现问题:
text
hadoop1: /app/hadoop/hadoop-2.6.4/sbin/hadoop-daemon.sh: line 159:
/app/hadoop/hadoop-2.6.4/logs/hadoop-hadoop-namenode-hadoop1.out: Permission denied
原来是日志目录的权限问题。hadoop用户没有权限写日志文件,导致进程启动失败。
解决过程
这个问题让我意识到,不仅是数据目录,日志目录也需要正确的权限。
bash
# root用户执行
chown -R hadoop:hadoop /app/hadoop/hadoop-2.6.4/logs
chown -R hadoop:hadoop /app/hadoop/hadoop-2.6.4
# 还要同步到其他节点
ssh hadoop2 "chown -R hadoop:hadoop /app/hadoop/hadoop-2.6.4"
ssh hadoop3 "chown -R hadoop:hadoop /app/hadoop/hadoop-2.6.4"
改完权限后,再启动服务,终于看到了完整的进程列表:
-
NameNode
-
DataNode
-
SecondaryNameNode
-
ResourceManager
-
NodeManager
心得
这个问题教会我:遇到问题不要只看表象,要深入看日志。启动失败的原因往往藏在日志文件里。
同时,这也让我理解了Hadoop的服务架构:
-
NameNode:管理文件系统命名空间
-
DataNode:存储实际数据
-
ResourceManager:管理计算资源
-
NodeManager:管理单个节点的计算任务
每一个进程都有明确的职责,这样的设计让系统更加健壮。
问题三:JAVA_HOME
遇到的情况
这个问题最诡异。我在hadoop1上配置了JAVA_HOME,启动服务也正常。但是登录hadoop2一查:
bash
ssh hadoop2 "echo \\$JAVA_HOME"
# 返回空
奇怪了,明明每台机器都配置了啊。
问题分析
经过排查,我发现问题出在配置文件的生效范围上。我是在/etc/profile里配置的JAVA_HOME,但这个文件在SSH非登录shell模式下不会生效。
更关键的是,Hadoop有自己的配置文件hadoop-env.sh,这个文件里的配置对Hadoop服务才是最重要的。
解决过程
解决方案是在每个节点的hadoop-env.sh里显式指定JAVA_HOME:
bash
# 编辑hadoop-env.sh
export JAVA_HOME=/usr/lib/java/jdk1.7.0_79
# 同步到其他节点
scp hadoop-env.sh hadoop@hadoop2:/app/hadoop/hadoop-2.6.4/etc/hadoop/
scp hadoop-env.sh hadoop@hadoop3:/app/hadoop/hadoop-2.6.4/etc/hadoop/
同时,为了日常使用的便利性,也要在每个用户的.bashrc里配置JAVA_HOME:
bash
echo "export JAVA_HOME=/usr/lib/java/jdk1.7.0_79" >> ~/.bashrc
echo "export PATH=\\$PATH:\\$JAVA_HOME/bin" >> ~/.bashrc
source ~/.bashrc
心得
这个问题让我理解了Linux中环境变量的作用域:
-
/etc/profile:系统级,登录shell生效
-
~/.bashrc:用户级,每次打开终端生效
-
hadoop-env.sh:Hadoop服务级,对Hadoop进程生效
不同的配置有不同的作用范围,要根据实际需求选择合适的配置位置。
问题四:SSH免密码登录的配置时机
遇到的情况
在启动HDFS时,系统不断提示输入密码:
text
root@hadoop1's password:
hadoop2's password:
hadoop3's password:
每次启动都要输入密码,这显然不行。
问题分析
SSH免密码登录是Hadoop集群正常运行的基础。因为Hadoop需要通过SSH在各个节点间启停进程,如果没有免密码登录,整个集群就无法正常工作。
解决过程
配置SSH免密码登录其实很简单,但要理解其中的原理:
bash
# 1. 生成密钥对
ssh-keygen -t rsa
# 一路回车,会在~/.ssh目录生成id_rsa(私钥)和id_rsa.pub(公钥)
# 2. 把公钥复制到需要访问的机器
ssh-copy-id hadoop@hadoop1
ssh-copy-id hadoop@hadoop2
ssh-copy-id hadoop@hadoop3
# 需要输入密码,这是唯一一次需要密码的地方
原理其实很简单:你的机器持有私钥,目标机器的authorized_keys文件里存有你的公钥。当你SSH连接时,目标机器会用公钥加密一个随机数发给你,你用私钥解密后发回,这样就验证了你的身份。
心得
SSH免密码登录看似简单,但它是分布式系统的基石。理解了它的原理,以后配置其他分布式系统也会更得心应手。
另外,一个细节是.ssh目录的权限必须是700,authorized_keys文件的权限必须是600,否则SSH会拒绝使用。这体现了安全机制对文件权限的严格要求。
问题五:NameNode格式化,一次就够了
遇到的情况
在折腾的过程中,我多次格式化NameNode,结果发现DataNode启动不了。查看日志,发现DataNode的cluster ID和NameNode的不一致。
问题分析
每次格式化NameNode,都会生成一个新的cluster ID。但DataNode的cluster ID是在第一次连接NameNode时确定的,之后就不会改变。如果NameNode的cluster ID变了,DataNode就会拒绝连接。
解决过程
解决方案有两种:
删除DataNode上的数据目录,让DataNode重新获取cluster ID:
bash
rm -rf /app/hadoop/hadoop-2.6.4/data/*
更简单的做法:只在第一次安装时格式化一次,之后除非要彻底重建集群,否则不要再次格式化。
心得
这个问题的教训是:有些操作是不可逆的,要慎重。NameNode格式化就是这样,它会清空所有元数据,相当于把整个文件系统重置了。
这让我想到,在生产环境中,NameNode的数据是极其宝贵的,需要定期备份。一旦丢失,整个集群的数据就找不回来了。
最终验证:WordCount的成功时刻
经历了以上种种问题,当最后看到WordCount成功输出时,那种成就感是无法言喻的。
bash
great 1
hadoop 3
hello 3
is 1
of 1
world 3
这简单的几行输出,背后是整个Hadoop集群的正常运行。从硬件准备到系统配置,从SSH免密码到环境变量设置,从权限分配到服务启动,每一个环节都不可或缺。
总结
一天的时间,踩了无数的坑,但也学到了很多:
权限问题:理解Linux的权限模型,不要把简单问题复杂化
日志先行:遇到问题第一时间看日志,不要瞎猜
环境变量:理解不同配置文件的生效范围
基础组件:SSH、Java这些基础组件要配置正确
操作慎重:有些操作(如格式化)是不可逆的,要三思而后行
最重要的是,我学会了独立思考。遇到问题时,不再只是机械地跟着教程走,而是会想:为什么会出错?应该怎么解决?有没有更好的方法?
这就是学习的意义所在。共勉!
网硕互联帮助中心



评论前必须登录!
注册