# Hadoop 集群搭建完整教程

16 阅读7分钟

大数据开发入门必备:Hadoop 架构原理、集群规划、环境准备、安装配置、高可用配置、性能调优、故障排查,从 0 到 1 搭建生产级 Hadoop 集群


📌 前言

为什么学习 Hadoop 集群搭建?

面试必问:

- "你们公司 Hadoop 集群多大?"
- "NameNode 内存多少?"
- "如何配置高可用?"
- "遇到 DataNode 宕机怎么处理?"

有集群搭建经验,面试加分!

工作需要:

- 搭建测试环境(开发/测试)
- 扩容生产集群
- 故障排查和恢复
- 性能调优

学习价值:

- 理解 Hadoop 架构(NameNode/DataNode/ResourceManager)
- 掌握大数据生态(Hive/Spark/Flink 都依赖 Hadoop)
- 提升运维能力(监控/告警/故障处理)

🏗️ Hadoop 架构深度解析

Hadoop 核心组件

Hadoop 3.x 架构:

┌─────────────────────────────────────────────────────────────┐
│                      HDFS(分布式文件系统)                  │
│  ┌─────────────┐              ┌─────────────┐              │
│  │ NameNode    │  ← 主节点    │ Secondary   │              │
│  │ (元数据)    │              │ NameNode    │              │
│  └──────┬──────┘              └─────────────┘              │
│         │                                                   │
│    ┌────┴────┬────────────┬────────────┐                   │
│    ↓         ↓            ↓            ↓                   │
│ ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐                       │
│ │Data  │ │Data  │ │Data  │ │Data  │  ← 数据节点           │
│ │Node  │ │Node  │ │Node  │ │Node  │                       │
│ └──────┘ └──────┘ └──────┘ └──────┘                       │
└─────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────┐
│                   YARN(资源调度系统)                       │
│  ┌─────────────┐                                            │
│  │ResourceManager│  ← 资源管理器                            │
│  └──────┬──────┘                                            │
│         │                                                   │
│    ┌────┴────┬────────────┬────────────┐                   │
│    ↓         ↓            ↓            ↓                   │
│ ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐                       │
│ │Node  │ │Node  │ │Node  │ │Node  │  ← 节点管理器          │
│ │Manager│ │Manager│ │Manager│ │Manager│                   │
│ └──────┘ └──────┘ └──────┘ └──────┘                       │
└─────────────────────────────────────────────────────────────┘

组件职责:

组件职责重要性
NameNode管理 HDFS 元数据(文件/目录/权限)⭐⭐⭐⭐⭐
DataNode存储实际数据块⭐⭐⭐⭐⭐
Secondary NameNode辅助 NameNode(合并 fsimage)⭐⭐⭐
ResourceManager集群资源管理和调度⭐⭐⭐⭐⭐
NodeManager单节点资源管理⭐⭐⭐⭐

Hadoop 高可用(HA)架构

生产环境必须配置 HA(避免单点故障):

┌─────────────────────────────────────────────────────────────┐
│                        HDFS HA                              │
│                                                             │
│  ┌─────────────┐         ┌─────────────┐                   │
│  │ NameNode1   │ ←───→   │ NameNode2   │                   │
│  │ (Active)    │  Journal│ (Standby)   │                   │
│  │             │  Nodes  │             │                   │
│  └─────────────┘         └─────────────┘                   │
│         ↑                     ↑                             │
│         └──────────┬──────────┘                             │
│                    ↓                                        │
│             ┌─────────────┐                                 │
│             │ ZooKeeper   │  ← 故障转移                     │
│             │ (Journal)   │                                 │
│             └─────────────┘                                 │
└─────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────┐
│                       YARN HA                               │
│                                                             │
│  ┌─────────────┐         ┌─────────────┐                   │
│  │ResourceManager1│ ←─→ │ResourceManager2│                │
│  │ (Active)    │  ZKFC   │ (Standby)   │                   │
│  └─────────────┘         └─────────────┘                   │
└─────────────────────────────────────────────────────────────┘

HA 关键组件:

