首页 > 应用开发 > IT综合 > Hadoop集群构建指南:从基础架构到生产部署
# Hadoop集群构建指南:从基础架构到生产部署
## Hadoop生态系统架构概述
Hadoop作为分布式计算框架的核心,由四个基础组件构成协同工作的系统。HDFS提供分布式存储能力,将大文件分割为数据块在多节点存储;YARN负责资源管理和作业调度;MapReduce是经典的计算模型;Common模块则提供基础工具支持。这种分层设计使得Hadoop能够处理PB级数据,同时保持系统的可扩展性和容错性。
现代Hadoop集群通常采用主从架构:NameNode作为HDFS的元数据管理中心,ResourceManager管理YARN资源,两者构成控制平面;DataNode存储实际数据,NodeManager执行计算任务,组成数据平面。这种分离设计允许存储和计算资源独立扩展,为不同工作负载提供灵活性。
```bash
# 典型Hadoop集群架构示例
# 控制节点(通常2-3台高配置服务器)
# ├── NameNode(Active) # HDFS主节点
# ├── NameNode(Standby) # HDFS备用节点
# ├── ResourceManager # YARN资源管理器
# └── HistoryServer # 作业历史服务器
# 数据/计算节点(多台标准服务器)
# ├── DataNode(存储数据块) # 每个节点部署
# ├── NodeManager(执行任务) # 每个节点部署
# └── 可选:ZooKeeper、JournalNode等
```
## 环境准备与系统配置
### 硬件与操作系统要求
生产环境Hadoop集群需要精心规划硬件配置。数据节点建议配置:64-128GB内存,12-24核CPU,10-20TB存储(多磁盘JBOD或RAID0),万兆网络。控制节点需要更高可靠性:128-256GB内存,冗余电源,RAID1/10存储。
```bash
# 系统环境检查脚本
#!/bin/bash
# check_system_requirements.sh
echo "Hadoop集群部署前系统检查"
echo "=========================="
# 1. 操作系统版本
echo "1. 操作系统:"
cat /etc/os-release | grep -E "PRETTY_NAME|VERSION"
# 2. 内核版本(建议3.10+)
echo -e "\n2. 内核版本:"
uname -r
# 3. 内存检查(建议>8GB)
echo -e "\n3. 内存容量:"
free -h | grep Mem
# 4. 磁盘空间(建议>100GB)
echo -e "\n4. 磁盘空间:"
df -h / /data* 2>/dev/null || df -h /
# 5. CPU核心数
echo -e "\n5. CPU核心:"
nproc
# 6. Java版本(要求Java 8或11)
echo -e "\n6. Java版本:"
java -version 2>&1 | grep version
# 7. 网络连通性测试
echo -e "\n7. 网络检查:"
ping -c 2 8.8.8.8 >/dev/null && echo "外网连通: 正常" || echo "外网连通: 异常"
# 8. 主机名解析
echo -e "\n8. 主机名设置:"
hostname -f
hostname -i
# 9. 防火墙状态
echo -e "\n9. 防火墙状态:"
systemctl status firewalld 2>/dev/null | grep -E "Active|running" || \
systemctl status iptables 2>/dev/null | grep -E "Active|running" || \
echo "防火墙未运行"
# 10. 时间同步检查
echo -e "\n10. 时间同步:"
timedatectl status | grep -E "synchronized|NTP"
echo -e "\n检查完成,请确保所有节点配置一致"
```
### 集群节点规划示例
```bash
# /etc/hosts 集群主机名配置(所有节点相同)
# 控制节点
192.168.1.101 hadoop-nn-01 # 主NameNode
192.168.1.102 hadoop-nn-02 # 备用NameNode
192.168.1.103 hadoop-rm-01 # ResourceManager
192.168.1.104 hadoop-zk-01 # ZooKeeper节点1
192.168.1.105 hadoop-zk-02 # ZooKeeper节点2
192.168.1.106 hadoop-zk-03 # ZooKeeper节点3
# 数据/计算节点(可扩展)
192.168.1.111 hadoop-dn-01 # DataNode/NodeManager 1
192.168.1.112 hadoop-dn-02 # DataNode/NodeManager 2
192.168.1.113 hadoop-dn-03 # DataNode/NodeManager 3
192.168.1.114 hadoop-dn-04 # DataNode/NodeManager 4
192.168.1.115 hadoop-dn-05 # DataNode/NodeManager 5
# 客户端节点
192.168.1.201 hadoop-client-01
# 验证主机名解析
ping -c 2 hadoop-nn-01
ping -c 2 hadoop-dn-01
```
## Hadoop集群分步部署指南
### 步骤1:基础环境配置
```bash
#!/bin/bash
# hadoop_base_setup.sh - 所有节点执行的基础配置
# 1. 创建Hadoop系统用户和组
groupadd hadoop
useradd -g hadoop -m -s /bin/bash hdfs
useradd -g hadoop -m -s /bin/bash yarn
useradd -g hadoop -m -s /bin/bash mapred
# 2. 配置SSH免密登录(控制节点执行)
# 在hadoop-nn-01上生成密钥并分发
su - hdfs << EOF
ssh-keygen -t rsa -P '' -f ~/.ssh/id_rsa
cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
# 复制公钥到其他节点
for host in hadoop-nn-02 hadoop-rm-01 hadoop-dn-{01..05}; do
ssh-copy-id -i ~/.ssh/id_rsa.pub hdfs@\$host
done
EOF
# 3. 创建数据目录
mkdir -p /data/{hdfs/namenode,hdfs/datanode,yarn/local,yarn/logs}
chown -R hdfs:hadoop /data/hdfs
chown -R yarn:hadoop /data/yarn
# 4. 安装Java(以OpenJDK 8为例)
yum install -y java-1.8.0-openjdk java-1.8.0-openjdk-devel
# 设置Java环境变量
cat >> /etc/profile.d/java.sh << 'EOF'
export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk
export JRE_HOME=\$JAVA_HOME/jre
export PATH=\$PATH:\$JAVA_HOME/bin
EOF
source /etc/profile.d/java.sh
# 5. 优化系统参数
cat >> /etc/sysctl.conf << 'EOF'
# Hadoop优化参数
net.core.somaxconn = 32768
net.ipv4.tcp_syncookies = 0
net.ipv4.ip_local_port_range = 1024 65535
vm.swappiness = 10
EOF
<"w1.a8k1.org.cn"><"g8.a8k1.org.cn"><"q0.a8k1.org.cn">
sysctl -p
# 6. 配置limits限制
cat >> /etc/security/limits.conf << 'EOF'
hdfs soft nofile 65536
hdfs hard nofile 65536
hdfs soft nproc 65536
hdfs hard nproc 65536
yarn soft nofile 65536
yarn hard nofile 65536
yarn soft nproc 65536
yarn hard nproc 65536
* soft nproc 65536
* hard nproc 65536
EOF
```
### 步骤2:Hadoop软件安装与配置
```bash
# 下载Hadoop(以3.3.4为例)
cd /opt
wget https://archive.apache.org/dist/hadoop/common/hadoop-3.3.4/hadoop-3.3.4.tar.gz
tar -xzf hadoop-3.3.4.tar.gz
ln -s hadoop-3.3.4 hadoop
chown -R hdfs:hadoop /opt/hadoop*
# 配置环境变量
cat >> /etc/profile.d/hadoop.sh << 'EOF'
export HADOOP_HOME=/opt/hadoop
export HADOOP_CONF_DIR=\$HADOOP_HOME/etc/hadoop
export PATH=\$PATH:\$HADOOP_HOME/bin:\$HADOOP_HOME/sbin
EOF
source /etc/profile.d/hadoop.sh
```
### 步骤3:核心配置文件详解
```xml
<!-- etc/hadoop/core-site.xml - 所有节点相同 -->
<configuration>
<!-- 指定默认文件系统 -->
<property>
<name>fs.defaultFS</name>
<value>hdfs://hadoop-nn-01:8020</value>
</property>
<!-- Hadoop临时目录 -->
<property>
<name>hadoop.tmp.dir</name>
<value>/data/hadoop/tmp</value>
</property>
<!-- IO缓冲区大小 -->
<property>
<name>io.file.buffer.size</name>
<value>131072</value>
</property>
<!-- 启用本地库 -->
<property>
<name>hadoop.native.lib</name>
<value>true</value>
</property>
</configuration>
```
```xml
<!-- etc/hadoop/hdfs-site.xml - HDFS配置 -->
<configuration>
<!-- NameNode元数据目录 -->
<property>
<name>dfs.namenode.name.dir</name>
<value>file:///data/hdfs/namenode</value>
</property>
<!-- DataNode数据目录 -->
<property>
<name>dfs.datanode.data.dir</name>
<value>file:///data/hdfs/datanode</value>
</property>
<!-- 数据块副本数 -->
<property>
<name>dfs.replication</name>
<value>3</value>
</property>
<!-- 启用HA -->
<property>
<name>dfs.nameservices</name>
<value>hadoop-cluster</value>
</property>
<!-- NameNode IDs -->
<property>
<name>dfs.ha.namenodes.hadoop-cluster</name>
<value>nn1,nn2</value>
</property>
<!-- NameNode RPC地址 -->
<property>
<name>dfs.namenode.rpc-address.hadoop-cluster.nn1</name>
<value>hadoop-nn-01:8020</value>
</property>
<property>
<name>dfs.namenode.rpc-address.hadoop-cluster.nn2</name>
<value>hadoop-nn-02:8020</value>
</property>
<!-- NameNode HTTP地址 -->
<property>
<name>dfs.namenode.http-address.hadoop-cluster.nn1</name>
<value>hadoop-nn-01:9870</value>
</property>
<property>
<name>dfs.namenode.http-address.hadoop-cluster.nn2</name>
<value>hadoop-nn-02:9870</value>
</property>
<!-- JournalNode地址 -->
<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://hadoop-zk-01:8485;hadoop-zk-02:8485;hadoop-zk-03:8485/hadoop-cluster</value>
</property>
<!-- HA故障切换代理 -->
<property>
<name>dfs.client.failover.proxy.provider.hadoop-cluster</name>
<value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
</property>
<!-- 自动故障切换 -->
<property>
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value>
</property>
</configuration>
```
```xml
<!-- etc/hadoop/yarn-site.xml - YARN配置 -->
<configuration>
<!-- 资源管理器地址 -->
<property>
<name>yarn.resourcemanager.hostname</name>
<value>hadoop-rm-01</value>
</property>
<!-- NodeManager辅助服务 -->
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<!-- 资源调度器 -->
<property>
<name>yarn.resourcemanager.scheduler.class</name>
<value>org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairScheduler</value>
</property>
<!-- 内存配置 -->
<property>
<name>yarn.nodemanager.resource.memory-mb</name>
<value>8192</value> <!-- 根据实际内存调整 -->
</property>
<property>
<name>yarn.scheduler.minimum-allocation-mb</name>
<value>1024</value>
</property>
<!-- CPU配置 -->
<property>
<name>yarn.nodemanager.resource.cpu-vcores</name>
<value>8</value> <!-- 根据实际CPU核心调整 -->
</property>
<!-- 日志聚合 -->
<property>
<name>yarn.log-aggregation-enable</name>
<value>true</value>
</property>
<property>
<name>yarn.nodemanager.remote-app-log-dir</name>
<value>/data/yarn/logs</value>
</property>
</configuration>
```
```xml
<!-- etc/hadoop/mapred-site.xml - MapReduce配置 -->
<configuration>
<!-- 指定MapReduce框架 -->
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
<!-- 作业历史服务器 -->
<property>
<name>mapreduce.jobhistory.address</name>
<value>hadoop-nn-01:10020</value>
</property>
<property>
<name>mapreduce.jobhistory.webapp.address</name>
<value>hadoop-nn-01:19888</value>
</property>
<!-- 内存配置 -->
<property>
<name>mapreduce.map.memory.mb</name>
<value>2048</value>
</property>
<property>
<name>mapreduce.reduce.memory.mb</name>
<value>4096</value>
</property>
</configuration>
```
### 步骤4:节点角色配置文件
```bash
# etc/hadoop/workers - 数据节点列表
hadoop-dn-01
hadoop-dn-02
hadoop-dn-03
hadoop-dn-04
hadoop-dn-05
# 可选:创建角色特定配置文件
# 对于NameNode节点
echo "hadoop-nn-01" > etc/hadoop/namenodes
# 对于ResourceManager节点
echo "hadoop-rm-01" > etc/hadoop/resourcemanagers
```
## 集群初始化与启动流程
### 初始格式化与启动
```bash
#!/bin/bash
# hadoop_cluster_init.sh - 集群初始化脚本
echo "Hadoop集群初始化流程"
echo "===================="
# 1. 格式化NameNode(仅在主NameNode执行)
echo "1. 格式化HDFS NameNode..."
su - hdfs -c "hdfs namenode -format -clusterId hadoop-cluster"
# 2. 启动JournalNode(所有ZK节点)
echo "2. 启动JournalNode服务..."
for host in hadoop-zk-{01..03}; do
ssh hdfs@$host "hdfs --daemon start journalnode"
done
# 3. 启动主NameNode
echo "3. 启动主NameNode..."
su - hdfs -c "hdfs --daemon start namenode"
# 4. 同步备用NameNode
echo "4. 配置备用NameNode..."
su - hdfs -c "hdfs namenode -bootstrapStandby"
# 5. 启动备用NameNode
echo "5. 启动备用NameNode..."
ssh hdfs@hadoop-nn-02 "hdfs --daemon start namenode"
# 6. 初始化ZKFC(故障切换控制器)
echo "6. 初始化ZKFC..."
su - hdfs -c "hdfs zkfc -formatZK"
# 7. 启动ZKFC(两个NameNode)
echo "7. 启动ZKFC服务..."
for host in hadoop-nn-{01..02}; do
ssh hdfs@$host "hdfs --daemon start zkfc"
done
# 8. 启动DataNode(所有数据节点)
echo "8. 启动DataNode..."
hdfs --workers --hostnames workers --daemon start datanode
# 9. 启动ResourceManager
echo "9. 启动ResourceManager..."
su - yarn -c "yarn --daemon start resourcemanager"
# 10. 启动NodeManager(所有计算节点)
echo "10. 启动NodeManager..."
yarn --workers --hostnames workers --daemon start nodemanager
# 11. 启动HistoryServer
echo "11. 启动HistoryServer..."
su - mapred -c "mapred --daemon start historyserver"
echo "初始化完成,等待服务启动..."
sleep 30
# 验证集群状态
echo -e "\n集群状态验证:"
hdfs dfsadmin -report | head -20
yarn node -list
```
### 服务管理脚本
```bash
#!/bin/bash
# hadoop_service_manager.sh
# 统一服务管理脚本
ACTION=${1:-status}
ROLE=${2:-all}
case $ACTION in
start|stop|status|restart)
;;
*)
echo "用法: $0 {start|stop|status|restart} {all|hdfs|yarn|mapred}"
exit 1
;;
esac
manage_hdfs() {
case $ACTION in
start)
echo "启动HDFS服务..."
hdfs --daemon start namenode
hdfs --daemon start datanode
hdfs --daemon start journalnode
hdfs --daemon start zkfc
;;
stop)
echo "停止HDFS服务..."
hdfs --daemon stop zkfc
hdfs --daemon stop journalnode
hdfs --daemon stop datanode
hdfs --daemon stop namenode
;;
status)
echo "HDFS服务状态:"
jps | grep -E "NameNode|DataNode|JournalNode|DFSZKFailoverController"
;;
esac
}
<"t4.a8k1.org.cn"><"i6.a8k1.org.cn"><"o3.a8k1.org.cn">
manage_yarn() {
case $ACTION in
start)
echo "启动YARN服务..."
yarn --daemon start resourcemanager
yarn --daemon start nodemanager
;;
stop)
echo "停止YARN服务..."
yarn --daemon stop nodemanager
yarn --daemon stop resourcemanager
;;
status)
echo "YARN服务状态:"
jps | grep -E "ResourceManager|NodeManager"
;;
esac
}
manage_mapred() {
case $ACTION in
start)
echo "启动MapReduce HistoryServer..."
mapred --daemon start historyserver
;;
stop)
echo "停止MapReduce HistoryServer..."
mapred --daemon stop historyserver
;;
status)
echo "MapReduce服务状态:"
jps | grep "JobHistoryServer"
;;
esac
}
case $ROLE in
hdfs)
manage_hdfs
;;
yarn)
manage_yarn
;;
mapred)
manage_mapred
;;
all)
manage_hdfs
manage_yarn
manage_mapred
;;
esac
```
## 集群验证与测试
### 基础功能测试
```bash
#!/bin/bash
# hadoop_cluster_test.sh
echo "Hadoop集群功能测试"
echo "=================="
# 1. 测试HDFS基础功能
echo "1. 测试HDFS基础功能..."
hdfs dfs -mkdir -p /test/input
hdfs dfs -put /etc/hosts /test/input/
hdfs dfs -ls /test/input
hdfs dfs -cat /test/input/hosts | head -5
# 2. 测试文件复制
echo -e "\n2. 测试文件复制..."
hdfs dfs -cp /test/input/hosts /test/copy_test
hdfs dfs -ls /test/copy_test
# 3. 测试YARN功能
echo -e "\n3. 测试YARN资源管理..."
yarn node -list
yarn application -list
# 4. 运行MapReduce示例作业
echo -e "\n4. 运行MapReduce测试作业..."
# 创建测试数据
echo -e "apple orange banana\norange banana\nbanana" > /tmp/test.txt
hdfs dfs -put /tmp/test.txt /test/input/
# 运行wordcount示例
yarn jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-*.jar \
wordcount /test/input/test.txt /test/output/wordcount
# 查看结果
echo "作业结果:"
hdfs dfs -cat /test/output/wordcount/part-r-00000
# 5. 测试高可用切换
echo -e "\n5. 测试NameNode高可用..."
echo "当前活动NameNode:"
hdfs haadmin -getServiceState nn1
hdfs haadmin -getServiceState nn2
# 6. 测试数据块分布
echo -e "\n6. 测试数据块分布..."
hdfs fsck / -blocks -locations | grep "Total blocks"
# 7. 清理测试数据
echo -e "\n7. 清理测试数据..."
hdfs dfs -rm -r /test
# 8. 性能基准测试(可选)
echo -e "\n8. 运行性能基准测试..."
# 测试写入性能
hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-client-jobclient-*-tests.jar \
TestDFSIO -write -nrFiles 10 -fileSize 100MB
# 测试读取性能
hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-client-jobclient-*-tests.jar \
TestDFSIO -read -nrFiles 10 -fileSize 100MB
# 清理基准测试数据
hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-client-jobclient-*-tests.jar \
TestDFSIO -clean
echo -e "\n集群测试完成"
```
### 监控与健康检查
```bash
#!/bin/bash
# hadoop_health_check.sh
echo "Hadoop集群健康检查"
echo "=================="
# 1. 检查服务进程
echo "1. 服务进程状态:"
jps | sort
# 2. 检查HDFS状态
echo -e "\n2. HDFS状态:"
hdfs dfsadmin -report | grep -E "Configured Capacity|Present Capacity|DFS Used%|Live datanodes"
# 3. 检查NameNode HA状态
echo -e "\n3. NameNode高可用状态:"
hdfs haadmin -getAllServiceState
# 4. 检查YARN状态
echo -e "\n4. YARN资源状态:"
yarn node -list | head -10
# 5. 检查磁盘使用
echo -e "\n5. 磁盘使用情况:"
df -h /data*
# 6. 检查网络连通性
echo -e "\n6. 节点间连通性:"
for node in hadoop-nn-01 hadoop-rm-01 hadoop-dn-01; do
ping -c 2 $node >/dev/null && echo "$node: 可达" || echo "$node: 不可达"
done
# 7. 检查日志错误
echo -e "\n7. 检查最近错误日志:"
LOG_DIR="/var/log/hadoop-hdfs"
ERROR_COUNT=$(find $LOG_DIR -name "*.log" -mtime -1 -exec grep -l "ERROR\|Exception" {} \; | wc -l)
echo "过去24小时错误日志文件数: $ERROR_COUNT"
# 8. 生成健康报告
REPORT_FILE="/tmp/hadoop_health_$(date +%Y%m%d_%H%M%S).txt"
{
echo "Hadoop集群健康报告"
echo "生成时间: $(date)"
echo "================================"
echo -e "\n服务状态摘要:"
jps | sort
echo -e "\nHDFS容量:"
hdfs dfsadmin -report | grep -E "Configured Capacity|Present Capacity|DFS Used%"
echo -e "\nYARN节点:"
yarn node -list 2>/dev/null | head -5
echo -e "\n系统资源:"
free -h | grep Mem
df -h /data* 2>/dev/null | head -5
} > "$REPORT_FILE"
echo -e "\n健康报告已保存到: $REPORT_FILE"
```
## 生产环境优化建议
### 安全加固配置
```xml
<!-- 启用Kerberos认证 -->
<property>
<name>hadoop.security.authentication</name>
<value>kerberos</value>
</property>
<property>
<name>hadoop.security.authorization</name>
<value>true</value>
</property>
<!-- 启用HDFS权限检查 -->
<property>
<name>dfs.permissions.enabled</name>
<value>true</value>
</property>
<!-- 启用YARN ACL -->
<property>
<name>yarn.acl.enable</name>
<value>true</value>
</property>
```
### 性能调优参数
```bash
# 内存优化调整(根据实际硬件)
# 在yarn-site.xml中调整
# NodeManager可用内存 = 物理内存 * 0.8 - 系统保留内存
# 例如:64GB内存,系统保留8GB,则设置:
# yarn.nodemanager.resource.memory-mb = 45000 (64*0.8*1024 - 8000)
# HDFS客户端优化
echo "export HADOOP_CLIENT_OPTS=\"-Xmx2048m\"" >> etc/hadoop/hadoop-env.sh
# 数据块大小调整(大文件场景)
# 在hdfs-site.xml中设置
# <property>
# <name>dfs.blocksize</name>
# <value>268435456</value> <!-- 256MB -->
# </property>
```
通过以上系统化的部署流程,可以构建出稳定可靠的Hadoop生产集群。关键在于前期规划要充分考虑业务需求,部署过程要严格按照步骤执行,上线后要建立完善的监控和维护体系。Hadoop集群的稳定性不仅取决于配置参数,更依赖于持续的运维管理和性能优化。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/19545/viewspace-3109736/ ,如需转载,请注明出处,否则将追究法律责任。