1. 环境准备与规划:为你的Hadoop集群打好地基

搭建一个稳定可靠的Hadoop集群,就像盖房子,地基打得好,后面才能省心。这次我们用的是三台CentOS 7的服务器,规划成一个NameNode(主节点)和两个DataNode(数据节点)。很多新手朋友一开始就急着敲命令,结果网络不通、权限不对,折腾半天又得重来。我建议你先花十分钟,把下面这几步规划清楚,后面能少踩80%的坑。

首先,你得明确每台机器的角色。我们这里用三台机器,IP和主机名分配如下:

  • Master (192.168.21.25):这台机器身兼多职,它既是NameNode(负责管理文件系统的元数据),也是ResourceManager(负责YARN的资源调度)。简单理解,它就是集群的“大脑”和“调度中心”。
  • Slave01 (192.168.21.26):第一个DataNode,负责存储实际的数据块,同时也是SecondaryNameNode。这个SecondaryNameNode可不是NameNode的热备,它主要帮NameNode做检查点合并,防止编辑日志文件过大,你可以把它理解为“秘书”,帮忙整理文件。
  • Slave02 (192.168.21.27):第二个DataNode,纯纯的数据存储节点。

为什么是3个DataNode?因为Hadoop默认的数据副本数就是3,这样一份数据会在集群里存三份,任何一台机器挂了,数据都不会丢,可靠性非常高。这个架构对于学习和中小规模生产环境都足够了。

硬件方面,CentOS 7建议最小化安装,干净。内存我给个参考:Master节点建议4G以上,Slave节点2G以上。磁盘空间嘛,DataNode当然是越大越好,但学习环境每台有个20G也够用了。最关键的是网络,确保这三台机器在同一个局域网内,能互相ping通,防火墙要么关闭,要么把需要用到的端口(像9000,50070,8088这些)都打开。

注意:在生产环境,NameNode和ResourceManager通常会分开部署在不同的机器上,以避免单点故障和资源竞争。我们这里为了简化学习和测试,放在了一起。如果你资源充足,用四台机器来部署是更理想的方案。

2. 基础系统配置:让三台机器“认亲”并畅通无阻

机器准备好了,但它们现在还是“陌生人”,互相不认识。我们得让它们在一个“家庭”里,并且能免密码串门。这一步是后续所有操作的基础,务必做扎实。

2.1 配置静态主机名与Hosts映射

CentOS 7默认的主机名是localhost.localdomain,这不利于我们管理。我们先给每台机器起个固定的、有意义的名字。在每台服务器上执行:

# 在Master节点上
hostnamectl set-hostname master
# 在Slave01节点上
hostnamectl set-hostname slave01
# 在Slave02节点上
hostnamectl set-hostname slave02

设置完后,断开SSH重新连接,或者执行bash让新主机名生效,用hostname命令检查一下。接下来是关键的一步:修改/etc/hosts文件。这个文件相当于集群内部的“通讯录”,通过主机名就能找到对应的IP地址,比直接记IP方便多了,而且配置文件里用主机名也更清晰。

不要在每台机器上只写自己的信息! 我见过有人只在Master的hosts里加了Master的映射,结果根本连不上Slave。正确的做法是,三台机器的/etc/hosts文件内容要完全一致。我们统一编辑这个文件:

vi /etc/hosts

在文件末尾添加以下三行(请确保IP地址和你机器的实际IP一致):

192.168.21.25 master
192.168.21.26 slave01
192.168.21.27 slave02

编辑完成后,保存退出。然后,分别在每台机器上,用ping命令测试一下连通性,这是验证配置是否成功的土办法但最有效:

ping master -c 3
ping slave01 -c 3
ping slave02 -c 3

如果都能收到回复,说明网络和主机名解析都正常了。这里有个小技巧,你可以用scp命令把Master配置好的hosts文件直接拷贝到两个Slave节点,省去重复编辑的麻烦:scp /etc/hosts root@slave01:/etc/scp /etc/hosts root@slave02:/etc/

2.2 配置SSH免密登录:实现“一把钥匙开所有门”

Hadoop集群启动和管理时,主节点(Master)需要能无密码登录到所有从节点(Slave)去启动进程。如果每次都要输密码,那全自动启动就无从谈起了。配置SSH免密登录,就是给Master配一把万能钥匙。

所有后续操作,如无特别说明,都在Master节点上进行。 首先,我们生成RSA密钥对:

