news 2026/9/26 20:35:00

openEuler 24.03上搭建Hadoop+Spark+Kafka+Hive等大数据集群实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
openEuler 24.03上搭建Hadoop+Spark+Kafka+Hive等大数据集群实战

写这篇东西的起因很简单:周末在家整理自己的服务器笔记,发现这套“Zookeeper+Hadoop+Spark+Kafka+Hive+Flume+MySQL分布式集群”在 openEuler 24.03 LTS SP2 上的搭建过程,散落在十几个文档里。正好最近不少朋友在问“能不能用国产开源系统搭一套大数据环境”,干脆整理成一篇能直接抄作业的版本。先说清楚,这篇是粗略版,不是生产级调优指南,更不是从零讲原理的教材。它的定位是:让你在 openEuler 24.03 LTS SP2 上,用最少的时间把一整套大数据组件跑起来,理解它们之间的依赖关系,为后续深入学习或课程设计铺路。我用的节点不算多,但结构完整——有协调服务、分布式存储、计算引擎、消息队列、日志采集、元数据库和数仓,覆盖了主流大数据项目的常见架构形态。


1. 整体设计与方案选型

1.1 这套组件组合到底在解决什么问题

很多零基础的朋友第一次接触这套名词,第一反应是“这七个东西为什么要放在一起”。我用一句话解释:ZooKeeper 是协调员,Hadoop 负责存和算,Spark 负责快算,Kafka 负责传数据,Flume 负责收数据,MySQL 负责记元数据,Hive 负责把 SQL 翻译成计算任务。它们不是平级关系,而是一条流水线。

我见过不少初学者在搭集群时只顾着“装”,装完却不知道为什么要装。以 Kafka 为例,它依赖 ZooKeeper 做 broker 选举和元数据管理;Hive 则依赖 MySQL 存储表结构、分区信息这些元数据;Spark 如果跑在 YARN 上,又依赖 Hadoop 的资源调度。所以搭建顺序很重要:系统准备 -> ZooKeeper -> Hadoop -> Spark -> Kafka -> Flume -> MySQL -> Hive。这个顺序本质上就是依赖顺序的倒推。

1.2 节点规划与版本选型

我推荐的最小规模是 3 节点,既能体现“分布式集群”的真实性,又不会让普通电脑扛不住。如果你的机器配置有限,也可以压缩到 2 节点甚至单节点,但 ZooKeeper 至少要有 3 个实例(否则没有选举意义),所以单机方案其实更适合伪分布式。我的规划如下:

节点角色主要组件
node01MasterZooKeeper + NameNode + ResourceManager + Spark Master + Hive + MySQL
node02Worker1ZooKeeper + DataNode + NodeManager + Kafka + Flume
node03Worker2ZooKeeper + DataNode + NodeManager + Kafka

每个节点 4 核 CPU、8GB 内存、100GB 磁盘,跑这套是够的。内存再小的话,Kafka 和 Spark 同时启动容易 OOM。注意 node01 上同时跑 NameNode、ResourceManager 和 MySQL 会很吃内存,建议给它 16GB,或者把 MySQL 挪到 node02。

版本选型我踩过不少坑。openEuler 24.03 LTS SP2 的 GLIBC 版本较新,太老的大数据组件容易出现兼容问题。我最终用的组合是:JDK 8(注意是 x86_64 架构)、Hadoop 3.3.6、ZooKeeper 3.8.4、Spark 3.5.1(for hadoop3)、Kafka 3.6.0、Flume 1.11.0、Hive 3.1.3、MySQL 8.0。这套组合最稳的地方在于:Spark 3.5.1 和 Hive 3.1.3 的兼容性有官方保证,Kafka 3.6.0 也不依赖 ZooKeeper 太老的特征,整体通讯协议能对上。

注意:openEuler 上有自带的 openjdk,但版本可能是 11 或 17。大数据组件对 JDK 8 的兼容性是最好的,尤其是老版本 Hive,用高版本 JDK 会报UnsupportedClassVersionError。我建议统一装 Oracle JDK 8 或 downloads 里的 Temurin 8。

2. 基础环境准备

2.1 网络配置与主机名映射

openEuler 的网络管理工具是 NetworkManager,装好系统后最烦的问题就是 IP 会变。我建议立即改成静态 IP,并维护好/etc/hosts。

