跳过正文
  1. Posts/

大数据集群分布式部署教程

·3189 字·15 分钟
作者
John Lee
Building things with code. Writing about tech, projects, and ideas.
目录

大数据集群分布式部署教程(完整验证版)
#

本教程提供每一步都可复制执行的大数据集群部署方案,包含全部配置文件的完整内容。所有步骤已在 3 节点 CentOS 7.9 集群上验证通过。

变量适配说明
#

部署新集群时,将教程中的以下值替换为实际环境配置:

变量教程示例值替换为你的值
域名后缀pblh123.cn你的域名,无域名的用 localdomain
节点数量3实际节点数(需同步调整副本数、ZK myid、Kafka broker.id)
主节点hd2 / 192.168.137.155你的主节点主机名/IP
节点2hd3 / 192.168.137.156你的第二个节点
节点3hd4 / 192.168.137.157你的第三个节点
Hadoop版本hadoop-3.3.6实际安装版本目录名
JDK版本jdk1.8.0_471实际安装版本目录名
HDFS副本数2通常设为 min(节点数, 3)
MySQL密码Hive@12345你的MySQL hive用户密码
安装根目录/opt/module各组件解压目录
数据根目录/opt/dataHDFS/ZK/Kafka 数据存储目录
NodeManager内存hd2:2800, hd3:2000, hd4:1200按实际物理内存的70-80%分配(MB)
SSH用户hadoop运行服务的系统用户
SSH密码hadoop相应密码

替换公式: ${组件路径} = /opt/module/${版本目录名},教程中所有路径均由公式推导,修改版本号后路径自动适用。


目录
#

  1. 架构设计
  2. 环境准备
  3. MySQL 安装配置
  4. Hadoop HDFS 部署
  5. YARN 部署
  6. ZooKeeper 部署
  7. Hive 部署
  8. HBase 部署
  9. Kafka 部署
  10. Spark 部署
  11. 集群验证
  12. 集群管理
  13. 一键脚本使用
  14. 故障排查
  15. 附录:适配新集群 Checklist

一、架构设计
#

1.1 集群拓扑
#

               ┌─────────────────────────────────────┐
               │           hd2 (4G/2C)                │
               │  192.168.137.155                     │
               │  NameNode, ResourceManager           │
               │  HBase Master, Hive Metastore        │
               │  HiveServer2, JobHistoryServer       │
               │  ZooKeeper, Kafka, Spark             │
               └──────────────┬──────────────────────┘
            ┌─────────────────┼─────────────────┐
            │                 │                 │
   ┌────────┴────────┐ ┌──────┴──────┐ ┌───────┴───────┐
   │  hd3 (3G/2C)    │ │ hd4 (2G/2C) │ │ (可扩展)      │
   │  192.168.137.156 │ │ 192.168.137.157 │             │
   │  DataNode       │ │  DataNode    │ │               │
   │  NodeManager    │ │  NodeManager │ │               │
   │  SecondaryNN    │ │  ZK, Kafka   │ │               │
   │  ZK, Kafka      │ │  HBase RS    │ │               │
   │  HBase RS       │ │              │ │               │
   └─────────────────┘ └──────────────┘ └───────────────┘

1.2 服务分配矩阵
#

服务hd2hd3hd4说明
NameNodeYHDFS 元数据管理
DataNodeYYY数据存储
SecondaryNameNodeYCheckpoint 合并
ResourceManagerYYARN 资源调度
NodeManagerYYY任务执行
JobHistoryServerYMR 历史
ZooKeeperYYY分布式协调
Hive MetastoreY元数据服务
HiveServer2YSQL 查询
HBase MasterYRegion 管理
HBase RegionServerYYY数据读写
Kafka BrokerYYY消息队列
Spark HistoryServerY任务历史

1.3 服务依赖与启动顺序
#

MySQL ──► HDFS ──┬──► YARN ──► JobHistory
                 ├──► ZooKeeper ──┬──► HBase
                 │                │
                 │                └──► Kafka
                 └──► Hive Metastore ──► HiveServer2 ──► Spark HistoryServer

启动顺序: HDFS → (ZooKeeper + YARN) → (Hive → HBase → Kafka → Spark)
停止顺序: Spark → Kafka → HBase → Hive → YARN → ZooKeeper → HDFS


二、环境准备
#

2.1 硬件要求
#

节点内存CPU磁盘
hd2≥4GB≥2核≥40GB
hd3≥3GB≥2核≥40GB
hd4≥2GB≥2核≥40GB

2.2 软件版本
#

组件版本安装路径
JDK1.8.0_471/opt/module/jdk1.8.0_471
Hadoop3.3.6/opt/module/hadoop-3.3.6
ZooKeeper3.5.9/opt/module/apache-zookeeper-3.5.9-bin
Hive3.1.3/opt/module/apache-hive-3.1.3-bin
HBase2.6.4/opt/module/hbase-2.6.4-hadoop3
Kafka2.8.0/opt/module/kafka_2.13-2.8.0
Spark3.5.8/opt/module/spark-3.5.8-bin-hadoop3-scala2.13
MySQL5.7+系统 yum 安装
MySQL JDBC8.0.33/opt/module/apache-hive-3.1.3-bin/lib/

2.3 创建用户(所有节点)
#

# 每节点上执行(使用 root)
useradd hadoop
echo "hadoop" | passwd --stdin hadoop
# 授予 sudo 权限
echo "hadoop ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers

2.4 配置 /etc/hosts(所有节点)
#

# 每节点上执行(使用 root)
cat >> /etc/hosts << 'EOF'
192.168.137.155 hd2.pblh123.cn hd2
192.168.137.156 hd3.pblh123.cn hd3
192.168.137.157 hd4.pblh123.cn hd4
EOF

适配说明: 替换 IP 和主机名为你的实际值。主机名建议用短名(如 hd2),FQDN 用 主机名.域名