# 切换到当前用户的.ssh目录,如果不存在会自动创建
cd ~/.ssh
# 如果之前生成过密钥,可以先删除(可选)
rm -f id_rsa id_rsa.pub
# 生成密钥对,执行下面命令后,连续按三次回车即可,不要设置密码短语(passphrase)
ssh-keygen -t rsa

生成后,id_rsa是私钥,自己保管好;id_rsa.pub是公钥,可以发给别人。接下来,我们把公钥追加到本机的授权文件里,实现Master自己能无密码登录自己:

cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
# 修改authorized_keys文件的权限,这一步非常重要,权限不对会导致免密失败
chmod 600 ~/.ssh/authorized_keys

现在测试一下:ssh master,应该不需要输入密码就直接登录了(第一次可能会问是否信任主机,输入yes就行)。接下来,要把Master的公钥分发到两个Slave节点。我们采用一个更稳妥的方法,先手动创建目录,再拷贝:

# 在Slave01和Slave02上创建.ssh目录(如果不存在)
ssh slave01 "mkdir -p ~/.ssh"
ssh slave02 "mkdir -p ~/.ssh"

# 将Master的公钥文件拷贝到Slave节点
scp ~/.ssh/id_rsa.pub root@slave01:~/.ssh/master.pub
scp ~/.ssh/id_rsa.pub root@slave02:~/.ssh/master.pub

# 分别登录到Slave节点,将公钥加入授权文件
ssh slave01 "cat ~/.ssh/master.pub >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"
ssh slave02 "cat ~/.ssh/master.pub >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"

最后,在Master上测试免密登录是否成功:

ssh slave01
# 登录成功后,执行个简单命令如 `hostname`,确认是slave01,然后退出
exit
ssh slave02
exit

如果能顺畅登录退出,恭喜你,SSH通道已经打通了!这一步的坑主要在于文件权限(authorized_keys必须是600)和目录是否存在,按上面的步骤走,基本没问题。

3. JDK安装与环境变量配置:Hadoop的运行基石

Hadoop是Java写的,所以JDK是必须的。原始文章里用了yum install java-1.8.0-openjdk,这确实方便,但有个问题:OpenJDK的jps命令(用来查看Java进程)默认不包含在基础包里,而我们在排查Hadoop进程时,jps是非常常用的工具。所以,我的建议是:要么用Oracle JDK,要么就按下面方法把OpenJDK的开发包也装上。

3.1 安装JDK 8

我们统一在三台机器上安装JDK 8。Hadoop 3.3.x版本对JDK 8兼容性最好。在每台服务器上执行:

# 1. 安装OpenJDK 8运行时环境和开发工具包
yum install -y java-1.8.0-openjdk java-1.8.0-openjdk-devel

# 2. 验证安装
java -version
# 应该输出类似:openjdk version "1.8.0_382"
javac -version
# 验证编译器,输出版本号

3.2 定位JAVA_HOME并配置环境变量

yum安装的JDK,其路径不像直接下载的tar包那么直观,需要我们找一下。执行以下命令来定位:

which java
# 输出可能是:/usr/bin/java
ls -l /usr/bin/java
# 输出是一个软链接,指向 /etc/alternatives/java
ls -l /etc/alternatives/java
# 这个软链接最终指向实际的Java安装路径,例如:
# /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.382.b05-1.el7_9.x86_64/jre/bin/java

我们需要的是JAVA_HOME,即去掉末尾的/jre/bin/java。以上面路径为例,JAVA_HOME应该是:/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.382.b05-1.el7_9.x86_64。为了确保准确,可以用一个取巧的方法:

dirname $(dirname $(readlink -f $(which java)))

这个命令链会解析出Java可执行文件的真实路径,然后向上回退两级目录,得到的就是JAVA_HOME。记下这个路径。

接下来,配置全局环境变量。编辑/etc/profile文件:

vi /etc/profile

在文件末尾添加以下内容(请将JAVA_HOME的值替换为你刚才找到的实际路径):

export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.382.b05-1.el7_9.x86_64
export JRE_HOME=$JAVA_HOME/jre
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib
export PATH=$PATH:$JAVA_HOME/bin

保存退出后,让配置立即生效:source /etc/profile。然后验证:

echo $JAVA_HOME
java -version