# 用 nmcli 配置静态 IP,示例为 node01 的 ens160 nmcli con mod ens160 ipv4.addresses 192.168.10.11/24 nmcli con mod ens160 ipv4.gateway 192.168.10.1 nmcli con mod ens160 ipv4.dns 192.168.10.1 nmcli con mod ens160 ipv4.method manual nmcli con up ens160

三台节点的/etc/hosts都加上同样的映射,后面所有组件配置里写主机名不写 IP,这是集群环境的通用习惯:

192.168.10.11 node01 192.168.10.12 node02 192.168.10.13 node03

我在第一次搭的时候偷懒,在 Hadoop 配置里写死 IP,结果后期加节点或者迁移环境,所有配置文件都要改一遍。直接把主机名映射做好,后面省心很多。另外建议把三台机器的 hostname 分别设置成 node01、node02、node03,用hostnamectl set-hostname node01设置。

2.2 JDK、免密登录与基础工具

JDK 安装没有太多技巧,解压后配置环境变量就行。我习惯把软件统一放到/opt/bigdata目录下,方便管理和备份。

mkdir -p /opt/bigdata tar -zxf jdk8u401-linux-x64.tar.gz -C /opt/bigdata/

然后在/etc/profile.d/bigdata.sh里写环境变量:

export JAVA_HOME=/opt/bigdata/jdk1.8.0_401 export PATH=$JAVA_HOME/bin:$PATH

这个bigdata.sh文件是我自己比较喜欢的做法,一段脚本统一管理所有组件的环境变量,比挨个改/etc/profile清晰得多。

集群之间需要免密登录。三台机器上都生成密钥,然后把公钥导入其他机器的authorized_keys:

ssh-keygen -t rsa -P "" -f ~/.ssh/id_rsa ssh-copy-id node01 ssh-copy-id node02 ssh-copy-id node03

注意一点,hadoop用户和root用户的免密要分开配。我全程用 root 跑实验没问题,但很多人会单独建hadoop用户来运行服务。不管用哪个用户,该用户的免密都要配好,否则后面脚本分发和start-dfs.sh会卡在输密码上。

2.3 系统参数与防火墙处理

大数据组件端口多,一个个放行太麻烦。单机实验环境下我直接关闭防火墙,但生产环境不建议这么干。

systemctl disable --now firewalld setenforce 0 sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config

另外,每个节点都加一行文件句柄和进程数限制,在/etc/security/limits.conf里追加:

* soft nofile 65536 * hard nofile 65536 * soft nproc 65536 * hard nproc 65536

很多奇怪的问题,比如 HDFS 报 “Too many open files”、Kafka 报句柄不够,都是这里没配。改完后重启系统或者重新登录一次。

3. ZooKeeper 集群部署

3.1 安装包准备与目录规划

ZooKeeper 是整条链路的基石,但它的安装反而是最简单的。下载二进制包后解压到/opt/bigdata,我习惯在组件目录里建立一个data软链接指向专门的存储盘,避免日志和临时数据写在系统盘里挤爆根分区。

tar -zxf apache-zookeeper-3.8.4-bin.tar.gz -C /opt/bigdata/ ln -s /data/zookeeper /opt/bigdata/apache-zookeeper-3.8.4/data mkdir -p /data/zookeeper

3.2 zoo.cfg 与 myid 配置细节

ZooKeeper 的配置文件在conf/zoo.cfg,需要手动创建(模板中的zoo_sample.cfg不算数)。我的三节点配置如下:

tickTime=2000 initLimit=10 syncLimit=5 dataDir=/data/zookeeper clientPort=2181 server.1=node01:2888:3888 server.2=node02:2888:3888 server.3=node03:2888:3888

重点解释下2888和3888:前者是 leader 和 follower 之间同步数据用的端口,后者是集群选举时投票用的端口。initLimit=10表示 follower 在启动后 10 个 tick 时间内必须连上 leader,syncLimit=5表示 follower 与 leader 心跳最大间隔。集群规模越大,这两个值要适当调大,否则启动时容易报连接超时。

每台机器还需要在dataDir目录下创建myid文件,文件内容就是自己的编号。比如 node01 执行:

echo 1 > /data/zookeeper/myid

这三个编号不能重复,必须和zoo.cfg里的server.x对应。很多第一次搭集群的人忘记建myid,启动日志会报Invalid myid或者直接失败,这是高频错误。