组件作用数量
JournalNode共享编辑日志3 或 5(奇数)
ZooKeeper故障检测和选举3 或 5(奇数)
ZKFCZooKeeper 故障转移客户端每个 NameNode 一个

📋 集群规划

生产环境推荐配置

小型集群(10 节点以下):

节点类型数量CPU内存磁盘用途
Master216 核64GB500GB SSDNameNode + RM
Worker5-1032 核128GB10TB HDDDataNode + NM
边缘节点18 核32GB500GB SSD客户端

中型集群(10-50 节点):

节点类型数量CPU内存磁盘用途
Master232 核128GB1TB SSDNameNode + RM
Worker10-5032-64 核256GB20-50TBDataNode + NM
边缘节点2-516 核64GB500GB SSD客户端

大型集群(50+ 节点):

节点类型数量CPU内存磁盘用途
Master3-564 核256GB+2TB SSDNameNode + RM
Worker50+64 核512GB50TB+DataNode + NM
边缘节点5-1016 核64GB500GB SSD客户端

本教程集群规划(3 节点测试环境)

┌──────────────┬──────────────┬──────────────┐
│  hadoop1     │  hadoop2     │  hadoop3     │
│  192.168.1.101│ 192.168.1.102│ 192.168.1.103│
├──────────────┼──────────────┼──────────────┤
│ NameNode     │ NameNode     │              │
│ (Active)     │ (Standby)    │              │
│ ResourceManager │ ResourceManager │          │
│ NodeManager  │ NodeManager  │ NodeManager  │
│ DataNode     │ DataNode     │ DataNode     │
│ JournalNode  │ JournalNode  │ JournalNode  │
│ ZooKeeper    │ ZooKeeper    │ ZooKeeper    │
└──────────────┴──────────────┴──────────────┘

软件版本:
- CentOS 7.9
- Hadoop 3.3.6
- JDK 1.8.0_301
- ZooKeeper 3.7.1

🔧 环境准备

1. 系统配置(所有节点)

主机名配置:

# 修改主机名
hostnamectl set-hostname hadoop1
hostnamectl set-hostname hadoop2
hostnamectl set-hostname hadoop3

# 配置 hosts
cat >> /etc/hosts << EOF
192.168.1.101 hadoop1
192.168.1.102 hadoop2
192.168.1.103 hadoop3
EOF

# 验证
ping hadoop1
ping hadoop2
ping hadoop3

关闭防火墙:

# 关闭防火墙
systemctl stop firewalld
systemctl disable firewalld

# 关闭 SELinux
setenforce 0
sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config

# 验证
systemctl status firewalld  # 应显示 inactive
getenforce  # 应显示 Disabled

创建用户:

# 创建 hadoop 用户
useradd -m hadoop
passwd hadoop  # 设置密码

# 配置 sudo(可选)
echo "hadoop ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers

# 切换到 hadoop 用户
su - hadoop

2. JDK 安装(所有节点)

# 创建目录
sudo mkdir -p /opt/module
sudo chown hadoop:hadoop /opt/module

# 下载 JDK
cd /opt/module
wget https://download.oracle.com/java/8u301/jdk-8u301-linux-x64.tar.gz

# 解压
tar -zxvf jdk-8u301-linux-x64.tar.gz
mv jdk1.8.0_301 jdk1.8

# 配置环境变量
cat >> ~/.bashrc << 'EOF'
# JAVA
export JAVA_HOME=/opt/module/jdk1.8
export PATH=$PATH:$JAVA_HOME/bin
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
EOF

# 生效
source ~/.bashrc

# 验证
java -version

3. SSH 免密登录(所有节点)

# 生成密钥
ssh-keygen -t rsa  # 一路回车

# 分发公钥(在 hadoop1 执行)
ssh-copy-id hadoop1
ssh-copy-id hadoop2
ssh-copy-id hadoop3

# 验证(无需密码)
ssh hadoop1
ssh hadoop2
ssh hadoop3

🔧 Hadoop 安装配置

1. Hadoop 安装(所有节点)

# 下载 Hadoop
cd /opt/module
wget https://archive.apache.org/dist/hadoop/common/hadoop-3.3.6/hadoop-3.3.6.tar.gz