2.5 SSH 免密登录(所有节点)
#

# 使用 hadoop 用户,在主节点上执行
su - hadoop
ssh-keygen -t rsa -N "" -f ~/.ssh/id_rsa

# 分发公钥到所有节点(包括本机)
for host in hd2 hd3 hd4; do
    ssh-copy-id -o StrictHostKeyChecking=no hadoop@$host
done

# 验证(三节点互相ssh不提示密码)
ssh hd3 "hostname"
ssh hd4 "hostname"

2.6 关闭防火墙和 SELinux(所有节点,root)
#

# 每节点上执行
systemctl stop firewalld && systemctl disable firewalld
setenforce 0
sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config

2.7 JDK 安装(所有节点,root)
#

# 解压 JDK 到指定目录
tar -zxf jdk-8u471-linux-x64.tar.gz -C /opt/module/

# 验证
/opt/module/jdk1.8.0_471/bin/java -version
# 预期输出: java version "1.8.0_471"

2.8 创建目录结构(所有节点,hadoop 用户)
#

# 每节点上执行
mkdir -p /opt/data/{namenode,datanode,hadoop-tmp,zookeeper,kafkadata}
# hd2 额外
mkdir -p /opt/data/{hive-metastore.log,hiveserver2.log}

2.9 全局环境变量(所有节点,root)
#

创建 /etc/profile.d/hadoop_env.sh,所有服务进程通过此脚本获取环境变量。

sudo tee /etc/profile.d/hadoop_env.sh << 'EOF'
# JAVA
JAVA_HOME=/opt/module/jdk1.8.0_471
# Hadoop
HADOOP_HOME=/opt/module/hadoop-3.3.6
# Kafka
KAFKA_HOME=/opt/module/kafka_2.13-2.8.0
# Hive
HIVE_HOME=/opt/module/apache-hive-3.1.3-bin
# Spark
SPARK_HOME=/opt/module/spark-3.5.8-bin-hadoop3-scala2.13
# HBase
HBASE_HOME=/opt/module/hbase-2.6.4-hadoop3
# ZooKeeper
ZOOKEEPER_HOME=/opt/module/apache-zookeeper-3.5.9-bin

PATH=$PATH:$JAVA_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$KAFKA_HOME/bin:$HIVE_HOME/bin:$SPARK_HOME/bin:$HBASE_HOME/bin:$ZOOKEEPER_HOME/bin
EOF

# 生效
source /etc/profile.d/hadoop_env.sh

适配说明: 修改 JAVA_HOME、各 *_HOME 路径为实际版本目录名。


三、MySQL 安装配置
#

仅在 hd2(主节点)执行,用于 Hive 元数据存储。

3.1 安装 MySQL
#

# root@hd2
yum install -y mysql-community-server 2>/dev/null || {
    # 如无 MySQL repo,使用 MariaDB
    yum install -y mariadb-server mariadb
    systemctl start mariadb && systemctl enable mariadb
}

3.2 创建 Hive 元数据库
#

mysql -u root << EOF
CREATE DATABASE IF NOT EXISTS hive_metastore DEFAULT CHARACTER SET utf8;
CREATE USER IF NOT EXISTS 'hive'@'%' IDENTIFIED BY 'Hive@12345';
GRANT ALL PRIVILEGES ON hive_metastore.* TO 'hive'@'%';
FLUSH PRIVILEGES;

-- 验证
SHOW DATABASES;
SELECT user, host FROM mysql.user WHERE user='hive';
EOF

适配说明: 替换 Hive@12345 为实际密码。教程中所有出现此密码的位置需同步修改。


四、Hadoop HDFS 部署
#

4.1 core-site.xml
#

文件位置: ${HADOOP_HOME}/etc/hadoop/core-site.xml

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>

  <!-- NameNode RPC 地址 -->
  <property>
    <name>fs.defaultFS</name>
    <value>hdfs://hd2.pblh123.cn:9000</value>
  </property>

  <!-- Hadoop 代理用户(Hive/Spark 访问 HDFS 需要) -->
  <property>
    <name>hadoop.proxyuser.hadoop.hosts</name>
    <value>*</value>
  </property>
  <property>
    <name>hadoop.proxyuser.hadoop.groups</name>
    <value>*</value>
  </property>
  <property>
    <name>hadoop.proxyuser.hive.hosts</name>
    <value>*</value>
  </property>
  <property>
    <name>hadoop.proxyuser.hive.groups</name>
    <value>*</value>
  </property>

  <!-- 临时目录 -->
  <property>
    <name>hadoop.tmp.dir</name>
    <value>/opt/data/hadoop-tmp</value>
  </property>

</configuration>

适配: 替换 hd2.pblh123.cn:9000 中的主机名和端口。

4.2 hdfs-site.xml
#

文件位置: ${HADOOP_HOME}/etc/hadoop/hdfs-site.xml

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>

  <!-- 数据副本数(3节点集群建议2或3) -->
  <property>
    <name>dfs.replication</name>
    <value>2</value>
  </property>

  <!-- NameNode 元数据存储目录 -->
  <property>
    <name>dfs.namenode.name.dir</name>
    <value>file:///opt/data/namenode</value>
  </property>

  <!-- DataNode 数据块存储目录 -->
  <property>
    <name>dfs.datanode.data.dir</name>
    <value>file:///opt/data/datanode</value>
  </property>

  <!-- 块大小 -->
  <property>
    <name>dfs.blocksize</name>
    <value>64m</value>
  </property>

  <!-- NameNode Web UI 地址 -->
  <property>
    <name>dfs.namenode.http-address</name>
    <value>hd2.pblh123.cn:9870</value>
  </property>

  <!-- SecondaryNameNode Web UI -->
  <property>
    <name>dfs.namenode.secondary.http-address</name>
    <value>hd3.pblh123.cn:9868</value>
  </property>

  <!-- 关闭权限检查(开发环境) -->
  <property>
    <name>dfs.permissions.enabled</name>
    <value>false</value>
  </property>