3.3 启动与健康检查

三台节点分别启动:

/opt/bigdata/apache-zookeeper-3.8.4/bin/zkServer.sh start

启动后用jps看是否出现QuorumPeerMain进程,再用四字命令检查状态:

echo srvr | nc node01 2181 echo mntr | nc node01 2181

mntr输出里的zk_server_state会显示当前角色。三台节点里有一台是leader,其余是follower,这是正常的。如果全部是standalone状态,说明集群模式没生效,多半是myid写错或者端口被防火墙挡了。

4. Hadoop 集群部署

4.1 HDFS 与 YARN 核心配置详解

Hadoop 的配置目录是etc/hadoop/,核心文件就四个:core-site.xml、hdfs-site.xml、yarn-site.xml、mapred-site.xml。配置项多,但真正影响集群行为的其实是几个关键参数。

core-site.xml指定 NameNode 地址和临时目录:

<configuration> <property> <name>fs.defaultFS</name> <value>hdfs://node01:9820</value> </property> <property> <name>hadoop.tmp.dir</name> <value>/data/hadoop/tmp</value> </property> </configuration>

注意端口是9820。如果你在网上看到 9000/8020,那是旧版本 Hadoop 的默认端口,3.x 默认改成了 9820,照着老教程配会连不上。

hdfs-site.xml设置副本数和 NameNode 元数据目录:

<configuration> <property> <name>dfs.replication</name> <value>2</value> </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>

副本数建议设置为2。三台节点,副本数为 3 的话,数据会存满三台,读取效率高但占用空间大;试验环境设置 2 更经济。但注意dfs.replication如果设置为 1,万一某个 DataNode 挂掉,数据就真丢了,自己权衡。

yarn-site.xml是资源调度的核心:

<configuration> <property> <name>yarn.nodemanager.aux-services</name> <value>mapreduce_shuffle</value> </property> <property> <name>yarn.resourcemanager.hostname</name> <value>node01</value> </property> <property> <name>yarn.nodemanager.resource.memory-mb</name> <value>6144</value> </property> <property> <name>yarn.scheduler.maximum-allocation-mb</name> <value>6144</value> </property> </property> </configuration>

yarn.nodemanager.resource.memory-mb决定每个 NodeManager 能分配多少内存给容器。它必须小于物理内存,建议设置为物理内存的 80% 左右。我在 8G 机器上设了 6144,剩下留给系统和服务端。

mapred-site.xml只需要指定 MapReduce 跑在 YARN 上:

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

4.2workers文件与数据目录权限

这一步经常被忽略。Hadoop 3.x 里etc/hadoop/workers文件(旧版本叫 slaves)决定哪些机器是 DataNode:

node02 node03

第一行不能有空格,不要写 node01,因为 NameNode 节点通常不再额外当 DataNode(当然你也可以让它当,但试验环境没必要让主节点承担太多存储任务)。

所有需要存储数据的目录要先创建好:

mkdir -p /data/hadoop/tmp mkdir -p /data/hadoop/namenode mkdir -p /data/hadoop/datanode

然后要么把/data/hadoop属主改成运行 Hadoop 的用户,要么直接 chmod 777(实验环境图省事)。Permission denied是我见过最多的问题,hadoop 进程想写数据目录但没有权限,启动日志里报错却不明显。

4.3 NameNode 格式化与集群首次启动

第一次启动前必须格式化 NameNode,这个操作会初始化元数据目录。只在 node01 上执行一次,以后永远不要重复执行:

hdfs namenode -format

格式化成功会有successfully formatted的提示。如果第二次不小心又执行了格式化,会导致 NameNode 的 clusterID 变化,DataNode 全部连不上,报Incompatible clusterIDs错误。此时最粗暴的解决办法是:清掉所有节点的 namenode/datanode 目录,重新格式化。

首次启动:

start-dfs.sh start-yarn.sh

分别在 node01 上有进程NameNode、SecondaryNameNode、ResourceManager,node02 和 node03 上有DataNode、NodeManager。用jps确认后用浏览器访问http://node01:9870看 HDFS 页面,http://node01:8088看 YARN 页面。如果节点列表里 DataNode 没出现,先翻日志,不要急着重启。

5. Spark 集群部署

5.1 部署模式选择:YARN 还是 Standalone