# 解压
tar -zxvf hadoop-3.3.6.tar.gz
mv hadoop-3.3.6 hadoop-3.3.6

# 配置环境变量
cat >> ~/.bashrc << 'EOF'
# Hadoop
export HADOOP_HOME=/opt/module/hadoop-3.3.6
export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin
export HADOOP_CONF_DIR=$HADOOP_HOME/etc/hadoop
export YARN_CONF_DIR=$HADOOP_HOME/etc/hadoop
EOF

# 生效
source ~/.bashrc

# 验证
hadoop version

2. Hadoop 配置文件

core-site.xml:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
    <!-- HDFS 默认地址 -->
    <property>
        <name>fs.defaultFS</name>
        <value>hdfs://mycluster</value>
    </property>
    
    <!-- 临时目录 -->
    <property>
        <name>hadoop.tmp.dir</name>
        <value>/opt/module/hadoop-3.3.6/data/tmp</value>
    </property>
    
    <!-- 回收站时间(分钟) -->
    <property>
        <name>fs.trash.interval</name>
        <value>1440</value>
    </property>
    
    <!-- 启用回收站 -->
    <property>
        <name>fs.trash.checkpoint.interval</name>
        <value>1440</value>
    </property>
    
    <!-- ZooKeeper 地址 -->
    <property>
        <name>ha.zookeeper.quorum</name>
        <value>hadoop1:2181,hadoop2:2181,hadoop3:2181</value>
    </property>
</configuration>

hdfs-site.xml:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
    <!-- 副本数 -->
    <property>
        <name>dfs.replication</name>
        <value>3</value>
    </property>
    
    <!-- NameNode 数据目录 -->
    <property>
        <name>dfs.namenode.name.dir</name>
        <value>file:///opt/module/hadoop-3.3.6/data/namenode</value>
    </property>
    
    <!-- DataNode 数据目录 -->
    <property>
        <name>dfs.datanode.data.dir</name>
        <value>file:///opt/module/hadoop-3.3.6/data/datanode</value>
    </property>
    
    <!-- 集群 ID -->
    <property>
        <name>dfs.nameservices</name>
        <value>mycluster</value>
    </property>
    
    <!-- NameNode ID -->
    <property>
        <name>dfs.ha.namenodes.mycluster</name>
        <value>nn1,nn2</value>
    </property>
    
    <!-- NameNode RPC 地址 -->
    <property>
        <name>dfs.namenode.rpc-address.mycluster.nn1</name>
        <value>hadoop1:8020</value>
    </property>
    <property>
        <name>dfs.namenode.rpc-address.mycluster.nn2</name>
        <value>hadoop2:8020</value>
    </property>
    
    <!-- NameNode HTTP 地址 -->
    <property>
        <name>dfs.namenode.http-address.mycluster.nn1</name>
        <value>hadoop1:9870</value>
    </property>
    <property>
        <name>dfs.namenode.http-address.mycluster.nn2</name>
        <value>hadoop2:9870</value>
    </property>
    
    <!-- JournalNode 地址 -->
    <property>
        <name>dfs.namenode.shared.edits.dir</name>
        <value>qjournal://hadoop1:8485;hadoop2:8485;hadoop3:8485/mycluster</value>
    </property>
    
    <!-- 故障转移代理 -->
    <property>
        <name>dfs.client.failover.proxy.provider.mycluster</name>
        <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
    </property>
    
    <!--  fencing 方法 -->
    <property>
        <name>dfs.ha.fencing.methods</name>
        <value>sshfence</value>
    </property>
    <property>
        <name>dfs.ha.fencing.ssh.private-key-files</name>
        <value>/home/hadoop/.ssh/id_rsa</value>
    </property>
    
    <!-- JournalNode 数据目录 -->
    <property>
        <name>dfs.journalnode.edits.dir</name>
        <value>/opt/module/hadoop-3.3.6/data/journalnode</value>
    </property>
    
    <!-- 启用自动故障转移 -->
    <property>
        <name>dfs.ha.automatic-failover.enabled</name>
        <value>true</value>
    </property>