</configuration>

适配: 替换主机名。副本数 dfs.replication 不能超过 DataNode 节点数。

4.3 workers(DataNode 列表)
#

文件位置: ${HADOOP_HOME}/etc/hadoop/workers

hd2.pblh123.cn
hd3.pblh123.cn
hd4.pblh123.cn

适配: 每行一个 DataNode 的完整主机名(FQDN)。

4.4 hadoop-env.sh(JVM 参数)
#

文件位置: ${HADOOP_HOME}/etc/hadoop/hadoop-env.sh

export JAVA_HOME=/opt/module/jdk1.8.0_471
export HADOOP_HOME=/opt/module/hadoop-3.3.6
export HADOOP_CONF_DIR=$HADOOP_HOME/etc/hadoop
export HADOOP_LOG_DIR=$HADOOP_HOME/logs
export HADOOP_PID_DIR=$HADOOP_HOME/pids

# JVM 堆内存(低内存 VM 优化)
export HADOOP_HEAPSIZE_MAX=512m
export HADOOP_HEAPSIZE_MIN=256m
export HDFS_NAMENODE_OPTS="-Xmx512m -Xms256m"
export HDFS_DATANODE_OPTS="-Xmx256m -Xms128m"
export YARN_RESOURCEMANAGER_HEAPSIZE=512
export YARN_NODEMANAGER_HEAPSIZE=256

适配: 修改 JAVA_HOMEHADOOP_HOME。内存充足的机器可适当调大堆内存。

4.5 同步配置到所有节点
#

# 在 hd2 上执行(hadoop 用户)
HADOOP_CONF=/opt/module/hadoop-3.3.6/etc/hadoop

# 同步到 hd3 和 hd4
for host in hd3 hd4; do
    scp $HADOOP_CONF/{core-site.xml,hdfs-site.xml,workers,hadoop-env.sh} hadoop@$host:$HADOOP_CONF/
done

# 验证:三节点配置文件一致
md5sum $HADOOP_CONF/core-site.xml
ssh hd3 "md5sum $HADOOP_CONF/core-site.xml"
ssh hd4 "md5sum $HADOOP_CONF/core-site.xml"

4.6 格式化 NameNode
#

# 仅在 hd2 执行一次(hadoop 用户)
source /etc/profile.d/hadoop_env.sh
hdfs namenode -format

# 预期输出末尾: ...common.Storage: Storage directory /opt/data/namenode has been successfully formatted.

注意: 此命令仅在首次部署时执行。重复格式化会清空 HDFS 所有数据。如需重新格式化,先删除 /opt/data/namenode/opt/data/datanode

4.7 启动 HDFS
#

# 在 hd2 上执行
start-dfs.sh

# 等待 5 秒
sleep 5

4.8 验证 HDFS
#

# 1. 进程检查
jps | grep -E "NameNode|DataNode"
# 预期 hd2: NameNode + DataNode
# hd3/hd4 上执行 jps 应有 DataNode

# 2. 集群报告
hdfs dfsadmin -report
# 预期: Live datanodes (3):  共3个节点在线

# 3. 读写测试
echo "Hello HDFS" | hdfs dfs -put - /test_verify.txt
hdfs dfs -cat /test_verify.txt
# 预期输出: Hello HDFS
hdfs dfs -rm /test_verify.txt

# 4. Web UI
# 浏览器访问 http://192.168.137.155:9870
# Datanodes 标签页应显示 3 个节点

五、YARN 部署
#

5.1 yarn-site.xml(含每节点差异化内存)
#

YARN 的 yarn.nodemanager.resource.memory-mb 需按节点内存配置。以下为三节点分别配置的版本。

hd2 版本 (/opt/module/hadoop-3.3.6/etc/hadoop/yarn-site.xml):

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>

  <property>
    <name>yarn.nodemanager.aux-services</name>
    <value>mapreduce_shuffle</value>
  </property>

  <property>
    <name>yarn.resourcemanager.hostname</name>
    <value>hd2.pblh123.cn</value>
  </property>

  <property>
    <name>yarn.resourcemanager.webapp.address</name>
    <value>hd2.pblh123.cn:8088</value>
  </property>

  <!-- ★ 内存:按节点实际物理内存 70-80% 配置,单位 MB -->
  <property>
    <name>yarn.nodemanager.resource.memory-mb</name>
    <value>2800</value>
    <!-- hd2: 4G × 70% ≈ 2800MB -->
    <!-- hd3: 3G × 70% ≈ 2000MB -->
    <!-- hd4: 2G × 60% ≈ 1200MB -->
  </property>

  <property>
    <name>yarn.scheduler.maximum-allocation-mb</name>
    <value>2048</value>
  </property>

  <property>
    <name>yarn.scheduler.minimum-allocation-mb</name>
    <value>256</value>
  </property>

  <property>
    <name>yarn.nodemanager.resource.cpu-vcores</name>
    <value>2</value>
  </property>

  <!-- 关闭虚拟内存检查(低内存 VM 必须) -->
  <property>
    <name>yarn.nodemanager.vmem-check-enabled</name>
    <value>false</value>
  </property>

  <!-- 日志聚合 -->
  <property>
    <name>yarn.log-aggregation-enable</name>
    <value>true</value>
  </property>

  <property>
    <name>yarn.log.server.url</name>
    <value>http://hd2.pblh123.cn:19888/jobhistory/logs</value>
  </property>

</configuration>

适配关键: yarn.nodemanager.resource.memory-mbyarn.scheduler.maximum-allocation-mb 须按节点实际内存修改。公式:NM内存 = 物理内存 × 70%调度最大 = min(NM内存 - 256, 2048)

hd3 的配置: 只需将 yarn.nodemanager.resource.memory-mb 改为 2000yarn.scheduler.maximum-allocation-mb 改为 1744