Spark 本身有独立的集群模式(Standalone),但在已经有 YARN 的情况下,我更推荐 Spark on YARN。原因很简单:资源统一由 YARN 调度,不需要再单独管理一套 Spark Master/Worker,能少维护几个进程。而且 Spark 官方对 on YARN 模式支持得很好,提交作业时只需要指定--master yarn就行。

有人会觉得 Standalone 模式简单,但从集群资源利用角度考虑,两套调度器各管各的容易浪费资源。既然 Hadoop 都搭了,顺手用 YARN 就好。

5.2 spark-env.sh 关键参数配置

Spark 解压后,最重要的配置是conf/spark-env.sh。从模板复制一个出来改:

cp conf/spark-env.sh.template conf/spark-env.sh

关键参数如下:

export JAVA_HOME=/opt/bigdata/jdk1.8.0_401 export HADOOP_HOME=/opt/bigdata/hadoop-3.3.6 export HADOOP_CONF_DIR=$HADOOP_HOME/etc/hadoop export SPARK_HOME=/opt/bigdata/spark-3.5.1-bin-hadoop3 export SPARK_DIST_CLASSPATH=$(hadoop classpath)

SPARK_DIST_CLASSPATH这行是最容易漏的。如果你不设置它,Spark 启动时会报找不到hadoop相关类,尤其在我们这种“Hadoop 装在和 Spark 不同目录”的情况下。设置它其实就是把 Hadoop 的 classpath 传给 Spark 进程。

conf/spark-defaults.conf我也建议提前配一个 spark UI 端口:

spark.master yarn spark.eventLog.enabled true spark.eventLog.dir hdfs://node01:9820/spark-logs spark.history.fs.logDirectory hdfs://node01:9820/spark-logs

5.3 提交测试任务验证集群

Spark 不需要像 Hadoop 那样显式“启动集群”。它作为一个客户端提交任务到 YARN。先创建 HDFS 上日志目录:

hdfs dfs -mkdir -p /spark-logs # 确保 spark-logs 目录权限可写 hdfs dfs -chmod -R 777 /spark-logs

然后在 node01 上提交自带示例验证:

/opt/bigdata/spark-3.5.1-bin-hadoop3/bin/spark-submit \ --class org.apache.spark.examples.SparkPi \ --master yarn \ --deploy-mode client \ --driver-memory 1g \ --executor-memory 1g \ --executor-cores 1 \ /opt/bigdata/spark-3.5.1-bin-hadoop3/examples/jars/spark-examples_2.12-3.5.1.jar 10

看到输出Pi is roughly 3.14159...就说明 Spark on YARN 跑通了。在 YARN 的 UI 页面(8088 端口)里会看到一个SparkPi的 application,过一会儿状态变成 SUCCEEDED。

6. Kafka 集群部署

6.1 server.properties 核心参数解读

Kafka 3.6.0 依然依赖 ZooKeeper 做协调,安装包自带了一个旧版 ZooKeeper,但我们要用自己配置的集群实例,所以不用它内置的。

Kafka 的配置在config/server.properties,每台机器只需要改几个关键项:

broker.id=1 listeners=PLAINTEXT://node01:9092 log.dirs=/data/kafka/logs zookeeper.connect=node01:2181,node02:2181,node03:2181 num.partitions=3 default.replication.factor=2 offsets.topic.replication.factor=2

broker.id每台必须不同,node01 是 1,node02 是 2,node03 是 3。listeners里的地址一定要写当前节点的主机名,如果写localhost会导致别的机器连不上。log.dirs是 Kafka 数据目录,需要提前建好并保证权限。

default.replication.factor和offsets.topic.replication.factor建议设置为 2。前者是 topic 默认副本数,后者是 Kafka 内部存的 offset 提交数据的副本数。设置太小,Kafka 内部元数据 topic 在节点故障时会丢消息,设置太大又过于浪费。

6.2 启动 Kafka 并验证生产消费

启动 Kafka 前先在 node01 上确认 ZooKeeper 的/brokers目录能被访问:

/opt/bigdata/apache-zookeeper-3.8.4/bin/zkCli.sh -server node01:2181 ls /brokers

如果报错,说明 ZooKeeper 的端口没通,先排查 ZooKeeper。

Kafka 的启动命令:

/opt/bigdata/kafka_2.13-3.6.0/bin/kafka-server-start.sh -daemon config/server.properties

