云计算百科
云计算领域专业知识百科平台

Hadoop集群搭建踩坑全记录

最近在学习大数据技术,第一个拦路虎就是搭建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这些基础组件要配置正确

  • 操作慎重:有些操作(如格式化)是不可逆的,要三思而后行

  • 最重要的是,我学会了独立思考。遇到问题时,不再只是机械地跟着教程走,而是会想:为什么会出错?应该怎么解决?有没有更好的方法?

    这就是学习的意义所在。共勉!

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » Hadoop集群搭建踩坑全记录
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!