openEuler 24.03上搭建Hadoop+Spark+Kafka+Hive等大数据集群实战
写这篇东西的起因很简单周末在家整理自己的服务器笔记发现这套“ZookeeperHadoopSparkKafkaHiveFlumeMySQL分布式集群”在 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 MySQLnode02Worker1ZooKeeper DataNode NodeManager Kafka Flumenode03Worker2ZooKeeper 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.1for 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_keysssh-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/SELINUXenforcing/SELINUXdisabled/ /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/zookeeper3.2 zoo.cfg 与 myid 配置细节ZooKeeper 的配置文件在conf/zoo.cfg需要手动创建模板中的zoo_sample.cfg不算数。我的三节点配置如下tickTime2000 initLimit10 syncLimit5 dataDir/data/zookeeper clientPort2181 server.1node01:2888:3888 server.2node02:2888:3888 server.3node03:2888:3888重点解释下2888和3888前者是 leader 和 follower 之间同步数据用的端口后者是集群选举时投票用的端口。initLimit10表示 follower 在启动后 10 个 tick 时间内必须连上 leadersyncLimit5表示 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 2181mntr输出里的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 namefs.defaultFS/name valuehdfs://node01:9820/value /property property namehadoop.tmp.dir/name value/data/hadoop/tmp/value /property /configuration注意端口是9820。如果你在网上看到 9000/8020那是旧版本 Hadoop 的默认端口3.x 默认改成了 9820照着老教程配会连不上。hdfs-site.xml设置副本数和 NameNode 元数据目录configuration property namedfs.replication/name value2/value /property property namedfs.namenode.name.dir/name value/data/hadoop/namenode/value /property property namedfs.datanode.data.dir/name value/data/hadoop/datanode/value /property /configuration副本数建议设置为2。三台节点副本数为 3 的话数据会存满三台读取效率高但占用空间大试验环境设置 2 更经济。但注意dfs.replication如果设置为 1万一某个 DataNode 挂掉数据就真丢了自己权衡。yarn-site.xml是资源调度的核心configuration property nameyarn.nodemanager.aux-services/name valuemapreduce_shuffle/value /property property nameyarn.resourcemanager.hostname/name valuenode01/value /property property nameyarn.nodemanager.resource.memory-mb/name value6144/value /property property nameyarn.scheduler.maximum-allocation-mb/name value6144/value /property /property /configurationyarn.nodemanager.resource.memory-mb决定每个 NodeManager 能分配多少内存给容器。它必须小于物理内存建议设置为物理内存的 80% 左右。我在 8G 机器上设了 6144剩下留给系统和服务端。mapred-site.xml只需要指定 MapReduce 跑在 YARN 上configuration property namemapreduce.framework.name/name valueyarn/value /property /configuration4.2workers文件与数据目录权限这一步经常被忽略。Hadoop 3.x 里etc/hadoop/workers文件旧版本叫 slaves决定哪些机器是 DataNodenode02 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、ResourceManagernode02 和 node03 上有DataNode、NodeManager。用jps确认后用浏览器访问http://node01:9870看 HDFS 页面http://node01:8088看 YARN 页面。如果节点列表里 DataNode 没出现先翻日志不要急着重启。5. Spark 集群部署5.1 部署模式选择YARN 还是 StandaloneSpark 本身有独立的集群模式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-logs5.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.id1 listenersPLAINTEXT://node01:9092 log.dirs/data/kafka/logs zookeeper.connectnode01:2181,node02:2181,node03:2181 num.partitions3 default.replication.factor2 offsets.topic.replication.factor2broker.id每台必须不同node01 是 1node02 是 2node03 是 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 EagleCFAK。演示环境跑一个 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 topicKafka 再交给后面的消费者去处理。我们这套集群里Flume 就是一个“送水工”把数据从前端系统搬到 Kafka。这个模式也是网约车项目、交通分析系统里最常见的数据入口设计。7.2 采集到 Kafka 的配置示例在 node02 上配置 Flume改conf/flume-conf.propertiesagent.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 -Fspooldir更稳定不会因为文件被轮转而丢失数据。先提前建好目录放入一个测试文件。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.loggerINFO,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 下安装 MySQLopenEuler 的默认源里没有 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.logMySQL 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 -pHive123!# -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 指向 MySQLHive 的核心配置文件是conf/hive-site.xml默认不存在需要自己创建。关键内容是让 metastore 连接 MySQLconfiguration property namejavax.jdo.option.ConnectionURL/name valuejdbc:mysql://node01:3306/hive?useSSLfalseamp;serverTimezoneAsia/Shanghai/value /property property namejavax.jdo.option.ConnectionDriverName/name valuecom.mysql.cj.jdbc.Driver/value /property property namejavax.jdo.option.ConnectionUserName/name valuehive/value /property property namejavax.jdo.option.ConnectionPassword/name valueHive123!#/value /property property namehive.metastore.uris/name valuethrift://node01:9083/value /property /configurationhive.metastore.uris这行很重要。如果不配置Hive 会默认启动一个内嵌的 metastore 服务客户端直接连接数据库但集群环境里多个 Hive 客户端连接同一个数据库会容易出现版本冲突或锁问题。单独启动 metastore 进程客户端统一连接这个服务是更规范的做法。9.2 执行引擎选择Hive 3.1.3 支持 MapReduce 和 Spark 两种执行引擎默认是 MapReduce。如果直接跑复杂查询MapReduce 的响应时间慢得让人抓狂。我建议在hive-site.xml里增加property namehive.execution.engine/name valuespark/value /property property namespark.master/name valueyarn/value /property property namespark.home/name value/opt/bigdata/spark-3.5.1-bin-hadoop3/value /property property namehive.spark.client.server.connect.timeout/name value60000/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 21 再启动 hiveserver2供 beeline 连接用nohup /opt/bigdata/hive-3.1.3/bin/hive --service hiveserver2 /var/log/hiveserver2.log 21 接着用 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 启动顺序与关闭顺序这套集群组件多相互依赖启动顺序错了就会出现各种诡异问题。我按依赖关系整理了一个顺序启动 ZooKeeper三台启动 HDFSstart-dfs.sh启动 YARNstart-yarn.sh启动 Kafka三台启动 Flumenode02启动 Hive metastore 和 hiveserver2node01Spark 不需要单独启动由 YARN 拉起关闭顺序基本反过来先关 Hive、Flume、Kafka再关 YARN、HDFS最后关 ZooKeeper。你可能会问为什么 Spark 不在这份清单里因为 Spark on YARN 模式没有常驻服务进程它就是客户端一提交任务就走。这个顺序的核心原则是“先启动其他组件依赖的服务”。Kafka 依赖 ZooKeeperHive 依赖 MySQL 和 Spark/HadoopFlume 依赖 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 和 brokerHDFS 目录打不开查权限。链路式排查比单点排查高效得多。11. 常见问题与排查技巧实录11.1 权限、目录与依赖类问题Permission deniedHDFS 或本地目录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_HEAPSIZE2048Spark 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等它初始化避免服务还没就绪下一个就去连。这个习惯能帮你省掉无数“启动顺序不对导致莫名其妙报错”的时间。
上一篇/下一篇内容由系统自动关联
返回资讯列表 →