启动后,创建 topic 并验证:

/opt/bigdata/kafka_2.13-3.6.0/bin/kafka-topics.sh \ --bootstrap-server node01:9092,node02:9092,node03:9092 \ --create --topic test --partitions 3 --replication-factor 2

用生产者和消费者命令实测一遍。开一个终端跑消费者,另一个终端跑生产者,输入几条消息,消费者能收到就说明整个链路没问题。如果消费者挂在join group状态不动,多半是advertised.listeners没配好,客户端找到了 broker 但来回通信的地址有问题。

6.3 可视化管理工具与监控思路

Kafka 的命令行工具能完成日常操作,但要看 broker 和 topic 的详细信息,我还是喜欢用可视化工具。我常用 Kafka 自带的 Kafka UI 或者开源的 Kafka Eagle(CFAK)。演示环境跑一个 Kafka UI 很轻量,它能显示每个 topic 的分区情况、消费者组的 lag、broker 状态。

Kafka Eagle 的话注意版本和 JDK 的配合,它需要配置数据库来存监控数据。个人建议先从 Kafka UI 上手,功能直观。监控重点看两个指标:消费者组的lag和 broker 的active connections。lag 是消费者处理的积压量,lag持续增长就意味着消费速度跟不上生产速度,这时候要增加消费者或者优化处理逻辑。

7. Flume 日志采集接入

7.1 Agent 架构与场景设计

Flume 的定位是日志采集和传输。它由一个 Agent 组成,Agent 内部有三部分:Source 接收数据,Channel 做缓冲,Sink 把数据发出去。常见的玩法是:Flume 监控一个文件或目录,把新增的行发送到 Kafka topic,Kafka 再交给后面的消费者去处理。

我们这套集群里,Flume 就是一个“送水工”,把数据从前端系统搬到 Kafka。这个模式也是网约车项目、交通分析系统里最常见的数据入口设计。

7.2 采集到 Kafka 的配置示例

在 node02 上配置 Flume,改conf/flume-conf.properties:

agent.sources = tailSource agent.channels = memChannel agent.sinks = kafkaSink agent.sources.tailSource.type = spooldir agent.sources.tailSource.spoolDir = /data/logs/spool agent.sources.tailSource.fileHeader = true agent.channels.memChannel.type = memory agent.channels.memChannel.capacity = 10000 agent.channels.memChannel.transactionCapacity = 1000 agent.sinks.kafkaSink.type = org.apache.flume.sink.kafka.KafkaSink agent.sinks.kafkaSink.kafka.bootstrap.servers = node01:9092,node02:9092,node03:9092 agent.sinks.kafkaSink.kafka.topic = flume-topic agent.sinks.kafkaSink.kafka.producer.acks = 1 agent.sources.tailSource.channels = memChannel agent.sinks.kafkaSink.channel = memChannel

这里 Source 我用了spooldir,它监控/data/logs/spool目录下的文件,一旦有新文件就会读取并发送。相比tail类型(类似tail -F),spooldir更稳定,不会因为文件被轮转而丢失数据。先提前建好目录放入一个测试文件。

7.3 启动与数据流验证

启动 Flume:

/opt/bigdata/flume-1.11.0/bin/flume-ng agent \ --name agent \ --conf conf \ --conf-file conf/flume-conf.properties \ -Dflume.root.logger=INFO,console

注意--name必须和配置文件里agent前缀一致。然后在/data/logs/spool里写一个新文件,比如:

echo "hello flume to kafka" > /data/logs/spool/test.log

再到 Kafka 终端里消费flume-topic,能看到这条消息,说明 Flume -> Kafka 链路通上了。如果看不到,第一反应是看 Flume 日志有没有报错,第二反应是确认 Kafka 的 topic 是否提前创建好了——KafkaSink 默认不会自动创建 topic,即使 auto.create 开启,也可能因为权限配置失败。

8. MySQL 元数据库准备

8.1 openEuler 下安装 MySQL

openEuler 的默认源里没有 MySQL,只有 MariaDB。Hive 官方文档支持 MySQL 和 MariaDB 作为 metastore,但标题既然写了 MySQL,我就按 MySQL 社区版来说,顺便解释两者的差异:MariaDB 是 MySQL 的分支,JDBC 驱动基本通用,Hive 的metastore配置只要改一下驱动类就行。