hd4 的配置: 改为 1200944

# 同步到各节点(分别修改内存后分发)
for host in hd3 hd4; do
    scp $HADOOP_CONF/yarn-site.xml hadoop@$host:$HADOOP_CONF/
done

5.2 mapred-site.xml
#

文件位置: ${HADOOP_HOME}/etc/hadoop/mapred-site.xml

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>

  <property>
    <name>mapreduce.framework.name</name>
    <value>yarn</value>
  </property>

  <property>
    <name>mapreduce.jobhistory.address</name>
    <value>hd2.pblh123.cn:10020</value>
  </property>

  <property>
    <name>mapreduce.jobhistory.webapp.address</name>
    <value>hd2.pblh123.cn:19888</value>
  </property>

</configuration>
# 分发到所有节点
for host in hd3 hd4; do
    scp $HADOOP_CONF/mapred-site.xml hadoop@$host:$HADOOP_CONF/
done

5.3 启动 YARN
#

# 在 hd2 上执行
source /etc/profile.d/hadoop_env.sh
start-yarn.sh
mapred --daemon start historyserver
sleep 5

5.4 验证 YARN
#

# 1. 节点列表(3 个 RUNNING)
yarn node -list -all | grep RUNNING
# 预期输出: 3 行,每行末尾 RUNNING

# 2. 进程检查
jps | grep -E "ResourceManager|NodeManager|JobHistoryServer"

# 3. MapReduce Pi 计算测试
hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.3.6.jar pi 2 5
# 预期: Estimated value of Pi is 3.148...

# 4. Web UI
# http://192.168.137.155:8088  — YARN 管理
# http://192.168.137.155:19888 — 任务历史

六、ZooKeeper 部署
#

6.1 zoo.cfg(所有节点相同)
#

文件位置: ${ZOOKEEPER_HOME}/conf/zoo.cfg

tickTime=2000
initLimit=10
syncLimit=5
dataDir=/opt/data/zookeeper
clientPort=2181
maxClientCnxns=60
autopurge.snapRetainCount=3
autopurge.purgeInterval=1

# 集群节点列表
server.1=hd2.pblh123.cn:2888:3888
server.2=hd3.pblh123.cn:2888:3888
server.3=hd4.pblh123.cn:2888:3888

适配: 替换主机名。新增节点需添加 server.N 行,N 为递增整数。

6.2 myid(每个节点不同)
#

# hd2 上
echo 1 > /opt/data/zookeeper/myid

# hd3 上
echo 2 > /opt/data/zookeeper/myid

# hd4 上
echo 3 > /opt/data/zookeeper/myid

注意: myid 的值必须与 zoo.cfgserver.X 的 X 完全对应。

# 同步 zoo.cfg 到所有节点
ZK_CONF=/opt/module/apache-zookeeper-3.5.9-bin/conf
for host in hd3 hd4; do
    scp $ZK_CONF/zoo.cfg hadoop@$host:$ZK_CONF/
done

6.3 启动 ZooKeeper
#

# 在所有节点上执行
source /etc/profile.d/hadoop_env.sh
zkServer.sh start

# 等待 3 秒
sleep 3

6.4 验证 ZooKeeper
#

# 1. 每个节点检查状态
zkServer.sh status
# 预期: 1 个 leader,2 个 follower

# 2. 客户端连接测试
zkCli.sh -server hd2.pblh123.cn:2181 <<< "ls /"
# 预期: 成功连接,列出 /

# 3. 四字命令
echo stat | nc hd2.pblh123.cn 2181 | grep Mode
# 预期: Mode: leader 或 Mode: follower

七、Hive 部署
#

Hive 服务仅在 hd2(主节点)部署。

7.1 MySQL JDBC 驱动
#

# 下载 MySQL JDBC 驱动到 Hive lib 目录
# 如无法访问外网,可手动下载后上传
HIVE_LIB=/opt/module/apache-hive-3.1.3-bin/lib
wget -P $HIVE_LIB https://repo1.maven.org/maven2/mysql/mysql-connector-java/8.0.33/mysql-connector-java-8.0.33.jar
# 或使用国内镜像
# wget -P $HIVE_LIB https://maven.aliyun.com/repository/public/mysql/mysql-connector-java/8.0.33/mysql-connector-java-8.0.33.jar

7.2 hive-site.xml
#

文件位置: /opt/module/apache-hive-3.1.3-bin/conf/hive-site.xml

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>

  <!-- Metastore 服务地址 -->
  <property>
    <name>hive.metastore.uris</name>
    <value>thrift://hd2.pblh123.cn:9083</value>
  </property>

  <!-- MySQL 连接(元数据库) -->
  <property>
    <name>javax.jdo.option.ConnectionURL</name>
    <value>jdbc:mysql://localhost:3306/hive_metastore?useSSL=false&amp;createDatabaseIfNotExist=true</value>
  </property>

  <property>
    <name>javax.jdo.option.ConnectionDriverName</name>
    <value>com.mysql.jdbc.Driver</value>
  </property>

  <property>
    <name>javax.jdo.option.ConnectionUserName</name>
    <value>hive</value>
  </property>

  <property>
    <name>javax.jdo.option.ConnectionPassword</name>
    <value>Hive@12345</value>
  </property>

  <!-- 数据仓库目录(在 HDFS 上) -->
  <property>
    <name>hive.metastore.warehouse.dir</name>
    <value>/user/hive/warehouse</value>
  </property>

  <!-- HiveServer2 绑定 -->
  <property>
    <name>hive.server2.thrift.bind.host</name>
    <value>hd2.pblh123.cn</value>
  </property>

  <property>
    <name>hive.server2.thrift.port</name>
    <value>10000</value>
  </property>

</configuration>

适配: 替换 MySQL 连接信息、Metastore 和 HiveServer2 的主机名、密码。

