三种运行模式
Hadoop 三种运行模式:从单机调试到生产集群,一路搭过来
Hadoop 提供三种运行模式,本质上对应三个场景:
- 单机模式:我电脑上写代码,跑通逻辑就行
- 伪分布式模式:我测试 HDFS + YARN 功能对不对
- 完全分布式模式:生产环境,多台机器跑大数据
从单机到完全分布式的过程,就是你的 Hadoop 技能从入门到生产的过程。
不管哪种模式,先配 Java 环境
Hadoop 依赖 Java,不管哪种模式,这一步都逃不掉。
安装 Java(以 CentOS 为例)
sudo yum install java-1.8.0-openjdk-devel
确认 Java 路径
which java
输出:/usr/bin/java
找到 JAVA_HOME
readlink -f /usr/bin/java | sed 's:/bin/java::'
然后在 $HADOOP_HOME/etc/hadoop/hadoop-env.sh 里加上:
export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk
验证 Hadoop 能跑:
hadoop version
单机模式:什么都不配,直接跑
Hadoop 默认就是单机模式,解压即用。所有进程跑在单个 JVM 里,不启动 HDFS、不启动 YARN,读写本地文件系统。
什么时候用? 写 MapReduce 代码的时候,跑通逻辑就行。输入输出都在本地,不用跟 HDFS 打交道。
快速上手 WordCount:
创建输入目录
mkdir -p input
echo "hello hadoop world" > input/file.txt
echo "hello yarn" >> input/file.txt
运行 WordCount(JAR 包路径按实际版本调整)
hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.3.0.jar wordcount input output
看结果
cat output/part-r-00000
hadoop 1
hello 2
world 1
yarn 1
单机模式的优点: 零配置,秒级启动,用来验证逻辑正确性最好。缺点: 没有 HDFS,没有分布式调度,不能模拟真正的集群行为。
伪分布式模式:一台机器模拟集群
单机模式验证了代码逻辑,但你还不确定它在 HDFS + YARN 上能不能跑。伪分布式模式就是在一台机器上启动所有守护进程——NameNode、DataNode、ResourceManager、NodeManager 全都有,但都跑在同一台机器上。
什么时候用? 功能测试、开发调试,需要验证 HDFS 和 YARN 的交互逻辑。
核心配置(4 个文件,都在 $HADOOP_HOME/etc/hadoop/):
1. core-site.xml——HDFS 地址
<configuration>
<!-- 指定 HDFS 的 NameNode 地址 -->
<property>
<name>fs.defaultFS</name>
<value>hdfs://localhost:9000</value>
</property>
<!-- Hadoop 临时文件存储目录(需手动创建) -->
<property>
<name>hadoop.tmp.dir</name>
<value>/opt/data/hadoop/tmp</value>
</property>
</configuration>
2. hdfs-site.xml——单节点副本数设为 1
<configuration>
<!-- 副本数量(单节点集群设为 1) -->
<property>
<name>dfs.replication</name>
<value>1</value>
</property>
<!-- NameNode 元数据存储目录(需手动创建) -->
<property>
<name>dfs.namenode.name.dir</name>
<value>/opt/data/hadoop/hdfs/name</value>
</property>
<!-- DataNode 数据存储目录(需手动创建) -->
<property>
<name>dfs.datanode.data.dir</name>
<value>/opt/data/hadoop/hdfs/data</value>
</property>
<!-- 关闭 HDFS 权限检查(方便测试) -->
<property>
<name>dfs.permissions.enabled</name>
<value>false</value>
</property>
</configuration>
3. mapred-site.xml——用 YARN 跑 MapReduce
<configuration>
<!-- 指定 MapReduce 运行在 YARN 上 -->
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
<!-- MapReduce 应用类路径(3.x 版本需配置) -->
<property>
<name>mapreduce.application.classpath</name>
<value>$HADOOP_MAPRED_HOME/share/hadoop/mapreduce/*:$HADOOP_MAPRED_HOME/share/hadoop/mapreduce/lib/*</value>
</property>
</configuration>
4. yarn-site.xml——开启 Shuffle
<configuration>
<!-- 启用 Shuffle 服务(MapReduce 依赖) -->
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<!-- Shuffle 服务类(3.x 版本需配置) -->
<property>
<name>yarn.nodemanager.aux-services.mapreduce_shuffle.class</name>
<value>org.apache.hadoop.mapred.ShuffleHandler</value>
</property>
<!-- 允许环境变量白名单(避免 YARN 启动报错) -->
<property>
<name>yarn.nodemanager.env-whitelist</name>
<value>JAVA_HOME,HADOOP_COMMON_HOME,HADOOP_HDFS_HOME,HADOOP_CONF_DIR,HADOOP_YARN_HOME,HADOOP_MAPRED_HOME</value>
</property>
</configuration>
启动:
格式化 HDFS(仅需执行一次,多次执行会清空数据)
hdfs namenode -format
启动 HDFS
start-dfs.sh
启动 YARN
start-yarn.sh
检查进程
jps
应该看到:NameNode、DataNode、SecondaryNameNode、ResourceManager、NodeManager
验证:
- HDFS Web UI:
http://localhost:9870 - YARN Web UI:
http://localhost:8088
跑个作业验证:
在 HDFS 上建目录、传文件
hdfs dfs -mkdir -p /input
hdfs dfs -put input/file.txt /input/
运行 WordCount
hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.3.0.jar wordcount /input /output
看结果
hdfs dfs -cat /output/part-r-00000
关闭:
stop-yarn.sh
stop-dfs.sh
完全分布式模式:多台机器真正跑集群
伪分布式的所有进程挤在一台机器上,资源争抢、单点风险——生产环境不能这样。完全分布式模式把组件分散到多台机器,真正分布式部署。
集群规划(3 台机器):
| 机器 | HDFS 角色 | YARN 角色 |
|---|---|---|
| hadoop1(主) | NameNode | — |
| hadoop2(从) | DataNode + SecondaryNameNode | NodeManager |
| hadoop3(从) | DataNode | ResourceManager + NodeManager |
前置准备(在所有节点执行):
配置主机名和 /etc/hosts
每台机器的 /etc/hosts 都要加上
192.168.1.101 hadoop1
192.168.1.102 hadoop2
192.168.1.103 hadoop3
SSH 免密登录
主节点(hadoop1)需要能免密登录所有从节点:
生成 SSH 密钥(主节点执行)
ssh-keygen -t rsa -P "" -f ~/.ssh/id_rsa
复制公钥到所有节点(包括自身)
ssh-copy-id hadoop1
ssh-copy-id hadoop2
ssh-copy-id hadoop3
所有节点安装 Java + Hadoop,路径一致
主节点配置(hadoop1 上配,然后 scp 到其他节点):
core-site.xml:
<configuration>
<!-- 指定 NameNode 地址(主节点 hostname) -->
<property>
<name>fs.defaultFS</name>
<value>hdfs://hadoop1:9000</value>
</property>
<!-- Hadoop 临时目录(所有节点需手动创建) -->
<property>
<name>hadoop.tmp.dir</name>
<value>/opt/data/hadoop/tmp</value>
</property>
</configuration>
hdfs-site.xml:
<configuration>
<!-- 副本数量(建议设为 2-3,取决于从节点数) -->
<property>
<name>dfs.replication</name>
<value>2</value>
</property>
<!-- SecondaryNameNode 地址(建议部署在从节点) -->
<property>
<name>dfs.namenode.secondary.http-address</name>
<value>hadoop2:9868</value>
</property>
<!-- NameNode 元数据存储目录 -->
<property>
<name>dfs.namenode.name.dir</name>
<value>/opt/data/hadoop/hdfs/name</value>
</property>
<!-- DataNode 数据存储目录 -->
<property>
<name>dfs.datanode.data.dir</name>
<value>/opt/data/hadoop/hdfs/data</value>
</property>
</configuration>
mapred-site.xml:
<configuration>
<!-- 指定 MapReduce 运行在 YARN 上 -->
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
</configuration>
yarn-site.xml:
<configuration>
<!-- 启用 Shuffle 服务 -->
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<!-- 指定 ResourceManager 地址 -->
<property>
<name>yarn.resourcemanager.hostname</name>
<value>hadoop3</value>
</property>
</configuration>
workers(告诉 Hadoop 哪些节点是 DataNode):
hadoop2
hadoop3
分发配置到所有节点:
scp -r $HADOOP_HOME/etc/hadoop/* hadoop2:$HADOOP_HOME/etc/hadoop/
scp -r $HADOOP_HOME/etc/hadoop/* hadoop3:$HADOOP_HOME/etc/hadoop/
启动集群:
hadoop1 上执行:格式化 HDFS
hdfs namenode -format
hadoop1 上执行:启动 HDFS
start-dfs.sh
hadoop3 上执行:启动 YARN(ResourceManager 在 hadoop3)
start-yarn.sh
验证:
- hadoop1 上能看到
NameNode - hadoop2 上能看到
DataNode+SecondaryNameNode - hadoop3 上能看到
DataNode+ResourceManager+NodeManager - Web UI:HDFS 在
http://hadoop1:9870,YARN 在http://hadoop3:8088