Hive on Tez兼容Hadoop 3.3.1:源码构建minimal包与部署排查全指南
2026/9/16 2:52:18 网站建设 项目流程

最近重装了一套 Hadoop 3.3.1 + Hive 3.1.2 的环境,过程中卡得最久的一件事,就是搞出一个能在上面正常跑的 Tez 0.10.1 minimal 包。直接去 Apache 下载官方apache-tez-0.10.1-minimal.tar.gz,丢进 Hive 里当执行引擎,大概率跑select 1都出不来。这个锅不背给 Hive,而是官方 Tez 0.10.1 默认依赖的是 Hadoop 2.x 的 jar,在 Hadoop 3 上会抛各种类找不到、方法找不到。

这篇文章把我从踩坑到解决的全过程写一遍:官方包为什么跑不了、为什么我不建议手动替换 jar、怎么用源码重新打出真正兼容 Hadoop 3.3.1 的 minimal 包、部署到 Hive 3.1.2 的完整步骤,以及跑起来之后常见的故障排查链路。如果你也在折腾同一套版本组合,可以直接照着抄。

1. 问题的根源:官方Tez 0.10.1包里装的是Hadoop 2的依赖

1.1 为什么Tez要“自带一份Hadoop依赖”

Tez 不是一个纯内存框架,它要跟 HDFS、YARN 直接通信。Tez 客户端要提交 Application、Tez AM 要跟 ResourceManager 谈资源、Task 要读写 HDFS,这些环节都依赖 Hadoop Client。所以 Tez 的发布包会把 Hadoop 相关 jar 一起打进去,避免用户环境里缺依赖。

你可以把 Tez 理解成搬进 YARN 小区的租客,它需要和自己住在同一个时期的门禁系统对接。Tez 0.10.1 发布时默认主流还是 Hadoop 2.x,官方构建脚本就把依赖版本都指向了 Hadoop 2 系列。所以你下载到的官方 minimal 包,里面的 hadoop-common、hadoop-hdfs、hadoop-auth 都是 2.x 的版本。

这一点很容易确认。如果你机器上已经下好了官方包,直接看压缩包里的文件列表:

tar -tzf apache-tez-0.10.1-minimal.tar.gz | grep -E "hadoop-(common|hdfs|auth)"

排除掉目录路径之后,看到的文件会是这种风格:

tez-0.10.1/lib/hadoop-common-2.x.jar tez-0.10.1/lib/hadoop-hdfs-2.x.jar tez-0.10.1/lib/hadoop-auth-2.x.jar

问题就在这。

1.2 Hadoop 3不是“向后兼容的老好人”

Hadoop 3 相比 2.x,不是简单升个版本号,改动非常多。对你跑 Tez 影响最大的有几个点:

  • Protobuf 版本不兼容:Hadoop 3.3.1 默认依赖的 protobuf-java 是 3.x,而 Hadoop 2 时代用的是 2.5 之类。protobuf 的类名大量重叠,但二进制协议和序列化格式不兼容。
  • RPC 协议有调整:YARN ResourceManager、HDFS NameNode 的 RPC 协议版本在 Hadoop 3 中有变化。旧 Tez 包里带着的 hadoop-common 去建立连接时,轻则握手失败,重则整个 AM 直接退出。
  • API 改动:Hadoop 3 删除或调整了一批类和方法,比如ConfigurationFileSystemhadoop-auth相关的接口。旧版本的 jar 可能类还在,但某方法签名变了,运行时才爆NoSuchMethodError

这些不是 Hive 3.1.2 的问题。Hive 3.1.2 只是把 Tez 当执行引擎使用,Tez 往 YARN 上提交 DAG、启动 AM、调度任务,这一整条链路都在跟 Hadoop 3.3.1 打交道。只要 Tez 带的 Hadoop 依赖是 2.x,连第一关都过不去。

所以在动手配置 Hive 之前,最好先问自己一句:手头这个 Tez 包,是不是跟集群同一个 Hadoop 版本编译出来的。

2. 选型判断:手动替换jar这条路为什么放弃

2.1 直接替换lib下Hadoop jar,看起来很美

我一开始的想法很简单:既然问题只是 Tez 包里带了 Hadoop 2.x 的 jar,那把lib/下面几个 hadoop 相关 jar 换成 Hadoop 3.3.1 的对应版本不就行了?