7.3 初始化 Hive 元数据库
#

# 在 hd2 上执行
source /etc/profile.d/hadoop_env.sh
schematool -dbType mysql -initSchema

# 预期输出: schemaTool completed

常见错误: Access denied for user 'hive' — 检查 MySQL 密码和用户授权。Table 'hive_metastore.VERSION' doesn't exist — 说明未执行 initSchema。

7.4 启动 Hive 服务
#

# 启动 Metastore(先)
nohup hive --service metastore > /opt/data/hive-metastore.log 2>&1 &
sleep 3

# 启动 HiveServer2(后)
nohup hiveserver2 > /opt/data/hiveserver2.log 2>&1 &
sleep 2

7.5 验证 Hive
#

# 1. 进程检查
jps | grep RunJar
# 预期: 2 个 RunJar 进程(Metastore + HiveServer2)

# 2. Beeline 连接
beeline -u jdbc:hive2://hd2.pblh123.cn:10000 -n hadoop << EOF
SHOW DATABASES;
CREATE DATABASE IF NOT EXISTS testdb;
USE testdb;
CREATE TABLE test (id INT, name STRING);
INSERT INTO test VALUES (1, 'hello');
SELECT * FROM test;
DROP TABLE test;
DROP DATABASE testdb;
EOF

# 3. 端口检查
netstat -tlnp | grep -E "9083|10000"
# 预期: 两行分别显示 9083 和 10000 端口在 LISTEN

八、HBase 部署
#

8.1 hbase-site.xml(所有节点相同)
#

文件位置: ${HBASE_HOME}/conf/hbase-site.xml

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>

  <property>
    <name>hbase.cluster.distributed</name>
    <value>true</value>
  </property>

  <!-- HBase 根目录(存储在 HDFS 上) -->
  <property>
    <name>hbase.rootdir</name>
    <value>hdfs://hd2.pblh123.cn:9000/hbase</value>
  </property>

  <!-- ZooKeeper 集群地址 -->
  <property>
    <name>hbase.zookeeper.quorum</name>
    <value>hd2.pblh123.cn,hd3.pblh123.cn,hd4.pblh123.cn</value>
  </property>

  <property>
    <name>hbase.zookeeper.property.clientPort</name>
    <value>2181</value>
  </property>

  <!-- 兼容性配置(HBase 2.x + Hadoop 3.x 需要) -->
  <property>
    <name>hbase.unsafe.stream.capability.enforce</name>
    <value>false</value>
  </property>

  <property>
    <name>hbase.wal.provider</name>
    <value>filesystem</value>
  </property>

</configuration>

8.2 regionservers
#

文件位置: ${HBASE_HOME}/conf/regionservers

hd2.pblh123.cn
hd3.pblh123.cn
hd4.pblh123.cn

8.3 同步配置
#

HBASE_CONF=/opt/module/hbase-2.6.4-hadoop3/conf
for host in hd3 hd4; do
    scp $HBASE_CONF/{hbase-site.xml,regionservers} hadoop@$host:$HBASE_CONF/
done

8.4 启动 HBase
#

# 在 hd2 上执行
source /etc/profile.d/hadoop_env.sh
start-hbase.sh
sleep 5

8.5 验证 HBase
#

# 1. 进程检查
# hd2: HMaster + HRegionServer
# hd3: HRegionServer
# hd4: HRegionServer
jps | grep H

# 2. HBase Shell
echo "status" | hbase shell -n 2>/dev/null
# 预期: 1 active master, 1 backup master, 3 region servers

# 3. 读写测试
hbase shell << EOF
create 'verify', 'cf'
put 'verify', 'row1', 'cf:col1', 'value1'
scan 'verify'
disable 'verify'
drop 'verify'
EOF

# 4. Web UI
# http://192.168.137.155:16010

九、Kafka 部署
#

9.1 server.properties(每个节点 broker.id 不同)
#

文件位置: ${KAFKA_HOME}/config/server.properties

需要修改的属性(三节点相同部分):

# ZooKeeper 连接
zookeeper.connect=hd2.pblh123.cn:2181,hd3.pblh123.cn:2181,hd4.pblh123.cn:2181

# 监听地址
listeners=PLAINTEXT://:9092

每节点不同的 broker.id:

# hd2: broker.id=1
# hd3: broker.id=2
# hd4: broker.id=3

# 在 hd2 上
sed -i 's/^broker.id=.*/broker.id=1/' /opt/module/kafka_2.13-2.8.0/config/server.properties
sed -i 's|^zookeeper.connect=.*|zookeeper.connect=hd2.pblh123.cn:2181,hd3.pblh123.cn:2181,hd4.pblh123.cn:2181|' /opt/module/kafka_2.13-2.8.0/config/server.properties

# hd3 上(通过 ssh 或手动执行)
ssh hd3 "sed -i 's/^broker.id=.*/broker.id=2/' /opt/module/kafka_2.13-2.8.0/config/server.properties"
ssh hd3 "sed -i 's|^zookeeper.connect=.*|zookeeper.connect=hd2.pblh123.cn:2181,hd3.pblh123.cn:2181,hd4.pblh123.cn:2181|' /opt/module/kafka_2.13-2.8.0/config/server.properties"

# hd4 上
ssh hd4 "sed -i 's/^broker.id=.*/broker.id=3/' /opt/module/kafka_2.13-2.8.0/config/server.properties"
ssh hd4 "sed -i 's|^zookeeper.connect=.*|zookeeper.connect=hd2.pblh123.cn:2181,hd3.pblh123.cn:2181,hd4.pblh123.cn:2181|' /opt/module/kafka_2.13-2.8.0/config/server.properties"

9.2 克隆节点特殊处理
#

如果节点是磁盘克隆的,/opt/data/kafkadata/meta.properties 中保存的 broker.id 可能与 server.properties 不一致,导致启动失败。