我采用的方案是下载 MySQL 8.0 社区版 RPM 包,用rpm -ivh安装:

# 先安装 MySQL 官方仓库 rpm -ivh mysql80-community-release-el8-7.noarch.rpm dnf install mysql-community-server

需要注意 openEuler 基于 RHEL 兼容层,安装 el8 的包一般没问题。装完后初始化:

systemctl start mysqld grep 'temporary password' /var/log/mysqld.log

MySQL 8.0 首次启动会在日志里打印一个临时 root 密码,用这个密码登录后必须立刻修改。

8.2 用户授权与连接测试

Hive 需要一个专门的数据库用户,用于读写元数据库。我在 MySQL 里执行:

CREATE DATABASE hive CHARACTER SET utf8mb4; CREATE USER 'hive'@'%' IDENTIFIED BY 'Hive123!@#'; GRANT ALL PRIVILEGES ON hive.* TO 'hive'@'%'; FLUSH PRIVILEGES;

%表示允许任何主机连接,这在集群环境里是必须的,因为 Hive 客户端可能从任意节点访问 metastore。但也意味着安全问题更大,实验环境尚可,生产环境建议只开放 node01 的地址。

测试连接:

mysql -h node01 -u hive -p'Hive123!@#' -e 'select 1;'

能输出1就说明连接正常。然后下载 MySQL JDBC 驱动mysql-connector-j-8.0.33.jar,放到 Hive 的lib目录下。这一步跳过的话,后面初始化 metastore 时会报ClassNotFoundException: com.mysql.cj.jdbc.Driver,非常经典。

9. Hive 数据仓库搭建

9.1 Metastore 指向 MySQL

Hive 的核心配置文件是conf/hive-site.xml,默认不存在,需要自己创建。关键内容是让 metastore 连接 MySQL:

<configuration> <property> <name>javax.jdo.option.ConnectionURL</name> <value>jdbc:mysql://node01:3306/hive?useSSL=false&amp;serverTimezone=Asia/Shanghai</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>Hive123!@#</value> </property> <property> <name>hive.metastore.uris</name> <value>thrift://node01:9083</value> </property> </configuration>

hive.metastore.uris这行很重要。如果不配置,Hive 会默认启动一个内嵌的 metastore 服务,客户端直接连接数据库;但集群环境里多个 Hive 客户端连接同一个数据库会容易出现版本冲突或锁问题。单独启动 metastore 进程,客户端统一连接这个服务,是更规范的做法。

9.2 执行引擎选择

Hive 3.1.3 支持 MapReduce 和 Spark 两种执行引擎,默认是 MapReduce。如果直接跑复杂查询,MapReduce 的响应时间慢得让人抓狂。我建议在hive-site.xml里增加:

<property> <name>hive.execution.engine</name> <value>spark</value> </property> <property> <name>spark.master</name> <value>yarn</value> </property> <property> <name>spark.home</name> <value>/opt/bigdata/spark-3.5.1-bin-hadoop3</value> </property> <property> <name>hive.spark.client.server.connect.timeout</name> <value>60000</value> </property>

用 Spark 引擎时,Hive 会在提交任务后去 YARN 上申请 Spark Application。如果连接超时,可以调大hive.spark.client.server.connect.timeout,我踩过这个坑,默认 20 秒在小机器上经常不够用。

9.3 初始化与验证

第一次使用前需要初始化 metastore schema:

/opt/bigdata/hive-3.1.3/bin/schematool -initSchema -dbType mysql

看到Initialization script completed就说明表创建成功。然后在 node01 上启动 metastore 服务:

nohup /opt/bigdata/hive-3.1.3/bin/hive --service metastore > /var/log/hive-metastore.log 2>&1 &

再启动 hiveserver2(供 beeline 连接用):

nohup /opt/bigdata/hive-3.1.3/bin/hive --service hiveserver2 > /var/log/hiveserver2.log 2>&1 &

接着用 beeline 连上去建表测试:

/opt/bigdata/hive-3.1.3/bin/beeline -u jdbc:hive2://node01:10000 CREATE TABLE test_table (id INT, name STRING); INSERT INTO test_table VALUES (1, 'hello'); SELECT * FROM test_table;

如果建表成功了,MySQL 的hive库下会多出几十张表,其中TBLS表里能看到test_table。用 Hive 查数最终是把 SQL 翻译成 Spark 或 MapReduce 任务,去 YARN 页面也能看到对应的 application。