如果正确输出了路径和版本号,说明JDK配置成功。最后,别忘了在Slave01和Slave02节点上重复3.1和3.2的所有步骤,确保集群所有节点JDK环境一致。你可以用scp/etc/profile文件从Master拷贝过去,然后source一下,但前提是JDK安装路径完全相同。如果路径不同,还是老老实实每台机器单独配置。

4. Hadoop安装与核心文件配置:赋予集群灵魂

基础环境搞定,现在可以请出主角——Hadoop了。我们将从官网下载Hadoop 3.3.4,进行解压和基础配置。

4.1 下载与安装Hadoop

Master节点上操作:

# 1. 创建一个统一的安装目录,比如 /opt/hadoop
mkdir -p /opt/hadoop
cd /opt/hadoop

# 2. 下载Hadoop 3.3.4。如果wget速度慢,可以先用浏览器下载到本地,再用scp上传。
wget https://archive.apache.org/dist/hadoop/common/hadoop-3.3.4/hadoop-3.3.4.tar.gz
# 或者使用国内镜像(如清华镜像)可能更快
# wget https://mirrors.tuna.tsinghua.edu.cn/apache/hadoop/common/hadoop-3.3.4/hadoop-3.3.4.tar.gz

# 3. 解压
tar -xzvf hadoop-3.3.4.tar.gz

# 4. 配置Hadoop环境变量
vi /etc/profile

/etc/profile文件末尾,JDK配置的后面,添加Hadoop的环境变量:

export HADOOP_HOME=/opt/hadoop/hadoop-3.3.4
export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin
export HADOOP_CONF_DIR=$HADOOP_HOME/etc/hadoop
export HADOOP_MAPRED_HOME=$HADOOP_HOME
export HADOOP_COMMON_HOME=$HADOOP_HOME
export HADOOP_HDFS_HOME=$HADOOP_HOME
export YARN_HOME=$HADOOP_HOME

保存退出,执行source /etc/profile。现在可以测试一下:hadoop version,应该能看到Hadoop 3.3.4的版本信息。

4.2 配置Hadoop-env.sh与创建必要目录

首先,告诉Hadoop我们的JDK在哪里。编辑$HADOOP_HOME/etc/hadoop/hadoop-env.sh文件:

vi $HADOOP_HOME/etc/hadoop/hadoop-env.sh

找到export JAVA_HOME=这一行,去掉注释,并设置为我们之前找到的路径:

export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.382.b05-1.el7_9.x86_64

同时,为了避免后续启动时的权限警告(生产环境不建议用root,但学习环境可以简化),可以在文件末尾添加:

export HDFS_NAMENODE_USER=root
export HDFS_DATANODE_USER=root
export HDFS_SECONDARYNAMENODE_USER=root
export YARN_RESOURCEMANAGER_USER=root
export YARN_NODEMANAGER_USER=root

接着,创建Hadoop运行所需的临时目录和数据目录。我们在/opt/hadoop下创建:

mkdir -p /opt/hadoop/tmp    # Hadoop临时文件目录
mkdir -p /opt/hadoop/hdfs/name # NameNode元数据存储目录
mkdir -p /opt/hadoop/hdfs/data # DataNode数据块存储目录

这些目录路径后面在配置文件里会用到。

4.3 详解四大核心配置文件

这是Hadoop配置的核心部分,理解每个参数的意义比死记硬背更重要。所有配置文件都在$HADOOP_HOME/etc/hadoop/目录下。

1. core-site.xml:全局核心配置 这个文件定义了Hadoop最基础的属性,比如文件系统默认的访问地址和临时目录。

<configuration>
    <property>
        <!-- 指定HDFS的默认访问地址和端口。NameNode就运行在这个地址上 -->
        <name>fs.defaultFS</name>
        <value>hdfs://master:9000</value>
    </property>
    <property>
        <!-- Hadoop临时文件目录,用于存储NameNode、DataNode等的运行时数据 -->
        <name>hadoop.tmp.dir</name>
        <value>/opt/hadoop/tmp</value>
    </property>
    <property>
        <!-- 设置HDFS数据存储的基础路径,DataNode会在此路径下创建子目录存储数据块 -->
        <name>hadoop.data.dir</name>
        <value>/opt/hadoop/hdfs/data</value>
    </property>
</configuration>

2. hdfs-site.xml:HDFS分布式文件系统配置 这个文件专门配置HDFS相关的参数,比如副本数、Web UI端口等。