理论上确实可以,实际操作起来却不是那么回事。替换完之后,最常见的报错长这样:

java.lang.NoSuchMethodError: org.apache.hadoop.conf.Configuration.getPassword(Ljava/lang/String;)[C at org.apache.hadoop.hdfs.DFSUtil.<clinit>(DFSUtil.java:...)

原因很简单:Tez 自己的 class 文件是按 Hadoop 2.x 编译的,里面的字节码引用的是 Hadoop 2 时代的方法和字段。你换成 Hadoop 3.3.1 的 jar 之后,类文件能加载,但某些方法在 Hadoop 3 里已经被调整或移除了。运行时一调用,直接 NoSuchMethodError。

反过来也有问题:Hadoop 3 里新增了部分接口和实现,而 Tez 老代码根本没有调用,所以光看编译期定义看不出毛病,必须等跑到某个具体功能才崩。这种问题最难排查,因为你不知道哪一步会炸。

而且手动替换不只是换 common、hdfs、auth 三个 jar。Hadoop 3 的 jar 体系比 2.x 更细,还牵扯hadoop-mapreduce-client-corehadoop-client-apihadoop-client-runtime、protobuf-java 等一串依赖。靠手工去试试错,时间成本远高于重新打包。

2.2 为什么最终选择源码重新构建

Tez 0.10.1 的工程对 Hadoop 版本的切换支持得比较友好,根 pom 里用${hadoop.version}这样一个属性统一控制所有 Hadoop 相关依赖的版本。也就是说,我们不需要去改几十个 jar 的版本号,只需要在打包时传一个参数覆盖它。

而且 Tez 的构建会一次性产出两个分发包:apache-tez-0.10.1-bin.tar.gzapache-tez-0.10.1-minimal.tar.gz。minimal 就是我们需要的运行时精简包,里面没有 UI、没有多余示例,正好适合放在 HDFS 上让容器远程加载。

从时间上看,我第一次手动替换 jar 折腾了大半天,最后还是跑不通。反过来老老实实走源码构建,整个编译加部署加验证,大概一个上午就搞定。所以结论很明确:别跟二进制杠,直接用源码构建。

3. 从源码构建Tez 0.10.1 minimal的完整步骤

3.1 构建前环境准备

我用的构建环境是 CentOS 7.9,Java 8,Maven 3.6.3。这里要特别注意:JDK 一定要用 8,不要用 JDK 11 甚至 17。Hadoop 3.3.1 虽然支持 Java 8 和 11,但 Tez 0.10.1 是明确按 Java 8 编译验证过的,我试过用 JDK 11 构建,某些模块会有编译告警甚至直接失败。

Maven 用 3.6.x 就行。如果网络环境访问 Maven 中央仓库慢,先配置阿里云镜像,否则构建 Tez 这种体量的工程会一直卡在下载依赖上。在~/.m2/settings.xml里加一段:

<mirrors> <mirror> <id>aliyun</id> <mirrorOf>*</mirrorOf> <url>https://maven.aliyun.com/repository/public</url> </mirror> </mirrors>

构建机器上不建议跑其他重负载任务,因为 Tez 的编译大概会拉数百兆依赖,中途断网很痛苦。

3.2 下载源码与完整构建命令

从 Apache Archive 下载 Tez 0.10.1 源码包:

mkdir -p /opt/build cd /opt/build wget https://archive.apache.org/dist/tez/0.10.1/apache-tez-0.10.1-src.tar.gz tar -xzf apache-tez-0.10.1-src.tar.gz cd apache-tez-0.10.1-src

构建命令如下:

mvn clean package \ -Dhadoop.version=3.3.1 \ -DskipTests \ -Dmaven.javadoc.skip=true \ -Dcheckstyle.skip=true \ -Drat.skip=true \ -DskipUI=true

逐项解释几个参数的作用:

  • -Dhadoop.version=3.3.1:核心参数,把整个工程里所有 Hadoop 相关依赖统一指向 Hadoop 3.3.1。
  • -DskipTests:跳过测试,避免在构建过程中跑起 YARN MiniCluster 等集成测试,又慢又容易翻车。
  • -Dmaven.javadoc.skip=true:跳过 javadoc 生成,省时间。
  • -Dcheckstyle.skip=true-Drat.skip=true:跳过代码风格检查和 RAT license 检查。自己打包没必要被这些规则卡住。
  • -DskipUI=true:跳过 Tez UI 的构建。Tez UI 依赖 Node、npm 那套前端工具链,如果你只是为了跑 SQL,根本没必须编译它。万一当前版本不支持这个属性,直接把 tez-ui 模块从构建里排掉也行。

如果你在编译tez-apitez-runtime-library时报 protobuf 相关错误,很可能是本地 Maven 仓库把 protobuf 版本解析成了 2.5 之类的旧版。这时可以补一个参数:

mvn clean package \ -Dhadoop.version=3.3.1 \ -Dprotobuf.version=3.7.1 \ -DskipTests \ -Dmaven.javadoc.skip=true

Hadoop 3.3.1 默认对应的 protobuf-java 就是 3.7.1 这条线,把它显式指定后,大部分编译问题能直接消失。

3.3 构建产物检查

构建完成之后,去tez-dist/target/下面看产物:

ls -lh tez-dist/target/*.tar.gz

应该能看到:

apache-tez-0.10.1-bin.tar.gz apache-tez-0.10.1-minimal.tar.gz

其中 minimal 包就是我们需要的。再验证一下内部的 Hadoop 依赖版本:

tar -tzf tez-dist/target/apache-tez-0.10.1-minimal.tar.gz | grep -E "hadoop-(common|hdfs|auth)"

正常结果里出现的应该是:

tez-0.10.1/lib/hadoop-common-3.3.1.jar tez-0.10.1/lib/hadoop-hdfs-3.3.1.jar tez-0.10.1/lib/hadoop-auth-3.3.1.jar

到这一步,包的核心问题已经解决了。后续所有部署操作都基于这个自建的 minimal 包。

3.4 进一步做“真minimal”裁剪

官方 minimal 包已经比 full 包干净很多,但如果你有洁癖,可以再手动裁一刀。把压缩包解压出来,清理这几类文件:

  • *-sources.jar:源码包,运行不需要。
  • *-tests.jar:测试类,不需要。
  • tez-tests-*.jartez-examples-*.jar:仅用于测试/示例,生产环境不需要。
  • 如果你非常确定集群的yarn.application.classpath已经覆盖全部 Hadoop 客户端 jar,且配置了tez.use.cluster.hadoop-libs=true,那lib/下的 hadoop-common、hadoop-hdfs、hadoop-auth 这些也可以拿掉。

我个人的建议是:第一次先保留 hadoop jar,确认整个链路跑通之后再考虑瘦身。否则你很难判断一次报错到底是因为裁剪了依赖,还是 Hive 本身配置有问题。

cd /opt/build tar -xzf tez-dist/target/apache-tez-0.10.1-minimal.tar.gz cd tez-0.10.1 rm -f lib/*sources.jar rm -f lib/*tests.jar rm -f tez-tests*.jar tez-examples*.jar cd /opt/build tar -czf tez-0.10.1-minimal-custom.tar.gz tez-0.10.1

4. 把自建Tez包部署到Hadoop 3.3.1 + Hive 3.1.2

4.1 本地目录规划与tez-site.xml

先把构建出来的 tar 包解压到固定目录。我这里统一放在/opt/tez-0.10.1/tez-0.10.1,后面 Hive 配置会引用这个路径:

mkdir -p /opt/tez-0.10.1 tar -xzf /opt/build/tez-dist/target/apache-tez-0.10.1-minimal.tar.gz -C /opt/tez-0.10.1

conf/tez-site.xml里做基本配置。Tez 的配置项很多,对第一次跑通来说,以下几项已经够用:

<?xml version="1.0" encoding="UTF-8"?> <configuration> <property> <name>tez.lib.uris</name> <value>hdfs://mycluster/apps/tez-0.10.1/tez-0.10.1.tar.gz</value> </property> <property> <name>tez.use.cluster.hadoop-libs</name> <value>true</value> </property> <property> <name>tez.staging-dir</name> <value>${fs.defaultFS}/tmp/tez/staging</value> </property> <property> <name>tez.am.resource.memory.mb</name> <value>2048</value> </property> <property> <name>tez.am.java.opts</name> <value>-Xmx1536m</value> </property> <property> <name>tez.task.resource.memory.mb</name> <value>2048</value> </property> <property> <name>tez.task.java.opts</name> <value>-Xmx1536m</value> </property> </configuration>

说明几点:

  • tez.lib.uris里的mycluster要换成你实际 NameNode 的 nameservice 或主机名。如果是单节点伪分布式,直接写成hdfs://localhost:8020/apps/tez-0.10.1/tez-0.10.1.tar.gz也行。
  • tez.use.cluster.hadoop-libs=true的意思是让 Tez 优先使用集群里已经存在的 Hadoop 库,而不是完全依赖自己打包进来的 jar。我们自建的包已经是 Hadoop 3.3.1 了,开这个开关不会冲突,还能减少未来跟集群 Hadoop 库打架的概率。
  • AM 和 Task 的内存别写太大,尤其伪分布式单机环境,稍后在排查环节会专门说明。

4.2 HDFS上放.tar.gz还是解压目录

Tez 运行时需要把依赖分发到 YARN 容器里,两种主流方式:

方式一:直接传压缩包,tez.lib.uris 指向 tar.gz

hadoop fs -mkdir -p /apps/tez-0.10.1 hadoop fs -put /opt/tez-0.10.1/tez-0.10.1/../apache-tez-0.10.1-minimal.tar.gz /apps/tez-0.10.1/tez-0.10.1.tar.gz

注意:这里传的是压缩包文件,不是解压后的目录。因为tez.lib.uris配置的是一个资源 URI,Tez 会在容器里把它当压缩包解压。

方式二:直接传解压目录,tez.lib.uris 指向目录

hadoop fs -mkdir -p /apps/tez-0.10.1 hadoop fs -put /opt/tez-0.10.1/tez-0.10.1 /apps/tez-0.10.1/

然后tez-site.xml里写:

<property> <name>tez.lib.uris</name> <value>hdfs://mycluster/apps/tez-0.10.1/tez-0.10.1/</value> </property>

两种方式我都试过,生产环境建议用方式一,HDFS 上就一个文件,管理成本低。调试阶段方式二更方便,改配置可以直接动目录。无论用哪种,记得检查 HDFS 权限,要保证提交任务的用户能读:

hadoop fs -chmod -R 755 /apps/tez-0.10.1 hadoop fs -ls /apps/tez-0.10.1/

4.3 配置Hive:TEZ_HOME、AUX_JARS与执行引擎

回到 Hive 3.1.2。先编辑$HIVE_HOME/conf/hive-env.sh,在文件末尾追加:

export TEZ_HOME=/opt/tez-0.10.1/tez-0.10.1 export TEZ_CONF_DIR=${TEZ_HOME}/conf export HADOOP_CLASSPATH="${TEZ_CONF_DIR}:${TEZ_HOME}/lib/*:${HADOOP_CLASSPATH}" export HIVE_AUX_JARS_PATH="${TEZ_CONF_DIR}:${TEZ_HOME}/lib/*"

很多教程会写成TEZ_JARS一个变量再展开,但 Hive 3 对HIVE_AUX_JARS_PATH里的通配符支持得还不错,直接写lib/*是可以的。如果你用的 Hive 版本比较老,也可以把lib/*改成lib目录,Hive 会自动把这个目录下所有 jar 加进辅助 classpath。

然后修改$HIVE_HOME/conf/hive-site.xml,把执行引擎切到 Tez:

<property> <name>hive.execution.engine</name> <value>tez</value> </property>

如果之前一直用的 MapReduce 跑 HQL,这里一定要确认改对了。可以用下面命令验证一下:

hive -e "set hive.execution.engine;"

输出应该是:

hive.execution.engine=tez

到这里 Tez 和 Hive 的配置就接好了。需要重启的服务记得重启,尤其是启动了 HiveServer2 或者 Metastore 的话,别只改完配置就丢在原地。

5. 启动与验证:从select 1到实际跑HQL

5.1 先跑最朴素的select 1

配置改完之后,不要一上来就跑复杂 SQL,先跑一条最基础的:

hive -e "select 1;"

如果一切正常,终端里会看到类似“Connected to metastore”或者“Starting Spark Session”之类的 Hive 启动日志,但最终会进入 Tez Session 初始化,然后执行 Map 1 这样的阶段。注意看有没有出现Vertex failed或者DAGAppMaster异常堆栈。

同时可以开一个窗口观察 YARN UI。正常提交后,YARN Application 列表里会出现一个 Application Type 为TEZ的任务。如果 application type 还是MAPREDUCE,说明 Hive 还在用 MR 引擎,排查方向就偏了。

5.2 跑一个带Map和Reduce真实查询

select 1通过之后,我们可以跑一个真正触发分组、排序的 HQL,验证 Tez 的 DAG 调度能力:

hive -e " CREATE TABLE tmp_test_tez(id int, name string); INSERT INTO tmp_test_tez VALUES (1,'a'),(2,'b'),(2,'c'),(3,'d'),(3,'e'),(3,'f'); SELECT id, count(*) FROM tmp_test_tez GROUP BY id ORDER BY id; "

正常执行时,Tez 会为这条 SQL 生成一个包含多个 Vertex 的 DAG,从 Tez 的日志里能看到类似:

DAG. Plannable using tez runtime.

执行结束后没有异常,说明整个链路已经通了:Hive 客户端提交 DAG -> YARN 为 Tez AM 分配容器 -> AM 从 HDFS 拉取 minimal 包 -> Task 在 NodeManager 容器里执行 -> 结果返回。

我在这一步遇到过最典型的坑是:select 1能过,但INSERTGROUP BY就挂。原因通常是容器内存不足,或者 Hive 的 aux jar 没把hive-exec加到 Tez 子进程里。后面排查部分会展开。

5.3 看看YARN日志里到底有没有加载3.3.1的jar

如果还是不放心,可以进 YARN 的日志确认一下实际加载的 Hadoop 版本。用yarn logs -applicationId <app_id>查看 AM 日志,搜索hadoop-commonClasspath,能看到容器 classpath 里的 jar 路径。

这一步能回答一个关键问题:报错是不是因为某个 NodeManager 还残留旧版本 tez 的本地缓存。YARN 的本地资源缓存有时会保留同名旧文件,导致改版后依然加载到旧 jar。遇到这种情况,可以在节点上清理$yarn.nodemanager.local-dirs下的 filecache,或者重启 NodeManager 再跑一次。

6. 实战排查:Hive on Tez最常见的5个故障链路

6.1 AM容器反复退出:先看YARN Application日志

如果 Tez 任务提交后,Application 一直处于 ACCEPTED 或反复 FAILED,先把 YARN 日志拉出来:

yarn logs -applicationId application_1653000000000_0001

常见原因可以快速过一遍:

现场表现优先检查
AM 启动后秒退,日志里是 class not foundTez lib 加载路径、HIVE_AUX_JARS_PATH
AM 一直等待资源无法启动集群内存资源不足,调小 AM 内存
日志里出现 HDFS 路径不一致tez.lib.uris和实际 HDFS 上传路径是否匹配
日志提示 staging 目录问题tez.staging-dir是否创建并且可写

一个非常容易被忽略的点是:tez.lib.uris写的是hdfs://mycluster/...,但客户端环境的fs.defaultFS可能是别人的 nameservice,导致客户端根本解析不了这个地址。配置里最好用集群统一的 nameservice,或者直接参考core-site.xml里的实际地址。

6.2 类冲突/版本不匹配:先确认tez lib下hadoop jar

这一类报错五花八门,但根因基本都是“某个 jar 还是 Hadoop 2 的”。常见说法:

java.lang.NoSuchMethodError: org.apache.hadoop.conf.Configuration.getPassword(Ljava/lang/String;)[C java.lang.NoClassDefFoundError: org/apache/hadoop/hdfs/protocol/HdfsConstants...

排查链路按顺序做:

  1. 查看 HDFS 上 tez tar 里的 hadoop jar 版本:
    hadoop fs -cat /apps/tez-0.10.1/tez-0.10.1.tar.gz | tar -tzf - | grep "hadoop-common"
  2. 确认 Hive 客户端本地/opt/tez-0.10.1/tez-0.10.1/lib/下同样是 3.3.1。
  3. 检查 NodeManager 本地缓存里有没有历史残留的 tez 包,如果有,缓存可能命中了旧文件。

还有一个排查小技巧:在hive-site.xml里临时把 Hive 日志级别调到 DEBUG,再跑一次select 1。日志里会完整打印 Tez 客户端构建的 classpath,一眼就能看到某个 jar 的版本来源。

6.3 权限、staging目录和HDFS路径

Tez 运行时会往 HDFS 上报 staging 文件,如果没指定或权限不够,会报类似:

IllegalArgumentException: tez.staging-dir must not be null

解决办法是在tez-site.xml里显式指定:

<property> <name>tez.staging-dir</name> <value>${fs.defaultFS}/tmp/tez/staging</value> </property>

再确认目录存在且有写权限:

hadoop fs -mkdir -p /tmp/tez/staging hadoop fs -chmod -R 755 /tmp/tez

如果你是用普通用户(非 hdfs 超级用户)提交任务,HDFS 上/apps/tez-0.10.1也必须对该用户有读权限。之前我就因为没给/apps/tez-0.10.1加权限,任务一提交就报 AccessControlException。

6.4 Tez session一直pending或超时

单机伪分布式或者小集群经常遇到这种问题。select 1提交后卡很久,最终报:

TezSession has already shutdown

或者org.apache.tez.dag.api.SessionNotRunning

大概率是内存资源不够。YARN 的调度是整块内存分配,Tez AM 要 2GB,Task 要 2GB,而 NodeManager 总共只有 4GB 可用,那第一个容器可能勉强起来,第二个容器永远等不到资源。

建议先看yarn-site.xml

<property> <name>yarn.nodemanager.resource.memory-mb</name> <value>6144</value> </property> <property> <name>yarn.scheduler.maximum-allocation-mb</name> <value>4096</value> </property>

Tez 侧参数配合调整:

参数建议值(伪分布式)
tez.am.resource.memory.mb2048
tez.am.java.opts-Xmx1536m
tez.task.resource.memory.mb1024
tez.task.java.opts-Xmx768m

即使容器内存设置比较大,java.opts也一定要比容器内存小一些,因为 Hadoop 自身还要占一部分内存。

6.5 验证裁剪后的minimal包是否稳定

如果你按前面 3.4 节做了更激进的裁剪,比如把lib/下 hadoop jar 删了,那就必须用实际任务验证一次。凡是修改过 tez tar 或目录,重新上传 HDFS 之后要做三件事:

  1. 删掉 YARN NodeManager 本地文件缓存里旧的 tez 包,或者直接重启 NodeManager。
  2. 重新跑select 1
  3. 再跑一个有数据写入的 HQL。

如果裁剪后报ClassNotFoundException: org.apache.hadoop.conf.Configuration,说明集群的yarn.application.classpath没有像预期那样提供 Hadoop 库,你需要在yarn-site.xml里配置:

<property> <name>yarn.application.classpath</name> <value>$HADOOP_CONF_DIR,$HADOOP_COMMON_HOME/*,$HADOOP_COMMON_HOME/lib/*,$HADOOP_HDFS_HOME/*,$HADOOP_HDFS_HOME/lib/*,$HADOOP_MAPRED_HOME/*,$HADOOP_MAPRED_HOME/lib/*,$HADOOP_YARN_HOME/*,$HADOOP_YARN_HOME/lib/*</value> </property>

改完重启 ResourceManager 和 NodeManager 再跑。

我个人在生产环境里的建议是:不要为了省那几十兆空间把 hadoop jar 从 tez 包里删掉,除非你非常确定集群的 classpath 规则。保留这些 jar,配合tez.use.cluster.hadoop-libs=true,既能保证依赖版本一致,又不会引发重复加载冲突。

7. 一点扩展:这套“指定Hadoop版本重新打包”的思路还能用在哪

这次自建 Tez 0.10.1 minimal 的过程,本质上是一个通用思路:凡是框架发布包里带有 Hadoop 依赖的,都可以通过覆盖构建参数来匹配你的集群版本。我在 Spark、Flink、Presto 相关组件上也踩过类似的坑,比如 Spark 官方包默认对应的 Hadoop 版本跟集群不一致时,跑 HDFS 读写就会遇到各种兼容问题。

如果你以后升级 Hadoop 到 3.3.x 的某个小版本,不需要改 Tez 源码,只要把-Dhadoop.version换成对应版本,重新执行一次打包流程就行。这个流程我已经固化成了一个脚本,每次换版本大概十分钟就能产出新包。

最后再分享一个实操体会:遇到依赖类冲突,优先怀疑“版本不对”,其次才是“配置缺失”。Hive on Tez 这类嵌套多、classpath 超长的框架,大部分问题都能通过检查 Tez 包里的 hadoop jar 版本、HDFS 上 tez 资源路径、以及 YARN 容器实际 classpath 这三个地方定位到。把这几个点记牢,后面再碰到奇怪的报错,心里就有底了。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询