10. 集群启动顺序与全链路联调

10.1 启动顺序与关闭顺序

这套集群组件多,相互依赖,启动顺序错了就会出现各种诡异问题。我按依赖关系整理了一个顺序:

  1. 启动 ZooKeeper(三台)
  2. 启动 HDFS(start-dfs.sh)
  3. 启动 YARN(start-yarn.sh)
  4. 启动 Kafka(三台)
  5. 启动 Flume(node02)
  6. 启动 Hive metastore 和 hiveserver2(node01)
  7. Spark 不需要单独启动,由 YARN 拉起

关闭顺序基本反过来:先关 Hive、Flume、Kafka,再关 YARN、HDFS,最后关 ZooKeeper。你可能会问为什么 Spark 不在这份清单里,因为 Spark on YARN 模式没有常驻服务进程,它就是客户端一提交任务就走。

这个顺序的核心原则是“先启动其他组件依赖的服务”。Kafka 依赖 ZooKeeper,Hive 依赖 MySQL 和 Spark/Hadoop,Flume 依赖 Kafka。搞乱了顺序,轻则报连接超时,重则卡在启动阶段等不到心跳。

10.2 全链路数据流转验证

所有组件都起来了,我做一次全链路验证来确认它们真的在协作。思路是:Flume 采集日志 -> Kafka 存储 -> Spark 做消费 -> Hive 查结果。简化版的验证路径是先用 Flume 写入 Kafka 一个事件,再用 Kafka 命令行验证,然后做一次 Hive 查询确认写读链路通。

步骤操作预期结果
1向 Flume spooldir 写入文件Flume 日志显示 Event 被发送
2Kafka 消费对应 topic能读到日志内容
3Hive 建外部表指向某个 HDFS 目录表结构创建成功
4用LOAD DATA INPATH导入测试文件SELECT 能看到数据

这种全链路验证的价值在于:它能一次性把前面零散安装的组件串起来,发现问题时你知道该查哪一段——Flume 没发出去查 Flume 日志,Kafka 没有数据查 Kafka topic 和 broker,HDFS 目录打不开查权限。链路式排查比单点排查高效得多。

11. 常见问题与排查技巧实录

11.1 权限、目录与依赖类问题

Permission denied(HDFS 或本地目录)HDFS 的/tmp目录默认只能由创建者写入。如果 Spark 或 Hive 提交任务时报权限错误,先执行hdfs dfs -chmod -R 777 /tmp再试。本地目录的权限问题,通常是忘记chown或chmod,看日志里报错路径然后直接修正属主即可。

NameNode 启动失败大概率是dfs.namenode.name.dir指向的目录不存在或属主不对。注意格式化操作会静默失败,不要只看提示。格式化前要保证目录存在且为空。最稳妥的排查方式:先hdfs namenode -format,再看日志确认Storage directory ... successfully formatted。

类找不到(ClassNotFoundException)所有大数据集群的类加载问题,95% 是缺 jar 包或者版本不匹配。比如 Hive 连 MySQL 报 SQL 驱动找不到,就是没把 JDBC jar 放到lib目录。比如 Spark 找不到 Hadoop 类,就是没设SPARK_DIST_CLASSPATH。这种问题只能一个个补齐,没有捷径。

11.2 内存与 JVM 参数问题

Metaspace 或 heap OOMHive metastore 默认的堆内存很小,如果元数据库数据量大,容易 OOM。在/opt/bigdata/hive-3.1.3/conf/hive-env.sh里设置:

export HADOOP_HEAPSIZE=2048

Spark executor 内存不足YARN 上每个容器有内存上限。如果你提交 Spark 任务时报Container killed by YARN for exceeding memory limits,要么给容器分配更多内存(改yarn-site.xml的yarn.scheduler.maximum-allocation-mb),要么减少 executor 的内存占用(--executor-memory)。我一般是先看 YARN 页面上的 “Diagnostics”,它会直接告诉你容器实际用了多少内存,按那个数来调,而不是盲猜。