</configuration>

yarn-site.xml:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
    <!-- 启用 ResourceManager HA -->
    <property>
        <name>yarn.resourcemanager.ha.enabled</name>
        <value>true</value>
    </property>
    
    <!-- 集群 ID -->
    <property>
        <name>yarn.resourcemanager.cluster-id</name>
        <value>mycluster</value>
    </property>
    
    <!-- ResourceManager ID -->
    <property>
        <name>yarn.resourcemanager.ha.rm-ids</name>
        <value>rm1,rm2</value>
    </property>
    
    <!-- ResourceManager 地址 -->
    <property>
        <name>yarn.resourcemanager.hostname.rm1</name>
        <value>hadoop1</value>
    </property>
    <property>
        <name>yarn.resourcemanager.hostname.rm2</name>
        <value>hadoop2</value>
    </property>
    
    <!-- ZooKeeper 地址 -->
    <property>
        <name>yarn.resourcemanager.zk-address</name>
        <value>hadoop1:2181,hadoop2:2181,hadoop3:2181</value>
    </property>
    
    <!-- NodeManager 配置 -->
    <property>
        <name>yarn.nodemanager.aux-services</name>
        <value>mapreduce_shuffle</value>
    </property>
    
    <!-- 环境变量白名单 -->
    <property>
        <name>yarn.nodemanager.env-whitelist</name>
        <value>JAVA_HOME,HADOOP_COMMON_HOME,HADOOP_HDFS_HOME,HADOOP_CONF_DIR,CLASSPATH_PREPEND_DISTCACHE,HADOOP_YARN_HOME,HADOOP_MAPRED_HOME</value>
    </property>
    
    <!-- 内存配置 -->
    <property>
        <name>yarn.scheduler.maximum-allocation-mb</name>
        <value>8192</value>
    </property>
    <property>
        <name>yarn.scheduler.minimum-allocation-mb</name>
        <value>512</value>
    </property>
    
    <!-- 虚拟内存检查(关闭,避免任务被杀) -->
    <property>
        <name>yarn.nodemanager.vmem-check-enabled</name>
        <value>false</value>
    </property>
</configuration>

mapred-site.xml:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
    <!-- MapReduce 框架 -->
    <property>
        <name>mapreduce.framework.name</name>
        <value>yarn</value>
    </property>
    
    <!-- 历史服务器地址 -->
    <property>
        <name>mapreduce.jobhistory.address</name>
        <value>hadoop1:10020</value>
    </property>
    <property>
        <name>mapreduce.jobhistory.webapp.address</name>
        <value>hadoop1:19888</value>
    </property>
    
    <!-- 内存配置 -->
    <property>
        <name>mapreduce.map.memory.mb</name>
        <value>1024</value>
    </property>
    <property>
        <name>mapreduce.reduce.memory.mb</name>
        <value>2048</value>
    </property>
    <property>
        <name>mapreduce.map.java.opts</name>
        <value>-Xmx800m</value>
    </property>
    <property>
        <name>mapreduce.reduce.java.opts</name>
        <value>-Xmx1600m</value>
    </property>
</configuration>

workers(从节点):

# 编辑 workers 文件
cat > $HADOOP_HOME/etc/hadoop/workers << EOF
hadoop1
hadoop2
hadoop3
EOF

3. ZooKeeper 配置(所有节点)

# 下载 ZooKeeper
cd /opt/module
wget https://archive.apache.org/dist/zookeeper/zookeeper-3.7.1/apache-zookeeper-3.7.1-bin.tar.gz

# 解压
tar -zxvf apache-zookeeper-3.7.1-bin.tar.gz
mv apache-zookeeper-3.7.1-bin zookeeper-3.7.1

# 创建数据目录
mkdir -p /opt/module/zookeeper-3.7.1/data

# 配置 myid(每个节点不同)
# hadoop1:
echo "1" > /opt/module/zookeeper-3.7.1/data/myid
# hadoop2:
echo "2" > /opt/module/zookeeper-3.7.1/data/myid
# hadoop3:
echo "3" > /opt/module/zookeeper-3.7.1/data/myid