# 在 hd3 和 hd4 上删除旧的 meta.properties
ssh hd3 "rm -f /opt/data/kafkadata/meta.properties"
ssh hd4 "rm -f /opt/data/kafkadata/meta.properties"

9.3 启动 Kafka
#

# 在所有节点上执行
for host in hd2 hd3 hd4; do
    ssh $host "source /etc/profile.d/hadoop_env.sh && nohup kafka-server-start.sh -daemon $KAFKA_HOME/config/server.properties > /dev/null 2>&1 &"
done
sleep 3

9.4 验证 Kafka
#

# 1. 进程检查
jps | grep Kafka

# 2. 创建测试 Topic(3 分区 2 副本)
kafka-topics.sh --bootstrap-server hd2.pblh123.cn:9092 \
    --create --topic verify-topic --partitions 3 --replication-factor 2

# 3. 查看 Topic 列表
kafka-topics.sh --bootstrap-server hd2.pblh123.cn:9092 --list

# 4. 生产消费测试
echo "test message" | kafka-console-producer.sh \
    --bootstrap-server hd2.pblh123.cn:9092 --topic verify-topic

kafka-console-consumer.sh \
    --bootstrap-server hd2.pblh123.cn:9092 \
    --topic verify-topic --from-beginning --max-messages 1
# 预期输出: test message

# 5. 清理
kafka-topics.sh --bootstrap-server hd2.pblh123.cn:9092 --delete --topic verify-topic

十、Spark 部署
#

10.1 spark-env.sh
#

文件位置: ${SPARK_HOME}/conf/spark-env.sh

#!/usr/bin/env bash
export JAVA_HOME=/opt/module/jdk1.8.0_471
export HADOOP_HOME=/opt/module/hadoop-3.3.6
export HADOOP_CONF_DIR=$HADOOP_HOME/etc/hadoop
export SPARK_HOME=/opt/module/spark-3.5.8-bin-hadoop3-scala2.13
export SPARK_CONF_DIR=$SPARK_HOME/conf

# History Server 配置
export SPARK_HISTORY_OPTS="-Dspark.history.ui.port=18080 \
  -Dspark.history.fs.logDirectory=hdfs://hd2.pblh123.cn:9000/spark-history \
  -Dspark.history.retainedApplications=30"

# Daemon 内存(低内存 VM)
export SPARK_DAEMON_MEMORY=256m

10.2 spark-defaults.conf
#

文件位置: ${SPARK_HOME}/conf/spark-defaults.conf

# 运行模式:YARN 集群模式
spark.master                       yarn
spark.submit.deployMode            cluster

# 事件日志(History Server 使用)
spark.eventLog.enabled             true
spark.eventLog.dir                 hdfs://hd2.pblh123.cn:9000/spark-history
spark.history.fs.logDirectory      hdfs://hd2.pblh123.cn:9000/spark-history

# 序列化
spark.serializer                   org.apache.spark.serializer.KryoSerializer

# 内存调优(低内存 VM)
spark.driver.memory                512m
spark.executor.memory              512m
spark.executor.cores               1
spark.executor.instances           2
spark.yarn.am.memory               512m
spark.yarn.maxAppAttempts          2

# SQL 调优
spark.sql.shuffle.partitions       2
spark.driver.maxResultSize         256m

适配: 内存充足的集群可增大 executor.memoryexecutor.instances 等参数。

10.3 链接 hive-site.xml
#

Spark SQL 需要 Hive 配置来访问 Hive 元数据:

ln -sf /opt/module/apache-hive-3.1.3-bin/conf/hive-site.xml \
    /opt/module/spark-3.5.8-bin-hadoop3-scala2.13/conf/hive-site.xml

10.4 同步配置
#

SPARK_CONF=/opt/module/spark-3.5.8-bin-hadoop3-scala2.13/conf
for host in hd3 hd4; do
    scp $SPARK_CONF/{spark-env.sh,spark-defaults.conf} hadoop@$host:$SPARK_CONF/
    ssh $host "ln -sf /opt/module/apache-hive-3.1.3-bin/conf/hive-site.xml $SPARK_CONF/hive-site.xml"
done

10.5 创建 HDFS 工作目录
#

hdfs dfs -mkdir -p /spark-history /user/hive/warehouse
hdfs dfs -chmod 777 /spark-history

10.6 启动 Spark History Server
#

# 在 hd2 上
source /etc/profile.d/hadoop_env.sh
$SPARK_HOME/sbin/start-history-server.sh

10.7 验证 Spark
#

# 1. Spark Pi 集群模式
spark-submit --master yarn --deploy-mode cluster \
    --class org.apache.spark.examples.SparkPi \
    $SPARK_HOME/examples/jars/spark-examples_2.13-3.5.8.jar 100

# 预期: 提交后 YARN 上出现 RUNNING 任务,完成后状态 FINISHED
# 查看结果: yarn logs -applicationId <app_id> | grep "Pi is"

# 2. Spark SQL + Hive 集成测试
spark-sql --master yarn --deploy-mode client << EOF
SHOW DATABASES;
CREATE DATABASE IF NOT EXISTS testdb;
USE testdb;
CREATE TABLE test (id INT, name STRING);
INSERT INTO test VALUES (1, 'hello');
SELECT * FROM test;
DROP TABLE test;
DROP DATABASE testdb;
EOF

# 3. Web UI
# http://192.168.137.155:18080  — Spark History Server

十一、集群验证
#

11.1 完整进程检查
#

各节点执行 jps 后预期进程:

hd2 (约 12 个):

NameNode, DataNode, ResourceManager, NodeManager,
QuorumPeerMain, JobHistoryServer, HMaster, HRegionServer,
Kafka, HistoryServer, RunJar(Metastore), RunJar(HiveServer2)

hd3 (约 7 个):

DataNode, SecondaryNameNode, NodeManager,
QuorumPeerMain, HRegionServer, Kafka