<configuration>
    <property>
        <!-- 数据块的副本数量。我们集群有2个DataNode,但设为3意味着如果未来增加节点,会自动按3副本存储。
             对于当前2节点,实际只能存2个副本,日志会有警告,但可以运行。 -->
        <name>dfs.replication</name>
        <value>3</value>
    </property>
    <property>
        <!-- NameNode的Web管理界面地址和端口,用于在浏览器查看集群状态 -->
        <name>dfs.namenode.http-address</name>
        <value>master:9870</value>
        <!-- 注意:Hadoop 3.x版本默认端口已从50070改为9870 -->
    </property>
    <property>
        <!-- SecondaryNameNode的HTTP地址和端口。它辅助NameNode工作,我们将其部署在slave01 -->
        <name>dfs.namenode.secondary.http-address</name>
        <value>slave01:9868</value>
        <!-- 注意:Hadoop 3.x版本默认端口已从50090改为9868 -->
    </property>
    <property>
        <!-- NameNode元数据存储目录,非常重要!格式化NameNode后会产生文件 -->
        <name>dfs.namenode.name.dir</name>
        <value>file:///opt/hadoop/hdfs/name</value>
    </property>
    <property>
        <!-- DataNode数据块存储目录,可以配置多个用逗号分隔,实现多磁盘存储 -->
        <name>dfs.datanode.data.dir</name>
        <value>file:///opt/hadoop/hdfs/data</value>
    </property>
</configuration>

3. mapred-site.xml:MapReduce计算框架配置 这个文件告诉Hadoop使用哪种资源管理框架来运行MapReduce作业。现在主流是YARN。

<configuration>
    <property>
        <!-- 指定MapReduce作业运行在YARN框架上 -->
        <name>mapreduce.framework.name</name>
        <value>yarn</value>
    </property>
    <property>
        <!-- MapReduce作业历史服务器地址,便于查看已完成的作业详情 -->
        <name>mapreduce.jobhistory.address</name>
        <value>master:10020</value>
    </property>
    <property>
        <!-- 历史服务器Web UI地址 -->
        <name>mapreduce.jobhistory.webapp.address</name>
        <value>master:19888</value>
    </property>
</configuration>

4. yarn-site.xml:YARN资源管理器配置 YARN负责集群的资源管理和作业调度。