Kafka 消息延迟高常见原因是消费者数量少于分区数,或者单个消费者处理逻辑太重。一个分区同时只能被一个消费者组内的一个消费者消费,所以分区数为 3 时,消费者数最多只有 3 能并行。如果确认消费端没瓶颈,就检查 broker 的num.network.threads和num.io.threads,默认值在小流量下够用,但并发上来后要适当加大。另外 Kafka 的log.retention.hours和log.segment.bytes也会影响磁盘 I/O 模式,延迟高时先看磁盘的 IO 和 GC 日志,再调参数。


这套集群搭完之后,我自己最大的体会是:“能在 openEuler 上把这一整套跑通的人,再看任何单组件的教程都会觉得特别轻松”。因为分布式系统最难点不在某个组件本身,而是组件之间端口、目录、用户、权限这些繁琐的配合细节。配置里没有一处是“玄学”,每一个参数都是为某个具体问题服务的。如果照这篇搭的过程中遇到问题,建议先按链路从头到尾捋一遍——ZooKeeper 是否健康、HDFS 数据节点是否在线、Kafka topic 是否创建、MySQL 连接是否正常、jar 包有没有放对位置。排查顺序对了,问题基本都能定位到某一层。

最后再分享一个实操中特别省事的小技巧:把全链路启动命令写成一个 shell 脚本,放到/usr/local/bin/start-all.sh,每次实验直接跑脚本。脚本里每启动一个组件就sleep 5等它初始化,避免服务还没就绪下一个就去连。这个习惯能帮你省掉无数“启动顺序不对导致莫名其妙报错”的时间。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/26 20:34:49

双端影视APP无加密修复版源码:从框架选型到打包避坑实践

简介&#xff1a;这是一套面向影视APP开发者和运营站长的双端影视源码修复版&#xff0c;支持一键生成安卓与苹果客户端&#xff0c;UI界面美观&#xff0c;并已对接苹果CMS&#xff0c;只需开放API接口即可调用数据。包体共673个文件&#xff0c;压缩后约36.91MB&#xff0c;其…

作者头像 李华
网站建设 2026/9/26 20:34:25

园区无线网络规划与自动化交付:从链路预算到华为AC配置

简介&#xff1a;面向园区网络与无线覆盖设计场景&#xff0c;这份资料基于华为eNSP模拟器&#xff0c;给出一个完整园区无线网络的规划与构建方案&#xff0c;包含项目源码、拓扑、设计文档、平面图及布线图&#xff0c;适合网络工程、通信、电子信息等专业学生用于毕设、课设…

作者头像 李华
网站建设 2026/9/26 20:33:53

SecureCRT深色护眼配色方案:日志一眼分清级别,附可抄RGB值

刚入行那会儿&#xff0c;我盯着一整天白底黑字的SecureCRT&#xff0c;晚上回家眼睛酸得几乎睁不开。后来把配色换成深色护眼方案&#xff0c;才发现这是终端使用里性价比最高的一次优化。今天分享的这套SecureCRT配色方案&#xff0c;我已经在生产环境用了两三年&#xff0c;…

作者头像 李华
网站建设 2026/9/26 20:33:32

H5扫码实战:jsQR与html5-qrcode选型与避坑指南

简介&#xff1a;面向H5页面与uni-app开发者的扫码功能实现包&#xff0c;整合jsQR与html5-qrcode两种解码方案&#xff0c;帮助前端工程师在浏览器中快速完成摄像头扫码、图片识别与跨端集成。压缩包共43个文件&#xff0c;以JavaScript脚本、TypeScript类型定义、Vue页面组件…

作者头像 李华
网站建设 2026/9/26 20:33:17

通达信妙在三红主图指标:底部区域三红共振源码详解

1. 先拆设计&#xff1a;这个“三红”到底在表达什么逻辑做技术分析这么多年&#xff0c;“底部区域怎么找”一直是散户问得最多的问题。趋势没走完就急着抄底&#xff0c;结果买在半山腰&#xff1b;等真正见底了&#xff0c;又因为恐慌不敢上车&#xff0c;最后看着行情拉升干…

作者头像 李华
网站建设 2026/9/26 20:32:53

115网盘一键转存脚本实战:从原理到避坑指南

简介&#xff1a;115一键转存.user.js 是一款面向115网盘用户的效率辅助脚本&#xff0c;基于油猴&#xff08;Tampermonkey&#xff09;等浏览器扩展运行&#xff0c;能够在115网盘页面中直接触发&#xff0c;显著简化批量转存、批量创建共享链接以及获取下载链接等高频操作&a…

作者头像 李华