# 配置 zoo.cfg
cat > /opt/module/zookeeper-3.7.1/conf/zoo.cfg << EOF
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/opt/module/zookeeper-3.7.1/data
clientPort=2181

# 集群配置
server.1=hadoop1:2888:3888
server.2=hadoop2:2888:3888
server.3=hadoop3:2888:3888
EOF

🚀 集群启动

1. 分发配置(在 hadoop1 执行)

# 分发 Hadoop
scp -r /opt/module/hadoop-3.3.6 hadoop2:/opt/module/
scp -r /opt/module/hadoop-3.3.6 hadoop3:/opt/module/

# 分发 ZooKeeper
scp -r /opt/module/zookeeper-3.7.1 hadoop2:/opt/module/
scp -r /opt/module/zookeeper-3.7.1 hadoop3:/opt/module/

# 分发环境变量
scp ~/.bashrc hadoop2:~
scp ~/.bashrc hadoop3:~

2. 启动顺序

第一步:启动 ZooKeeper(所有节点):

# 在所有节点执行
/opt/module/zookeeper-3.7.1/bin/zkServer.sh start

# 验证
/opt/module/zookeeper-3.7.1/bin/zkServer.sh status
# 应显示 leader 或 follower

第二步:初始化 HDFS(仅 hadoop1):

# 格式化 NameNode(仅第一次)
hdfs namenode -format

# 初始化共享存储
hdfs zkfc -formatZK

# 启动 JournalNode
hdfs --daemon start journalnode

第三步:启动 HDFS(所有节点):

# 启动 DataNode
hdfs --daemon start datanode

# 启动 ZKFC(故障转移)
hdfs --daemon start zkfc

第四步:启动 YARN(所有节点):

# 启动 ResourceManager
yarn --daemon start resourcemanager

# 启动 NodeManager
yarn --daemon start nodemanager

3. 验证集群

HDFS 验证:

# 查看 NameNode 状态
hdfs haadmin -getServiceState nn1
hdfs haadmin -getServiceState nn2
# 应显示 active 和 standby

# 查看 HDFS 空间
hdfs dfsadmin -report

# 测试 HDFS
hdfs dfs -mkdir /test
hdfs dfs -put /etc/hosts /test
hdfs dfs -ls /test

YARN 验证:

# 查看节点
yarn node -list

# 提交测试任务
hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.3.6.jar pi 10 100

# 查看应用
yarn application -list

Web UI 验证:

HDFS NameNode:
- http://hadoop1:9870
- http://hadoop2:9870

YARN ResourceManager:
- http://hadoop1:8088
- http://hadoop2:8088

⚠️ 常见故障排查

故障 1:DataNode 无法启动

现象:

hdfs dfsadmin -report
DataNodes: 0

排查:

# 1. 查看日志
tail -100 $HADOOP_HOME/logs/hadoop-hadoop-datanode-hadoop1.log

# 2. 常见原因
# - 磁盘空间不足
df -h

# - 端口被占用
netstat -tunlp | grep 9864

# - 权限问题
ls -ld /opt/module/hadoop-3.3.6/data/datanode

