从 0 到 1:搭一个最小可用的大数据平台
大数据系列第 12 篇(完结篇):理论聊完了,咱们来动手搭一个能跑起来的最小大数据平台。不用 100 台机器,3 台就够了。
先泼点冷水
网上很多教程教你搭大数据平台,一上来就是:
- 10 台机器的 Hadoop 集群
- 3 个节点的 ZooKeeper 集群
- 5 个 Broker 的 Kafka 集群
- 高可用的 HBase、Hive Metastore、ClickHouse……
兄弟,你确定你需要这么复杂?
对于学习或者小规模业务,最小可用比"完美架构"重要得多。咱们今天搭一个3 台机器就能跑的平台,包含:
- HDFS(存数据)
- YARN(管资源)
- Hive(SQL 查询)
- Spark(计算引擎)
- Kafka(数据传输)
能跑通、能学习、能演示,就够了。生产环境再按需扩展。
架构设计
┌─────────────────────────────────────────────────────────────────┐ │ 最小大数据平台架构(3 节点) │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ Node 1(主节点) │ │ │ │ • NameNode(HDFS 主节点) │ │ │ │ • ResourceManager(YARN 主节点) │ │ │ │ • Hive Metastore(元数据服务) │ │ │ │ • HiveServer2(SQL 查询服务) │ │ │ │ • History Server(Spark 历史记录) │ │ │ │ • Kafka Broker 1 │ │ │ │ • ZooKeeper(单节点,学习用) │ │ │ └─────────────────────────────────────────────────────────┘ │ │ │ │ │ ┌───────────────────────────┼───────────────────────────┐ │ │ │ Node 2 / Node 3(工作节点) │ │ │ │ • DataNode(HDFS 数据节点) │ │ │ │ • NodeManager(YARN 工作节点) │ │ │ │ • Spark Executor │ │ │ │ • Kafka Broker 2 / 3 │ │ │ └───────────────────────────────────────────────────────┘ │ │ │ │ 说明: │ │ • 生产环境 ZooKeeper 至少 3 节点,这里单节点仅为学习 │ │ • 生产环境 NameNode 需要 HA,这里单节点仅为学习 │ │ • 3 台机器的配置建议:8 核 CPU、16GB+ 内存、100GB+ 磁盘 │ │ │ └─────────────────────────────────────────────────────────────────┘环境准备
机器配置
| 节点 | IP | 角色 |
|---|---|---|
| node1 | 192.168.1.101 | 主节点 + 工作节点 |
| node2 | 192.168.1.102 | 工作节点 |
| node3 | 192.168.1.103 | 工作节点 |
基础环境(3 台机器都要做)
# 1. 配置主机名hostnamectl set-hostname node1# node2/node3 同理# 2. 配置 hostscat>>/etc/hosts<<EOF 192.168.1.101 node1 192.168.1.102 node2 192.168.1.103 node3 EOF# 3. 关闭防火墙(学习用,生产环境请配置规则)systemctl stop firewalld systemctl disable firewalld# 4. 配置免密登录(node1 能免密登录所有节点)ssh-keygen-trsa ssh-copy-id node1 ssh-copy-id node2 ssh-copy-id node3# 5. 安装 JDKyuminstall-yjava-1.8.0-openjdk java-1.8.0-openjdk-devel# 6. 配置环境变量cat>>/etc/profile<<EOF export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk export PATH=\$PATH:\$JAVA_HOME/bin EOFsource/etc/profile第一步:安装 Hadoop(HDFS + YARN)
下载解压
# 在 node1 上操作cd/optwgethttps://archive.apache.org/dist/hadoop/common/hadoop-3.3.4/hadoop-3.3.4.tar.gztar-zxvfhadoop-3.3.4.tar.gzln-shadoop-3.3.4 hadoop配置文件
core-site.xml(HDFS 入口地址):
<configuration><property><name>fs.defaultFS</name><value>hdfs://node1:9000</value></property><property><name>hadoop.tmp.dir</name><value>/data/hadoop/tmp</value></property></configuration>hdfs-site.xml(HDFS 配置):
<configuration><property><name>dfs.replication</name><value>2</value><!-- 3 台机器,副本数设为 2 --></property><property><name>dfs.namenode.name.dir</name><value>/data/hadoop/namenode</value></property><property><name>dfs.datanode.data.dir</name><value>/data/hadoop/datanode</value></property></configuration>yarn-site.xml(YARN 配置):
<configuration><property><name>yarn.resourcemanager.hostname</name><value>node1</value></property><property><name>yarn.nodemanager.aux-services</name><value>mapreduce_shuffle</value></property></configuration>workers(DataNode/NodeManager 节点):
node1 node2 node3分发到所有节点
scp-r/opt/hadoop-3.3.4 node2:/opt/scp-r/opt/hadoop-3.3.4 node3:/opt/# 在 node2/node3 上创建软链接ln-s/opt/hadoop-3.3.4 /opt/hadoop格式化并启动
# 格式化 NameNode(只在 node1 执行一次!)hdfs namenode-format# 启动 HDFSstart-dfs.sh# 启动 YARNstart-yarn.sh# 验证hdfs dfsadmin-report第二步:安装 Hive
安装 MySQL(存元数据)
# 在 node1 上yuminstall-ymysql-server systemctl start mysqld# 创建 Hive 数据库和用户mysql-uroot-pCREATE DATABASE hive DEFAULT CHARACTER SET utf8;CREATEUSER'hive'@'%'IDENTIFIED BY'hive_password';GRANT ALL PRIVILEGES ON hive.* TO'hive'@'%';FLUSH PRIVILEGES;下载配置 Hive
cd/optwgethttps://archive.apache.org/dist/hive/hive-3.1.3/apache-hive-3.1.3-bin.tar.gztar-zxvfapache-hive-3.1.3-bin.tar.gzln-sapache-hive-3.1.3-bin hive# 配置 hive-site.xmlcat>/opt/hive/conf/hive-site.xml<<EOF <configuration> <property> <name>javax.jdo.option.ConnectionURL</name> <value>jdbc:mysql://node1:3306/hive?createDatabaseIfNotExist=true</value> </property> <property> <name>javax.jdo.option.ConnectionDriverName</name> <value>com.mysql.cj.jdbc.Driver</value> </property> <property> <name>javax.jdo.option.ConnectionUserName</name> <value>hive</value> </property> <property> <name>javax.jdo.option.ConnectionPassword</name> <value>hive_password</value> </property> <property> <name>hive.metastore.warehouse.dir</name> <value>/user/hive/warehouse</value> </property> <property> <name>hive.execution.engine</name> <value>spark</value> </property> </configuration> EOF# 初始化 Metastore schema/opt/hive/bin/schematool-dbTypemysql-initSchema启动 Hive
# 启动 Metastorenohuphive--servicemetastore>/var/log/hive-metastore.log2>&1&# 启动 HiveServer2(支持 JDBC/Beeline 连接)nohuphive--servicehiveserver2>/var/log/hive-server2.log2>&1&# 测试连接beeline-ujdbc:hive2://node1:10000-e"SHOW DATABASES;"第三步:安装 Spark
下载配置
cd/optwgethttps://archive.apache.org/dist/spark/spark-3.3.2/spark-3.3.2-bin-hadoop3.tgztar-zxvfspark-3.3.2-bin-hadoop3.tgzln-sspark-3.3.2-bin-hadoop3 spark# 配置 spark-env.shcat>>/opt/spark/conf/spark-env.sh<<EOF export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk export HADOOP_CONF_DIR=/opt/hadoop/etc/hadoop export YARN_CONF_DIR=/opt/hadoop/etc/hadoop EOF# 配置 spark-defaults.confcat>>/opt/spark/conf/spark-defaults.conf<<EOF spark.master=yarn spark.submit.deployMode=client spark.yarn.jars=hdfs:///spark-jars/* EOF# 上传 Spark jars 到 HDFShdfs dfs-mkdir/spark-jars hdfs dfs-put/opt/spark/jars/* /spark-jars/测试 Spark on YARN
# 运行示例程序spark-submit\--classorg.apache.spark.examples.SparkPi\--masteryarn\--deploy-mode cluster\/opt/spark/examples/jars/spark-examples_2.12-3.3.2.jar\10# 或者进入 Spark SQLspark-sql--masteryarn第四步:安装 Kafka
下载配置
cd/optwgethttps://archive.apache.org/dist/kafka/3.4.0/kafka_2.13-3.4.0.tgztar-zxvfkafka_2.13-3.4.0.tgzln-skafka_2.13-3.4.0 kafka# 配置 server.properties(3 台机器分别配置)# node1:cat>>/opt/kafka/config/server.properties<<EOF broker.id=1 listeners=PLAINTEXT://node1:9092 log.dirs=/data/kafka-logs zookeeper.connect=node1:2181 EOF# node2:cat>>/opt/kafka/config/server.properties<<EOF broker.id=2 listeners=PLAINTEXT://node2:9092 log.dirs=/data/kafka-logs zookeeper.connect=node1:2181 EOF# node3:cat>>/opt/kafka/config/server.properties<<EOF broker.id=3 listeners=PLAINTEXT://node3:9092 log.dirs=/data/kafka-logs zookeeper.connect=node1:2181 EOF启动 ZooKeeper 和 Kafka
# 在 node1 启动 ZooKeeper/opt/kafka/bin/zookeeper-server-start.sh-daemon/opt/kafka/config/zookeeper.properties# 在 3 台机器分别启动 Kafka/opt/kafka/bin/kafka-server-start.sh-daemon/opt/kafka/config/server.properties# 测试/opt/kafka/bin/kafka-topics.sh--create--topictest--bootstrap-server node1:9092--partitions3--replication-factor2/opt/kafka/bin/kafka-topics.sh--list--bootstrap-server node1:9092第五步:跑通一个完整的数据流程
现在平台搭好了,咱们跑一个完整的数据流程验证一下:
1. 生成测试数据,写入 Kafka
# 创建 Topickafka-topics.sh--create--topicuser_behavior\--bootstrap-server node1:9092\--partitions3--replication-factor2# 用命令行生产几条测试数据echo'{"user_id":"u001","action":"click","item_id":"i100","ts":"2024-01-01 10:00:00"}'|\kafka-console-producer.sh--topicuser_behavior --bootstrap-server node1:9092echo'{"user_id":"u002","action":"purchase","item_id":"i200","ts":"2024-01-01 10:01:00"}'|\kafka-console-producer.sh--topicuser_behavior --bootstrap-server node1:90922. 用 Spark 读取 Kafka,写入 Hive
# kafka_to_hive.pyfrompyspark.sqlimportSparkSessionfrompyspark.sql.functionsimportfrom_json,colfrompyspark.sql.typesimportStructType,StringType spark=SparkSession.builder \.appName("KafkaToHive")\.enableHiveSupport()\.getOrCreate()# 定义 schemaschema=StructType()\.add("user_id",StringType())\.add("action",StringType())\.add("item_id",StringType())\.add("ts",StringType())# 读取 Kafkadf=spark.readStream \.format("kafka")\.option("kafka.bootstrap.servers","node1:9092,node2:9092,node3:9092")\.option("subscribe","user_behavior")\.option("startingOffsets","earliest")\.load()# 解析 JSONparsed=df.select(from_json(col("value").cast("string"),schema).alias("data")).select("data.*")# 写入 Hive(实际生产用 Structured Streaming 的 append 模式)# 这里简化为批处理示例parsed.write \.mode("append")\.saveAsTable("default.user_behavior")print("数据已写入 Hive!")# 提交 Spark 作业spark-submit--masteryarn--deploy-mode cluster kafka_to_hive.py3. 用 Hive 查询数据
beeline-ujdbc:hive2://node1:10000-e" SELECT action, COUNT(*) as cnt FROM user_behavior GROUP BY action; "4. 用 HDFS 查看存储的数据
hdfs dfs-ls/user/hive/warehouse/user_behavior/ hdfs dfs-cat/user/hive/warehouse/user_behavior/part-*踩坑指南
坑 1:内存不够
Hadoop + Spark + Hive + Kafka 同时跑,内存消耗很大。如果机器只有 8GB 内存,很可能会 OOM。
解决方案:
# 减少 YARN 容器内存# yarn-site.xml<property><name>yarn.nodemanager.resource.memory-mb</name><value>4096</value><!-- 根据实际内存调整 --></property># 减少 Spark Executor 内存# spark-defaults.confspark.executor.memory=1gspark.driver.memory=1g坑 2:端口冲突
Hive Metastore(9083)、HiveServer2(10000)、Kafka(9092)、ZooKeeper(2181)……端口冲突是常见问题。
解决方案:
# 检查端口占用netstat-tlnp|grep9083# 修改配置文件中的端口坑 3:权限问题
HDFS 上的文件权限、Hive 表的权限,经常导致"Permission Denied"。
解决方案:
# HDFS 上创建目录时指定权限hdfs dfs-mkdir-p/user/hive/warehouse hdfs dfs-chmod777/user/hive/warehouse# 学习用,生产环境不要 777# 或者以 HDFS 超级用户执行exportHADOOP_USER_NAME=hdfs坑 4:Hive 和 Spark 版本兼容
Hive 3.x 和 Spark 3.x 可能有兼容性问题。
解决方案:
- 使用官方推荐的版本组合
- 或者直接用 Spark SQL 替代 Hive(不依赖 Hive 执行引擎)
生产环境扩展建议
这个 3 节点平台是学习用的,生产环境需要:
| 组件 | 学习环境 | 生产环境建议 |
|---|---|---|
| NameNode | 单节点 | HA(2 节点 + JournalNode) |
| ResourceManager | 单节点 | HA(2 节点) |
| ZooKeeper | 单节点 | 3 节点或 5 节点 |
| Kafka Broker | 3 节点 | 5+ 节点 |
| Hive Metastore | 单节点 | 高可用部署 |
| 数据备份 | 2 副本 | 3 副本 |
| 监控 | 无 | Prometheus + Grafana |
系列总结
到这里,咱们的大数据框架系列就完结了。回顾一下这 12 篇的内容:
| 篇目 | 主题 | 核心收获 |
|---|---|---|
| 1 | 大数据技术体系综述 | 5V 特征、CAP/BASE、Lambda vs Kappa |
| 2 | HDFS | 分布式文件存储、副本机制、NameNode 高可用 |
| 3 | MapReduce | 分而治之、Shuffle 机制、为什么衰落 |
| 4 | Spark | 内存计算、RDD、DAG 调度、生态组件 |
| 5 | Flink | 流批一体、Event Time、Checkpoint、Exactly-Once |
| 6 | YARN | 资源调度、三种调度器、Container 隔离 |
| 7 | Hive | SQL on Hadoop、分区/分桶、存储格式优化 |
| 8 | HBase | 列式数据库、LSM-Tree、RowKey 设计 |
| 9 | Kafka | 消息队列、Partition、Consumer Group、高吞吐 |
| 10 | ClickHouse | 列式存储、向量化执行、MergeTree、OLAP |
| 11 | 框架选型 | 数据分层、典型场景、选型误区 |
| 12 | 搭建平台 | 3 节点最小平台、完整数据流程、踩坑指南 |
大数据技术的核心就一句话:一台机器搞不定,那就多台机器一起搞。但多台机器协同工作,就会引出数据切分、任务调度、故障恢复、一致性保证等一系列问题。这些框架就是解决这些问题的工程实践。
学习建议:
- 先理解每个框架解决什么问题、为什么这样设计
- 动手搭一个最小环境,跑通完整数据流程
- 结合实际业务场景,思考如何选型、如何优化
- 关注社区动态,了解技术演进趋势(如云原生、湖仓一体)
这个系列对你有帮助吗?有没有想深入了解的话题?或者你在实际项目中遇到了什么问题?欢迎在评论区交流,咱们一起探讨~
大数据之路,道阻且长,行则将至。