hd4 (约 6 个):

DataNode, NodeManager, QuorumPeerMain,
HRegionServer, Kafka
# 快速检查脚本
for host in hd2 hd3 hd4; do
    echo "=== $host ==="
    ssh $host "source /etc/profile.d/hadoop_env.sh && jps -l | grep -v Jps | sort"
    echo ""
done

11.2 各组件快速验证
#

# HDFS 读写
echo "verify" | hdfs dfs -put - /verify.txt && hdfs dfs -cat /verify.txt && hdfs dfs -rm /verify.txt

# YARN 计算
hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.3.6.jar pi 2 5

# ZooKeeper
echo stat | nc hd2.pblh123.cn 2181 | grep Mode

# Hive
beeline -u jdbc:hive2://hd2.pblh123.cn:10000 -n hadoop -e "SHOW DATABASES;"

# HBase
echo "status" | hbase shell -n

# Kafka
kafka-topics.sh --bootstrap-server hd2.pblh123.cn:9092 --list

# Spark
spark-submit --master yarn --deploy-mode cluster \
    --class org.apache.spark.examples.SparkPi \
    $SPARK_HOME/examples/jars/spark-examples_2.13-3.5.8.jar 10

十二、集群管理
#

12.1 一键启停
#

# Shell 版(在集群节点上运行)
bash cluster_ctl.sh start      # 启动全部
bash cluster_ctl.sh stop       # 停止全部
bash cluster_ctl.sh restart    # 重启全部
bash cluster_ctl.sh status     # 查看状态
bash cluster_ctl.sh start kafka  # 单独启动 Kafka

# Python 版(从管理机运行)
python cluster_ctl.py start
python cluster_ctl.py stop
python cluster_ctl.py restart
python cluster_ctl.py status
python cluster_ctl.py start hdfs

12.2 关机脚本
#

# Shell 版 — 先停服务再关机
bash shutdown_cluster.sh

# 跳过服务停止,直接强制关机
bash shutdown_cluster.sh --force

# Python 版(从管理机执行)
python shutdown_cluster.py
python shutdown_cluster.py --force

脚本流程: ① 确认提示 → ② 停止集群所有服务 → ③ 关闭从节点 → ④ 关闭主节点。

12.3 服务独立操作
#

# HDFS
start-dfs.sh / stop-dfs.sh

# YARN
start-yarn.sh / stop-yarn.sh

# ZooKeeper
zkServer.sh start / zkServer.sh stop / zkServer.sh status

# Hive
nohup hive --service metastore > /opt/data/hive-metastore.log 2>&1 &
nohup hiveserver2 > /opt/data/hiveserver2.log 2>&1 &

# HBase
start-hbase.sh / stop-hbase.sh

# Kafka
kafka-server-start.sh -daemon $KAFKA_HOME/config/server.properties
kafka-server-stop.sh

# Spark History
$SPARK_HOME/sbin/start-history-server.sh
$SPARK_HOME/sbin/stop-history-server.sh

12.4 日志路径
#

组件日志路径
HDFS NameNode$HADOOP_HOME/logs/hadoop-hadoop-namenode-*.log
HDFS DataNode$HADOOP_HOME/logs/hadoop-hadoop-datanode-*.log
YARN RM$HADOOP_HOME/logs/yarn-hadoop-resourcemanager-*.log
YARN NM$HADOOP_HOME/logs/yarn-hadoop-nodemanager-*.log
ZooKeeper$ZOOKEEPER_HOME/logs/zookeeper.out
Kafka$KAFKA_HOME/logs/server.log
Spark$SPARK_HOME/logs/
HBase/opt/data/hbase/logs/
Hive/opt/data/hive-metastore.log, /opt/data/hiveserver2.log

12.5 端口清单
#

端口服务用途
9000HDFS NameNodeRPC
9870HDFS NameNodeWeb UI
9868HDFS SecondaryNameNodeWeb UI
8088YARN ResourceManagerWeb UI
10020MapReduce JobHistoryRPC
19888MapReduce JobHistoryWeb UI
2181ZooKeeperClient
2888ZooKeeperPeer 通信
3888ZooKeeperLeader 选举
9083Hive MetastoreThrift
10000HiveServer2Thrift
9092KafkaBroker
16010HBase MasterWeb UI
18080Spark History ServerWeb UI

12.6 Web 管理界面
#

服务URL
HDFS NameNodehttp://192.168.137.155:9870
YARN ResourceManagerhttp://192.168.137.155:8088
Spark History Serverhttp://192.168.137.155:18080
HBase Masterhttp://192.168.137.155:16010
Job Historyhttp://192.168.137.155:19888

十三、一键脚本使用
#

13.1 config.ini 模板
#

项目提供完整的一键部署脚本,只需修改 config.ini 后执行 bash deploy.sh

# ============================================================
# 大数据集群全局配置文件
# 修改此文件后执行 bash deploy.sh 即可完成一键部署
# ============================================================

# ---------- 集群节点 ----------
[NODES]
hd2=192.168.137.155
hd3=192.168.137.156
hd4=192.168.137.157

# 各节点 YARN NodeManager 可用内存 (MB)
[NODE_MEMORY]
hd2=2800
hd3=2000
hd4=1200

[NODE_CPU]
hd2=2
hd3=2
hd4=2

# ---------- SSH 登录 ----------
[SSH]
user=hadoop
password=hadoop

# ---------- 安装路径 ----------
[PATHS]
base_dir=/opt/module
data_dir=/opt/data

# ---------- 组件版本 ----------
[VERSIONS]
jdk=jdk1.8.0_471
hadoop=hadoop-3.3.6
zookeeper=apache-zookeeper-3.5.9-bin
hive=apache-hive-3.1.3-bin
hbase=hbase-2.6.4-hadoop3
kafka=kafka_2.13-2.8.0
spark=spark-3.5.8-bin-hadoop3-scala2.13