# 3. 解决方案
# 清理数据目录(测试环境)
rm -rf /opt/module/hadoop-3.3.6/data/datanode/*

# 重新启动
hdfs --daemon stop datanode
hdfs --daemon start datanode

故障 2:NameNode 无法切换 Active

现象:

hdfs haadmin -getServiceState nn1
# 一直显示 standby

排查:

# 1. 查看 ZKFC 日志
tail -100 $HADOOP_HOME/logs/hadoop-hadoop-zkfc-hadoop1.log

# 2. 检查 ZooKeeper
/opt/module/zookeeper-3.7.1/bin/zkCli.sh
ls /hadoop-ha

# 3. 检查 fencing
# 确保 SSH 免密配置正确
ssh hadoop1 hostname

# 4. 手动切换
hdfs haadmin -transitionToActive nn1 --forceactive

故障 3:YARN 任务失败

现象:

Container killed by YARN for exceeding memory limits

解决:

<!-- yarn-site.xml -->
<property>
    <name>yarn.nodemanager.vmem-check-enabled</name>
    <value>false</value>
</property>

<!-- mapred-site.xml -->
<property>
    <name>mapreduce.map.memory.mb</name>
    <value>2048</value>
</property>
<property>
    <name>mapreduce.map.java.opts</name>
    <value>-Xmx1600m</value>
</property>

📋 性能调优

HDFS 调优

<!-- hdfs-site.xml -->

<!-- NameNode 内存优化 -->
<property>
    <name>dfs.namenode.handler.count</name>
    <value>100</value>
</property>

<!-- 数据块大小 -->
<property>
    <name>dfs.blocksize</name>
    <value>134217728</value>  <!-- 128MB -->
</property>

<!-- 副本放置策略 -->
<property>
    <name>dfs.namenode.replication.rack-awareness.policy</name>
    <value>org.apache.hadoop.hdfs.server.namenode.RackAwarePlacerDefaultImpl</value>
</property>

YARN 调优

<!-- yarn-site.xml -->

<!-- ResourceManager 内存 -->
<property>
    <name>yarn.resourcemanager.scheduler.maximum-allocation-mb</name>
    <value>16384</value>
</property>

<!-- NodeManager 内存 -->
<property>
    <name>yarn.nodemanager.resource.memory-mb</name>
    <value>32768</value>
</property>

<!-- 虚拟 CPU 核心数 -->
<property>
    <name>yarn.nodemanager.resource.cpu-vcores</name>
    <value>16</value>
</property>

📋 最佳实践清单

安装部署

  • 配置主机名和 hosts
  • 关闭防火墙和 SELinux
  • 配置 SSH 免密登录
  • 配置 NTP 时间同步
  • 配置 HA(生产环境必须)

参数配置

  • 合理设置副本数(测试 1,生产 3)
  • 配置数据目录(多磁盘)
  • 开启回收站
  • 配置日志级别

监控运维

  • 配置监控告警(Prometheus + Grafana)
  • 定期清理日志
  • 定期备份元数据
  • 定期巡检(磁盘/CPU/内存)

安全加固

  • 配置 Kerberos(生产环境)
  • 配置 Ranger(权限管理)
  • 开启审计日志
  • 限制访问 IP

📌 总结

核心要点

组件关键配置重要性
HDFS HAJournalNode + ZooKeeper⭐⭐⭐⭐⭐
YARN HAResourceManager HA⭐⭐⭐⭐⭐
参数调优内存 + 并行度⭐⭐⭐⭐
监控告警Prometheus + Grafana⭐⭐⭐⭐

实践原则

1. 测试环境从简
   3 节点即可,快速验证

2. 生产环境 HA
   必须配置高可用,避免单点故障

3. 监控先行
   先配置监控,再上线业务

4. 文档沉淀
   记录配置和故障处理

💡 Hadoop 集群搭建是大数据工程师的基本功,建议动手实践!


👋 感谢阅读!


🔗 系列文章

  • [01-SQL 窗口函数从入门到精通](./01-SQL 窗口函数从入门到精通.md)
  • [02-Spark 性能优化 10 个技巧](./02-Spark 性能优化 10 个技巧.md)
  • 03-数据仓库分层设计指南
  • 04-维度建模实战
  • [05-Flink 实时数仓实战](./05-Flink 实时数仓实战.md)
  • [06-Kafka 消息队列实战指南](./06-Kafka 消息队列实战指南.md)
  • [07-Hive 性能优化实战](./07-Hive 性能优化实战.md)
  • [08-Linux 大数据开发必备工具](./08-Linux 大数据开发必备工具.md)
  • [09-缓慢变化维 SCD Type 2 详解](./09-缓慢变化维 SCD Type2 详解.md)
  • [10-Flink 时间语义与 Watermark 详解](./10-Flink 时间语义与 Watermark 详解.md)
  • 11-Hadoop 集群搭建完整教程(本文)
  • [下一篇:Spark SQL 进阶实践](./12-Spark SQL 进阶实践.md)