<configuration>
    <property>
        <!-- NodeManager上运行的附属服务,需要配置成mapreduce_shuffle才能运行MapReduce程序 -->
        <name>yarn.nodemanager.aux-services</name>
        <value>mapreduce_shuffle</value>
    </property>
    <property>
        <!-- 指定ResourceManager运行在哪台机器上 -->
        <name>yarn.resourcemanager.hostname</name>
        <value>master</value>
    </property>
    <property>
        <!-- ResourceManager的Web UI地址 -->
        <name>yarn.resourcemanager.webapp.address</name>
        <value>master:8088</value>
    </property>
    <property>
        <!-- 这个配置在Hadoop 3.x很重要,指定YARN应用使用的classpath,避免找不到类 -->
        <name>yarn.application.classpath</name>
        <value>
            /opt/hadoop/hadoop-3.3.4/etc/hadoop:/opt/hadoop/hadoop-3.3.4/share/hadoop/common/lib/*:/opt/hadoop/hadoop-3.3.4/share/hadoop/common/*:/opt/hadoop/hadoop-3.3.4/share/hadoop/hdfs:/opt/hadoop/hadoop-3.3.4/share/hadoop/hdfs/lib/*:/opt/hadoop/hadoop-3.3.4/share/hadoop/hdfs/*:/opt/hadoop/hadoop-3.3.4/share/hadoop/mapreduce/*:/opt/hadoop/hadoop-3.3.4/share/hadoop/mapreduce/lib/*:/opt/hadoop/hadoop-3.3.4/share/hadoop/yarn:/opt/hadoop/hadoop-3.3.4/share/hadoop/yarn/lib/*:/opt/hadoop/hadoop-3.3.4/share/hadoop/yarn/*
        </value>
    </property>
    <property>
        <!-- 允许YARN容器使用物理内存检查,学习环境可关闭以简化 -->
        <name>yarn.nodemanager.pmem-check-enabled</name>
        <value>false</value>
    </property>
    <property>
        <name>yarn.nodemanager.vmem-check-enabled</name>
        <value>false</value>
    </property>
</configuration>

5. workers文件(旧版本是slaves) 这个文件列出了所有DataNode节点(即工作节点)的主机名。编辑$HADOOP_HOME/etc/hadoop/workers文件:

slave01
slave02

注意,Hadoop 3.x中,master不应该写在这个文件里,除非它同时也是DataNode(这不常见)。我们这里Master只作为NameNode和ResourceManager。

4.4 将配置分发到所有Slave节点

在Master节点上,把配置好的整个Hadoop目录和环境变量文件同步到两个Slave节点。

# 1. 将Hadoop安装包同步到Slave节点
scp -r /opt/hadoop/hadoop-3.3.4 root@slave01:/opt/hadoop/
scp -r /opt/hadoop/hadoop-3.3.4 root@slave02:/opt/hadoop/

# 2. 将环境变量配置文件同步过去(如果Slave节点的JAVA_HOME路径与Master不同,需要手动调整)
scp /etc/profile root@slave01:/etc/
scp /etc/profile root@slave02:/etc/

# 3. 在Slave节点上创建相同的目录结构
ssh slave01 "mkdir -p /opt/hadoop/tmp /opt/hadoop/hdfs/data"
ssh slave02 "mkdir -p /opt/hadoop/tmp /opt/hadoop/hdfs/data"

# 4. 在Slave节点上使环境变量生效,并测试Hadoop命令
ssh slave01 "source /etc/profile && hadoop version"
ssh slave02 "source /etc/profile && hadoop version"

如果两台Slave都能正确输出Hadoop版本信息,说明同步成功。

5. 集群启动、验证与初体验

万事俱备,只欠启动。启动Hadoop集群有严格的顺序,并且第一次启动前有一个关键操作:格式化NameNode。

5.1 格式化NameNode

这个操作只在第一次启动集群前执行一次! 如果重复格式化,会导致NameNode的元数据ID与DataNode存储的数据ID不匹配,DataNode将无法启动。在Master节点执行:

hdfs namenode -format

你会看到大量日志输出,最后几行如果出现“Storage directory /opt/hadoop/hdfs/name has been successfully formatted”之类的成功信息,并且没有“ERROR”字样,就说明格式化成功了。格式化后,/opt/hadoop/hdfs/name目录下会生成current等子目录和文件。

5.2 启动HDFS和YARN集群

Hadoop提供了方便的启动脚本。我们先启动HDFS(分布式文件系统):

# 在Master节点执行
start-dfs.sh

这个脚本会读取workers文件,依次SSH到slave01slave02启动DataNode进程,同时在Master上启动NameNode进程,在slave01上启动SecondaryNameNode进程(因为我们在hdfs-site.xml里配置了)。

接着启动YARN(资源管理框架):

start-yarn.sh

这个脚本会在Master上启动ResourceManager,在workers文件列出的所有节点(slave01, slave02)上启动NodeManager。

你可以用jps命令来检查各个节点上的Java进程是否启动成功:

  • 在Master节点,应该能看到:NameNode, ResourceManager, Jps
  • 在Slave01节点,应该能看到:DataNode, SecondaryNameNode, NodeManager, Jps
  • 在Slave02节点,应该能看到:DataNode, NodeManager, Jps

如果某个进程没有出现,可以去对应节点的$HADOOP_HOME/logs/目录下查看相关日志(比如hadoop-root-namenode-master.log),这是排查问题的第一现场。

5.3 通过Web UI验证集群状态

Hadoop提供了非常直观的Web管理界面,比命令行看状态方便多了。

  1. HDFS状态:在浏览器打开 http://master:9870。这是NameNode的Web UI。在首页的“Overview”部分,你应该能看到:

    • Live Nodes:显示为2,代表有两个活跃的DataNode(slave01和slave02)。
    • Total Datanode Storage:显示两个DataNode的总存储容量。
    • 在顶部菜单点击 Datanodes,可以看到两个DataNode的详细信息,包括主机名、存储使用情况等。
  2. YARN状态:在浏览器打开 http://master:8088。这是ResourceManager的Web UI。这里展示了集群的资源概况和运行的应用(目前是空的)。

5.4 跑一个简单的MapReduce作业试试水

集群跑起来了,我们让它干点活,验证整个计算流程是否通畅。用Hadoop自带的例子,计算$HADOOP_HOME/etc/hadoop目录下所有配置文件中,各个单词出现的次数。

# 1. 在HDFS上创建一个输入目录
hdfs dfs -mkdir -p /user/root/input

# 2. 将本地配置文件上传到HDFS的输入目录
hdfs dfs -put $HADOOP_HOME/etc/hadoop/*.xml /user/root/input/

# 3. 运行MapReduce单词计数示例程序
hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.3.4.jar wordcount /user/root/input /user/root/output

# 4. 查看输出结果
hdfs dfs -cat /user/root/output/part-r-00000 | head -20

如果一切正常,你会看到一串单词及其出现次数的列表。同时,在YARN的Web UI (http://master:8088) 上,应该能看到一个完成的MapReduce应用记录。

5.5 集群的停止与日常管理

完成测试后,可以按顺序停止集群:

stop-yarn.sh
stop-dfs.sh

日常管理常用命令:

  • hdfs dfsadmin -report:查看HDFS集群状态报告。
  • yarn node -list:查看所有YARN节点状态。
  • hdfs dfs -ls /:列出HDFS根目录下的文件。
  • 启动所有服务:start-all.sh (旧脚本,已不推荐,建议用start-dfs.shstart-yarn.sh分开启动)。
  • 停止所有服务:stop-all.sh

6. 避坑指南与性能优化建议

按照上面的步骤,你应该能成功拉起集群。但真实环境中总会遇到些“妖魔鬼怪”。这里分享几个我踩过的坑和对应的解决办法。

坑1:启动DataNode失败,日志显示“Incompatible clusterIDs”

  • 原因:最常见的原因是多次格式化NameNode。每次格式化都会生成新的集群ID(clusterID),而DataNode还保存着旧的ID,导致不匹配。
  • 解决:找到DataNode的数据目录(我们配置的是/opt/hadoop/hdfs/data/current),里面有个VERSION文件,将其中的clusterID修改为NameNode的clusterID(NameNode的ID在/opt/hadoop/hdfs/name/current/VERSION文件里)。或者,更彻底但会丢失数据的方法是:清空所有节点上hadoop.tmp.dir/opt/hadoop/tmp)和dfs.data.dir/opt/hadoop/hdfs/data)目录的内容,重新格式化NameNode。

坑2:Web UI无法访问(端口9870或8088打不开)

  • 原因:CentOS 7的防火墙(firewalld)或者SELinux可能阻止了访问。
  • 解决
    • 临时关闭防火墙(学习环境):systemctl stop firewalld
    • 永久关闭防火墙(不推荐生产):systemctl disable firewalld
    • 更安全:开放特定端口:
      firewall-cmd --permanent --add-port=9870/tcp
      firewall-cmd --permanent --add-port=8088/tcp
      firewall-cmd --permanent --add-port=9000/tcp
      firewall-cmd --permanent --add-port=9864/tcp # DataNode数据传输端口
      firewall-cmd --reload
      
    • SELinux:可以临时设置为宽容模式 setenforce 0,或永久禁用(修改/etc/selinux/config文件,设置SELINUX=disabled后重启)。

坑3:运行MapReduce作业报错“找不到类”或“权限被拒绝”

  • 原因yarn.application.classpath配置不正确,或者运行用户权限不足。
  • 解决:仔细检查yarn-site.xmlyarn.application.classpath的路径是否正确,确保包含了所有必要的Hadoop Jar包路径。对于权限问题,确保/opt/hadoop/tmp目录对所有Hadoop进程用户(我们用的是root)有读写权限。

性能优化小建议:

  1. 数据目录多磁盘:在生产环境,dfs.datanode.data.dir可以配置多个用逗号分隔的路径,指向不同的物理磁盘,可以显著提升IO性能。例如:file:///data1/hdfs/data,file:///data2/hdfs/data
  2. 调整JVM堆内存:在hadoop-env.shyarn-env.sh等文件中,可以设置HADOOP_HEAPSIZE_MAXYARN_RESOURCEMANAGER_HEAPSIZE等环境变量,根据机器内存调整各进程的堆大小,避免内存不足或浪费。
  3. 关闭IPv6:Hadoop在某些环境下对IPv6支持不佳,可以在/etc/hosts中确保主机名解析到IPv4地址,或在hadoop-env.sh中添加export HADOOP_OPTS="-Djava.net.preferIPv4Stack=true"

最后,记得定期查看日志($HADOOP_HOME/logs/),它是你排查问题最好的朋友。这套1 NameNode + 3 DataNode的集群,作为学习和开发测试环境已经非常扎实了。当你熟悉了整个流程和原理后,再去探索高可用(HA)NameNode、联邦(Federation)等更高级的架构,就会轻松很多。

更多推荐