# ---------- MySQL ----------
[MYSQL]
host=localhost
port=3306
database=hive_metastore
user=hive
password=Hive@12345

# ---------- 端口配置 ----------
[PORTS]
hdfs_namenode=9000
hdfs_web=9870
yarn_web=8088
jobhistory=19888
zookeeper_client=2181
hive_metastore=9083
hive_server2=10000
hbase_master_web=16010
kafka=9092
spark_history=18080

# ---------- HDFS 配置 ----------
[HDFS]
replication=2
block_size_mb=64
namenode_dir=/opt/data/namenode
datanode_dir=/opt/data/datanode
hadoop_tmp=/opt/data/hadoop-tmp

# ---------- ZooKeeper ----------
[ZOOKEEPER]
tick_time=2000
init_limit=10
sync_limit=5
data_dir=/opt/data/zookeeper

# ---------- Spark 内存 ----------
[SPARK]
driver_memory=512m
executor_memory=512m
executor_cores=1
executor_instances=2
am_memory=512m

# ---------- Java 堆内存 ----------
[JAVA_HEAP]
namenode=512m
datanode=256m
rm=512
nm=256

13.2 部署流程
#

# 1. 编辑配置
vi config.ini

# 2. 安装 sshpass(首次)
sudo yum install -y sshpass

# 3. 一键部署
bash deploy.sh

# 4. 验证
bash cluster_ctl.sh status

13.3 管理机远程部署
#

# 从 Windows/其他机器远程部署
pip install paramiko
python deploy.py
python cluster_ctl.py start
python cluster_ctl.py status

十四、故障排查
#

HDFS DataNode 未注册
#

# 检查 workers 文件: 主机名必须与节点 hostname 一致
cat $HADOOP_HOME/etc/hadoop/workers

# 检查 /etc/hosts: 所有节点 hosts 文件需一致
cat /etc/hosts | grep hd

# 检查 DataNode 日志
tail -100 $HADOOP_HOME/logs/hadoop-hadoop-datanode-*.log | grep -i error

YARN NodeManager 未启动
#

# 内存不足
free -h
# 调整 yarn-site.xml 中 yarn.nodemanager.resource.memory-mb
# 建议为物理内存的 70-80%

ZooKeeper 选举失败
#

# myid 值必须和 zoo.cfg 中 server.X 一致
cat /opt/data/zookeeper/myid
grep "server\." $ZOOKEEPER_HOME/conf/zoo.cfg

# 检查防火墙和网络
telnet hd3 2888

Kafka 克隆节点启动失败
#

# 错误: broker.id 1 already registered
# 原因: meta.properties 中记录的 broker.id 不同
rm -f /opt/data/kafkadata/meta.properties
kafka-server-start.sh -daemon $KAFKA_HOME/config/server.properties

HBase Master 启动后退出
#

# 1. 确认 ZooKeeper 正常运行
zkServer.sh status

# 2. 确认 HDFS /hbase 目录存在且权限正确
hdfs dfs -ls /

# 3. 检查日志
cat /opt/data/hbase/logs/hbase-hadoop-master-*.log | grep ERROR

HDFS 安全模式
#

hdfs dfsadmin -safemode get
hdfs dfsadmin -safemode leave

Hive 连接 MySQL 失败
#

# 检查 MySQL 用户授权
mysql -u hive -p'Hive@12345' -e "SHOW DATABASES;"

# 检查 JDBC 驱动
ls /opt/module/apache-hive-3.1.3-bin/lib/mysql-connector-java-*.jar

附录:适配新集群 Checklist
#

部署到新集群时,按以下步骤操作:

  1. [ ] 修改 /etc/hosts: 更新所有节点的 IP-主机名映射
  2. [ ] 修改 config.ini: 更新 [NODES] 的 IP 和 [NODE_MEMORY] 的记忆体配置
  3. [ ] 修改 [SSH]: 更新用户名和密码
  4. [ ] 修改 [VERSIONS]: 确认各组件版本目录名与 /opt/module/ 下一致
  5. [ ] 修改 [MYSQL]: 更新数据库连接信息
  6. [ ] 确认域名后缀: deploy.sh 中硬编码的 .pblh123.cn 需要替换为实际域名(或修改为从 config.ini 读取)
  7. [ ] 确认副本数: [HDFS] replication 不能超过 DataNode 节点数
  8. [ ] 确认内存配置: 每节点 NODE_MEMORY 设为物理内存的 70-80%
  9. [ ] 运行 bash deploy.sh: 一键部署
  10. [ ] 运行 bash cluster_ctl.sh status: 验证集群状态
  11. [ ] 逐个验证组件: HDFS 读写 → YARN Pi → ZK → Hive → HBase → Kafka → Spark

域名后缀适配
#

当前 deploy.sh 中硬编码了 .pblh123.cn 后缀。如你的环境使用不同域名(或无域名),有两种处理方式:

方式一: 在 hosts 文件中配置完整 FQDN:

# /etc/hosts
192.168.137.155 hd2.yourdomain.com hd2

方式二: 在 /etc/hosts 中直接用短名,然后将脚本中的 .pblh123.cn 全局替换为空(即只用短主机名)。需修改文件: deploy.sh, deploy.py, cluster_ctl.sh, cluster_ctl.py


附录:脚本文件清单
#

文件用途运行位置
config.ini全局配置文件部署前编辑
deploy.shShell 一键部署脚本集群主节点
deploy.pyPython 部署脚本管理机
cluster_ctl.shShell 集群启停集群节点
cluster_ctl.pyPython 集群启停管理机
ssh_exec.pySSH 连接底层模块被 Python 脚本引用
verify.py集群验证脚本管理机
cluster_check.py快速状态检查管理机
deep_check.py深度诊断管理机
shutdown_cluster.shShell 集群关机集群节点
shutdown_cluster.pyPython 集群关机管理机