Spark 2.3.0 without-hive 对接 Hive 元数据
发布时间:2026/10/26 17:48:13 锦皓数字建站

简介Spark 2.3.0 无 Hive JAR 发行包面向已部署独立 Hive 集群、希望借助 Spark 计算能力处理 Hive 数据并实践 hive on spark 的开发与运维人员用于在不引入 Hive 全套执行组件的前提下访问 Hive 元数据、完成批处理与交互式查询等任务也适合高校大数据课程实验与企业内训取用。压缩包共 867 个文件约 127.77MB以 235 个 Python、187 个 Scala、125 个 Java 源码和 109 个 jar 依赖为主体辅以文本说明、启动脚本、配置模板以及 parquet、orc、avro、csv 等示例数据兼顾多语言接口学习与运行环境搭建。已有 659 人学习。读者可从中熟悉 Spark 2.3.0 的目录结构与依赖组成结合示例数据与配置模板理解 Spark SQL、Streaming 及 Scala、Python、Java 接口的使用方式并为自行补齐 Hive 依赖、对接 metastore 提供可对照的底包适合集成实验、版本比对与教学演示。1. 版本先对齐为什么我偏偏挑 spark-2.3.0-bin-hadoop2-without-hive把 spark-2.3.0-bin-hadoop2-without-hive 解压到 /opt 之后绝大多数人第一件事就是敲 spark-shell看到版本号打出来就当装完了等真正要跑 hive on spark才发现包名里那个 without-hive 并不是随手加的后缀。它把 Hive 那套 jar 从发行包里摘了出去版本交给你自己挑——挑对了省事挑错了就是一串 ClassNotFound 和 NoSuchMethodError。这套组合在老机房里太常见了Hadoop 还在 2.7 这条线上JDK 是 8元数据仓库躺在一台独立机器上。装不好时的表现也很统一本地算得飞快一碰 HDFS 或者一读元数据就崩。这篇是我自己复现用的安装记录给手上有 2.7 版本线、又要接 Hive 元数据仓的开发者照着走。2. 装前把地基打平JDK 8、Scala 2.11 与 Hadoop 2.7 的版本对照装 Spark 这事翻车点八成不在 Spark 本身而在旁边三个东西的版本没对齐。我见过太多次解压完就急着启动结果卡在一个说不清道不明的报错上最后发现是 JDK 高了一个大版本。所以我的习惯是解压之前先把版本表抄在纸上一个一个核对。2.1 三个版本号先钉死JDK 8、Scala 2.11、Hadoop 2.7先说结论这个包能配的组合范围其实很窄组件我用的版本可替换范围说明JDK1.8.0_1818u 系列任意小版本不能上 9 及以上反射和字节码都对不上Scala2.11.82.11.12 也可以预编译包的二进制版本就是 2.11别混 2.12Hadoop2.7.3 或 2.7.62.6、2.8 谨慎包名里的 hadoop2 指的就是 2.7 这条线Hive1.2.1 或 2.3.x看元数据服务端without-hive 就是留给你自己挑的元数据库关系型库一套—只有元数据服务端需要客户端不用JDK 这条要单独强调。Spark 2.3.0 是 Java 8 时代编出来的里面大量用了反射去碰 JDK 内部类还依赖javax.xml.bind这类在后续版本里被移出标准库的包。你在 JDK 11 上能起来不代表能跑完一个作业往往是在某个序列化或者时间类型转换的节点突然炸。Scala 2.12 的包不是没有但那是另一份预编译产物两个包不要共用一个 SPARK_HOME混着装迟早出事。Hive 版本的选择逻辑是「跟服务端保持一致」。如果集群里已经有一套 Hive 元数据服务在跑版本是 1.2.1那你spark.sql.hive.metastore.version就写 1.2.1服务端是 2.3.x 就写 2.3.x。这里的数字不是随便填的它决定了 Spark 用哪套 thrift 协议去跟元数据服务说话写错了的表现是连接能建立、show databases 却报协议解析错误。2.2 解压式安装从压缩包到 SPARK_HOME 的三步落地这个发行包没有安装器就是纯解压。但解压本身也有讲究我一般分三步做每步都能验证# 1. 先校验压缩包完整性避免解到一半报 unexpected EOF tar -tzf spark-2.3.0-bin-hadoop2-without-hive.tgz /dev/null echo 包完整 # 2. 解到统一目录路径不要带空格、中文和软链 tar -xzf spark-2.3.0-bin-hadoop2-without-hive.tgz -C /opt # 3. 做一条软链固定入口以后换版本只改这一处 ln -s /opt/spark-2.3.0-bin-hadoop2-without-hive /opt/spark chown -R hadoop:hadoop /opt/spark-2.3.0-bin-hadoop2-without-hive第一条是tar -tzf只列目录不解压用来提前发现包是不是传坏了。离线环境里压缩包经常被中转几次完整性校验能省掉后面半小时的排查。第二条-C /opt指定落地目录解压后会自动生成一个与原包同名的目录所以别再加-d之类的参数容易多套一层。第三条软链是关键后面所有配置、脚本、环境变量都只认/opt/spark将来上 2.4 或者别的版本改软链指向就行配置文件不用动一个字符。权限也顺手做掉。Spark 的日志、pid 文件如果落在安装目录下用错用户启动就会写不进去报一个很隐晦的权限错误。统一 chown 给运行用户后面省心。2.3 环境变量与 spark-env.sh 的最小配置集环境变量这一块网上抄来的版本通常一堆我实际只留六条# /etc/profile.d/spark.sh export SPARK_HOME/opt/spark export PATH$SPARK_HOME/bin:$PATH export HADOOP_CONF_DIR/opt/hadoop/etc/hadoop export SPARK_CONF_DIR$SPARK_HOME/conf export SPARK_LOCAL_IP10.0.0.11 export JAVA_HOME/usr/local/jdk1.8.0_181SPARK_HOME和PATH是老两样bin目录进 PATH 之后 spark-shell、spark-submit 才能直接敲。HADOOP_CONF_DIR是最容易被漏掉的一条它的作用是让 Spark 去读 Hadoop 的 core-site.xml 和 hdfs-site.xml没有它读写 HDFS 会报No FileSystem for scheme: hdfs或者解析不了集群名。SPARK_CONF_DIR显式指一下避免有人把 conf 目录挪走之后配置不生效。SPARK_LOCAL_IP是给多网卡机器用的不钉住的话 driver 可能绑到 docker0 或者别的虚拟网卡上表现是提交任务后一直卡在连接血泪经验。JAVA_HOME写全路径别依赖系统默认的 java。然后是$SPARK_HOME/conf下的两个文件。先复制模板改坏了还能回滚cd $SPARK_HOME/conf cp spark-env.sh.template spark-env.sh cp spark-defaults.conf.template spark-defaults.confspark-env.sh我一般这么写# $SPARK_HOME/conf/spark-env.sh export JAVA_HOME/usr/local/jdk1.8.0_181 export SPARK_MASTER_HOST10.0.0.11 export SPARK_MASTER_PORT7077 export SPARK_MASTER_WEBUI_PORT8081 export SPARK_WORKER_MEMORY8g export SPARK_WORKER_CORES8 export SPARK_LOG_DIR/data/spark/logs export SPARK_PID_DIR/data/spark/pids export SPARK_HISTORY_OPTS-Dspark.history.fs.logDirectoryhdfs://ns1/spark/eventlog -Dspark.history.ui.port18080这里要澄清一个常见误解上面这些 master、worker 的配置只在你用 Standalone 集群模式时才真正生效。如果只是单机 local 模式验证安装实际起作用的就是JAVA_HOME和SPARK_LOG_DIR、SPARK_PID_DIR这三条。但配置先写好没坏处等接上集群不用返工。端口上我把 webui 改成 8081、history 改成 18080纯粹是因为 8080 和 18080 在很多机器上已经被别的服务占了端口冲突导致的「启动成功但页面打不开」是最浪费时间的一类问题。SPARK_LOG_DIR和SPARK_PID_DIR指向/data而不是安装目录是运维习惯装软件的盘和放数据的盘分开日志涨起来不会把根分区撑爆。3. 单机先跑通local 模式下的第一个作业与 History Server地基铺完之后不要急着上集群。我的顺序永远是单机 local 先跑通再考虑 Standalone最后才是 YARN。理由很简单local 模式下没有资源调度、没有网络分发出问题一定是本地环境问题排查范围小得多。3.1 spark-shell 与 spark-submit 的第一次启动第一枪打spark-shell并且显式带上 master$SPARK_HOME/bin/spark-shell --master local[2]进去之后别急着退出先做两件事// 版本自证确认 Scala 是 2.11Spark 是 2.3.0 sc.version scala.util.Properties.versionNumberString // 一个不落盘的小作业验证执行引擎通了 spark.range(1, 1000000).selectExpr(sum(id)).show()sc.version返回 2.3.0 说明包没拿错scala.util.Properties.versionNumberString返回 2.11.x 说明 Scala 版本对得上。第二条spark.range造了一百万行数据做求和全程在内存里不碰磁盘也不碰 HDFS能跑出结果就说明 JVM、内存、执行器这条链路是通的。如果这一步就卡住或者 OOM问题一定在spark-env.sh的内存分配或者 JDK跟 Hive 一点关系没有。再用 spark-submit 跑一个官方自带的脚本示例验证提交入口$SPARK_HOME/bin/spark-submit \ --master local[4] \ --name pi-test \ $SPARK_HOME/examples/src/main/python/pi.py 100--master local[4]表示用本地四核跑--name是作业名会在 UI 上显示方便你确认提交的是哪一次。这个脚本算 π只用内存和 CPU是最干净的一次提交验证。跑通了说明 spark-submit 解析参数、拉起 driver、分配 executor 这一整条路都没问题。3.2 事件日志落盘与 History Server 配置local 模式能跑通不代表你能看到历史。默认情况下作业结束UI 一关什么都没了出了问题只能靠翻日志猜这就是我说的「黑匣子」状态。所以第三步是把事件日志打开# $SPARK_HOME/conf/spark-defaults.conf spark.eventLog.enabled true spark.eventLog.dir hdfs://ns1/spark/eventlog spark.eventLog.compress true spark.history.fs.logDirectory hdfs://ns1/spark/eventlog spark.history.ui.port 18080spark.eventLog.enabled是总开关spark.eventLog.dir是作业运行时写事件的地方spark.history.fs.logDirectory是 History Server 读的地方——这两个路径必须完全一致写成不一样是新手最常犯的错表现是 History Server 起来了、页面能打开、但列表永远是空的让人怀疑人生。spark.eventLog.compress打开压缩事件日志增长很快不压缩的话几百个作业就能堆出几个 G。HDFS 还没通的时候先把这两个路径换成file:///data/spark/eventlog本地路径单机验证阶段够用等 HDFS 通了再换回去。配置写完启动 History Server$SPARK_HOME/sbin/start-history-server.sh # 检查是否起来 jps | grep HistoryServer curl -s http://10.0.0.11:18080/api/v1/applications | head -c 200jps里能看到进程说明进程活着curl打 API 能返回 JSON 说明服务真的在对外提供查询。这两步比直接开浏览器靠谱因为浏览器打不开你分不清是服务没起、端口没通、还是页面问题。3.3 without-hive 这个包到底少了什么在往下接 Hive 之前先亲眼确认一下这个包里有什么、没什么# 看 jars 目录里跟 hive 相关的包正常应该一条都不剩 ls $SPARK_HOME/jars | grep -i hive # 对比总数with-hive 的包一般会多出二十来个 jar ls $SPARK_HOME/jars | wc -l第一条命令如果什么都不输出说明你拿到的确实是 without-hive 版本发行方把 Hive 1.2.1 那一整套依赖hive-exec、hive-metastore、datanucleus 系列都摘掉了。这一点非常关键因为它直接决定了配置里spark.sql.hive.metastore.jars不能写builtin——builtin 的含义是「用我包里自带的那些 Hive jar」而你没有。第二条命令看 jar 总数通常在一百来个。数量可以作为快速判断依据如果只有几十个那可能是拿错了精简包或者解压不完整。这个数字不用记死但心里要有个量级概念。摘掉 Hive 依赖不是缺陷反而是这个包的价值所在集群里通常已经有一套固定版本的 Hive 在服务其他组件让 Spark 去迁就包里那套 1.2.1多半会跟服务端版本打架。without-hive 把选择权交出来代价就是你必须自己把依赖补齐——这正是下一章要做的事。4. 补齐 Hive 依赖without-hive 包怎么把 hive on spark 这条链路接上到了这一步很多人会直接抄网上一段配置贴进 spark-defaults.conf然后发现根本连不上。原因是这类配置通常来自 with-hive 的包前提条件跟你不一样。这一章按「配置文件放哪 → 参数填什么 → jar 从哪来」的顺序走每一步都有可验证的结果。4.1 hive-site.xml放哪个目录、改哪三行Spark 认 Hive 配置的方式很朴素从 classpath 里找hive-site.xml。所以最省事的做法是把它放进$SPARK_HOME/conf这个目录天然在 classpath 上。# 从已有的 Hive 客户端机器上拷一份不要手写 scp hadoop10.0.0.12:/opt/hive/conf/hive-site.xml $SPARK_HOME/conf/手写 hive-site.xml 是我不推荐的做法Hive 的配置项太多漏一个就可能出奇怪的问题。从已经在用的客户端机器上拷一份过来只改必要的地方风险最小。拷过来之后重点看三行configuration !-- 1. 元数据服务地址必须是服务端真实起的 thrift 端口 -- property namehive.metastore.uris/name valuethrift://10.0.0.12:9083/value /property !-- 2. 仓库目录要跟 Hive 服务端保持一致否则两张皮 -- property namehive.metastore.warehouse.dir/name value/user/hive/warehouse/value /property !-- 3. 只有内嵌元数据模式才需要 JDBC远程模式可以留空 -- property namejavax.jdo.option.ConnectionURL/name valuejdbc:mysql://10.0.0.12:3306/hive?createDatabaseIfNotExisttrueamp;useSSLfalse/value /property /configuration第一条hive.metastore.uris是最关键的端口 9083 是元数据服务的默认 thrift 端口。填之前先用telnet 10.0.0.12 9083或者nc -z确认端口是通的服务端没起的话后面所有配置都是空谈。第二条hive.metastore.warehouse.dir决定了表数据落在 HDFS 的哪里这一项如果跟服务端不一致会出现「Spark 建的表在 Hive 里查不到」的诡异现象第五章会专门讲。第三条 JDBC 只在元数据服务用内嵌模式也就是 Spark 直连数据库时才生效走远程 thrift 的话客户端根本不需要数据库连接信息填了也不起作用——但很多人因为这一项不对误以为连接有问题排查半天。如果作业要跑在 YARN 集群模式hive-site.xml在 driver 端不一定能被分发到这时候要在提交时显式带上--files $SPARK_HOME/conf/hive-site.xml \ --conf spark.hadoop.hive.metastore.uristhrift://10.0.0.12:9083--files把文件分发到每个 executor 的工作目录spark.hadoop.前缀的含义是「把这个配置项注入到 Hadoop 的 Configuration 里」Spark 读 Hive 配置时走的正是这套机制。4.2 spark-defaults.conf 里的四个关键参数hive-site.xml解决的是「连哪里」spark-defaults.conf解决的是「用哪套 jar 去连」。这几个参数填错前面全白搭# 让 SparkSession 默认走 Hive 元数据等价于代码里 enableHiveSupport spark.sql.catalogImplementation hive # 必须跟服务端的 Hive 版本一致写错会报协议解析异常 spark.sql.hive.metastore.version 1.2.1 # without-hive 包不能写 builtin指向本地已有的 Hive lib 目录最稳 spark.sql.hive.metastore.jars /opt/hive/lib/* # 这几个前缀的类不走隔离类加载避免 JDBC 驱动被加载两次 spark.sql.hive.metastore.sharedPrefixes com.mysql.jdbc,org.postgresql # 仓库目录跟 hive-site.xml 里保持一致 spark.sql.warehouse.dir /user/hive/warehousespark.sql.catalogImplementation设成 hive 之后spark-shell或者spark-submit起来的 SparkSession 默认就带元数据能力不用每次在代码里写enableHiveSupport()。这是省事但也意味着一旦配置错了连最简单的show databases都会失败——所以我通常先不设这一项用代码显式开启确认链路通了再写进默认配置。spark.sql.hive.metastore.jars是这一章的核心。它有三个取值形态builtin表示用包里自带的你没有maven表示运行时去仓库拉指定版本需要节点能访问外部仓库离线环境基本没戏路径形式表示用你本地指定的 jar 集合。离线环境里路径形式是唯一靠谱的选择指向一台已经装好 Hive 客户端机器上的 lib 目录版本天然对得上。sharedPrefixes这一项解释起来有点绕。Spark 加载 Hive jar 时用的是隔离类加载器目的是防止 Hive 的依赖污染 Spark 自己的 classpath。但数据库驱动这种需要注册到 DriverManager 的类如果也被隔离加载就会报「找不到合适的驱动」。把驱动的包前缀写进 sharedPrefixes等于告诉 Spark「这几个包别隔离用父加载器」冲突就没了。清单里写几个取决于你用哪些库用不到的不写也行。4.3 Hive 依赖 jar 的两种落地方式与取舍spark.sql.hive.metastore.jars指向/opt/hive/lib/*的前提是这台机器上有一份完整的 Hive 客户端 lib。如果机器上没有有两种补法。第一种是把 Hive 的 lib 目录整份拷过来配置指过去# 从元数据服务所在机器同步一份 lib注意版本要完全一致 mkdir -p /opt/hive-deps rsync -av hadoop10.0.0.12:/opt/hive/lib/ /opt/hive-deps/lib/ # 配置改成指向这份拷贝 # spark.sql.hive.metastore.jars /opt/hive-deps/lib/*这种做法干净跟 Spark 安装目录完全解耦升级 Hive 只换这个目录。缺点是每个节点都得有一份集群规模大的话分发成本不小通常配合配置管理工具做。第二种是只拷必要的几个 jar 进$SPARK_HOME/jars# 只拷元数据客户端需要的不要整个 lib 全倒进去 cp /opt/hive/lib/hive-metastore-1.2.1.jar $SPARK_HOME/jars/ cp /opt/hive/lib/hive-exec-1.2.1.jar $SPARK_HOME/jars/ cp /opt/hive/lib/libthrift-0.9.3.jar $SPARK_HOME/jars/这种做法省事但我不太推荐原因有两个一是$SPARK_HOME/jars是个扁平目录所有 jar 平铺在一起Hive 带的 Guava 版本很容易跟 Spark 自带的撞上报出来的错是NoSuchMethodError加一串看不懂的类名二是它把版本绑死了将来换 Hive 版本得回头清理这个目录容易漏。真要这么干拷完立刻用ls $SPARK_HOME/jars | grep -i guava看一眼有没有多出一份 Guava有就删掉。不管用哪种方式配置改完都要重启一次会话再验证。spark-defaults.conf是启动时读取的改完不重启你会以为配置没生效然后开始怀疑人生。5. 避坑与排查五条翻车记录每条都带现象、原因和解决这一章是我自己踩过的以及帮别人排查过的全是真实症状。写的时候按「现象 → 原因 → 解决」的顺序照着对照就能定位。5.1 启动就报 ClassNotFoundHiveConf 找不到现象spark-shell能起来一敲spark.sql(show databases)立刻抛java.lang.ClassNotFoundException: HiveConf堆栈里全是类加载相关的行。原因spark.sql.hive.metastore.jars还停留在模板里的默认值或者写了builtin。without-hive 包里根本没有这套 jar隔离类加载器找不到类就直接抛出来。这个错的迷惑性在于「spark-shell 能起来」让人以为是 Hive 服务端的问题实际上跟服务端一点关系没有。解决确认这个参数写的是路径形式并且路径下真的有 jar。用ls /opt/hive/lib | grep metastore验证一下目录不是空的再重启。如果路径写的是通配符/*注意它是由 Spark 自己展开的不要加引号加了引号就变成一个字面量路径。5.2 Guava 撞车NoSuchMethodError 后面跟一长串类名现象连元数据的时候报NoSuchMethodError通常指向Preconditions.checkArgument或者Stopwatch这类方法说参数列表对不上。原因classpath 上存在两份不同版本的 Guava。Spark 2.3.0 自带的是 Guava 14 那一代Hive 2.x 系列带的 Guava 版本更高方法签名有变化。谁的类先被加载另一份的调用方就找不到匹配的方法。解决三步走。第一ls $SPARK_HOME/jars | grep -i guava确认只有一份。第二如果之前往 jars 目录拷过 Hive 的整个 lib把里面的 Guava 删掉让 Spark 用自己那份。第三如果确实需要高版本 Guava把它加进spark.sql.hive.metastore.sharedPrefixes让两边共用同一份。这个坑的排查成本很高因为报错信息完全看不出跟 Guava 有关只能靠经验往这个方向想。5.3 JDK 版本高了一个大版本javax/xml/bind 找不到现象启动直接抛NoClassDefFoundError: javax/xml/bind/DatatypeConverter还没到业务代码就挂了。原因机器上装的是 JDK 11 或更高JAVA_HOME指过去之后javax.xml.bind这一整包在 JDK 11 里被移出了标准库。Spark 2.3.0 的代码里到处在用这个包做类型转换。解决切回 JDK 8别想着加依赖包绕过去。绕过去的做法在某些场景确实能跑但会留下更多隐蔽问题不值得。改完JAVA_HOME记得确认spark-env.sh里那条也改了——环境变量和 spark-env.sh 里各写一份JAVA_HOME是常见配置方式改一处漏一处重启之后还是老 JDK。5.4 读不了 HDFSNo FileSystem for scheme 或 UnknownHostException现象本地文件算得好好的一读 HDFS 路径就报No FileSystem for scheme: hdfs或者报集群名解析不了。原因HADOOP_CONF_DIR没配或者配了但指向的目录里没有 core-site.xml、hdfs-site.xml。Spark 找不到fs.defaultFS自然不知道该连哪个集群。解决先echo $HADOOP_CONF_DIR确认变量有值再ls $HADOOP_CONF_DIR/core-site.xml确认文件存在最后grep -A2 fs.defaultFS $HADOOP_CONF_DIR/core-site.xml确认里面写的是真实集群地址。三步都对还报错的话检查是不是在 YARN 集群模式下跑的——集群模式下 driver 在别的节点上那台机器也必须有一份同样的配置文件光在提交机上配没用。5.5 表建出来了Hive 里看不见两套仓库路径现象在 Spark 里create table成功show tables也能看到但去 Hive 客户端里show tables是空的。原因spark.sql.warehouse.dir和hive.metastore.warehouse.dir指向了不同的 HDFS 路径。Spark 把表建到了自己那一套路径下元数据写进去了但 Hive 客户端按自己的配置去找路径对不上就看不到。这在接远程元数据服务时特别容易发生因为两边各自有一份配置。解决把两个参数改成完全一致然后重启会话重新建表。已经建歪的表drop table之后重建是最快的别去手动挪 HDFS 目录容易把元数据搞成半残状态。我一般会在配置里把这两项写在一起中间加一行注释标上「必须一致」就是为了防止下次自己手贱改一处。6. 装完怎么验证五步自检清单与一个提交模板装完不验证等于没装。我给自己定的规矩是走一套固定清单每一步都有明确的通过标准任何一步不过就停下来排查不往下走。验证项命令或语句通过标准版本与 Scalaspark-submit --version显示 2.3.0Scala 2.11.x本地执行引擎spark.range(1,100000).count()返回 100000耗时秒级HDFS 连通hadoop fs -ls /user/hive/warehouse能列出目录不报 UnknownHost元数据连通spark.sql(show databases).show()列出 default 及已有库仓库一致性spark.sql(desc formatted 某表)里的 Location与 Hive 侧一致第三步那条hadoop fs是我加进来的跟 Spark 无关但它能快速区分「Spark 配置问题」和「Hadoop 客户端问题」。如果hadoop fs都跑不通那智慧在 Spark 这边折腾是白费力气。一个完整的提交模板我一般存成脚本换作业只改类名和参数#!/bin/bash # submit.sh —— hive on spark 作业提交模板 $SPARK_HOME/bin/spark-submit \ --master yarn \ --deploy-mode client \ --name my-job-$(date %Y%m%d%H%M) \ --driver-memory 4g \ --executor-memory 8g \ --executor-cores 4 \ --num-executors 8 \ --conf spark.sql.catalogImplementationhive \ --conf spark.sql.hive.metastore.version1.2.1 \ --conf spark.sql.hive.metastore.jars/opt/hive/lib/* \ --conf spark.sql.warehouse.dir/user/hive/warehouse \ --files $SPARK_HOME/conf/hive-site.xml \ --class com.example.MyJob \ /data/jobs/my-job.jar $--deploy-mode client是我在调试期的默认选择driver 就在提交机上日志直接打屏出问题看得见。上线再换 cluster 模式。--num-executors和--executor-cores要结合队列资源算不是越大越好executor 数量超过队列能给的容器数任务会一直卡在等待调度看起来像是卡死。--files那行是为了让 executor 也能读到 hive-site.xml集群模式下漏了这行是最常见的「本地能跑、上线就挂」。最后一个技巧验证元数据是不是真通了别只看show databases那个可能读的是缓存。建一张临时表写一条数据进去再从完全独立的 Hive 客户端查一次两边都能看到才算真的打通。这一步多花两分钟能省掉后面调试半天。从那以后我每装一套 Spark不管多急第五章那五条和第六章这张表都强制走一遍尤其是「仓库路径两端一致」这条被坑过一次就再也不敢跳。希望帮到你。本文还有配套的精品资源点击获取
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。