简介该资源为 Spark 2.3.0 与 Hadoop 2.x 兼容的精简发行包去除了内置 Hive JAR面向已拥有独立 Hive 集群、希望借助 Spark 计算能力处理 Hive 数据的大数据开发者与运维人员。包内共 867 个文件以 235 个 py、187 个 scala、125 个 java 源码及 109 个 jar 依赖为主辅以 sh、cmd 启动脚本与 template、json 等配置样例压缩包约 127.77MB目录结构完整便于按模块查阅与二次配置。已有 660 人学习下载。资源核心价值在于演示无 Hive JAR 环境下通过 spark.sql.hive.metastore.uris 对接 Hive 元数据、实现 Hive on Spark 的集成思路读者可据此理解 Spark SQL 访问 Hive 表的配置要点与依赖取舍适合需要精简部署、提升系统灵活性的中高级用户参考。1. 从一台跑不动 Hive 的旧集群说起spark-2.3.0-bin-hadoop2-without-hive 到底装给谁上周帮一个做离线数仓的朋友收拾一台老节点机器上 Hadoop 2.x 跑得好好的Hive 也能起但一提交hive on spark任务就卡在Spark context初始化日志里翻来覆去就是 jar 冲突和NoSuchMethodError。他一开始以为是内存不够加了两轮 executor memory问题照旧。真正的原因很朴素他下的是带 hive 的 Spark 包Hive 自己也带一套 Spark 相关依赖两边版本一撞玄学问题就来了。这次要装的spark-2.3.0-bin-hadoop2-without-hive就是为这种场景准备的——Hadoop 2.x 环境、要用 Hive 作为 SQL 入口、但不想让 Spark 发行包自带的那套 Hive jar 掺和进来。它适合还在维护 Hadoop 2 系集群、需要把hive on spark跑通的老项目维护者也适合刚接手一套历史环境、被依赖冲突折磨过的开发者。装不好会怎样轻则任务提交后一直ACCEPTED不动重则 HiveServer2 直接起不来排查成本比装环境本身高得多。2. 装前把版本和环境列清Hadoop 2 系下的依赖取舍2.1 为什么选 without-hive 这个包Spark 官方发行包按是否内置 Hive 分成两类。带 hive 的包会把 Hive 的 metastore 客户端、execution 相关 jar 一起打进去好处是开箱即用坏处是当你的 Hive 版本和 Spark 内置的 Hive 版本对不上时类加载顺序会变成一场赌博。without-hive的包把这块留空由外部 Hive 提供等于把版本决定权交回给你。我一般会先确认三件事集群 Hadoop 是 2.x 哪个小版本、Hive 是 1.x 还是 2.x、JDK 是 7 还是 8。这套组合决定了后面SPARK_HOME下 jar 的取舍也决定了hive on spark能不能顺利握手。组件建议版本说明Hadoop2.6 / 2.7包名里的 hadoop2 对应这一系Spark2.3.0本文安装对象Hive1.2.x与 Spark 2.3 搭配较稳JDK1.82.3.0 对 JDK 8 支持最好Scala2.112.3.0 默认编译版本2.2 环境预检别等解压完才发现 JDK 不对装之前先做一轮预检比装完再回滚省事得多。下面几条命令我每次都会在目标节点上跑一遍确认基础环境没有暗坑。# 确认 JDK 版本Spark 2.3.0 建议 1.8 java -version 21 | head -n 1 # 确认 Hadoop 是否在 PATH 中以及版本 hadoop version | head -n 1 # 确认 Hive 客户端可用 hive --version # 查看当前用户和 HOME后面配环境变量要用 whoami echo $HOMEjava -version输出里如果是1.7.x先别急着往下走Spark 2.3.0 在 JDK 7 上虽然能起但部分算子会触发兼容问题常见做法是统一到 JDK 8。hadoop version用来核对是不是 2.x如果输出是 3.x这个包里的 hadoop2 依赖不一定对得上需要另找对应发行包。hive --version确认 Hive 客户端存在因为 without-hive 包要靠外部 Hive 提供 metastore 连接能力。2.3 目录规划安装路径别带空格和中文我习惯把这类组件统一放在/opt/bigdata/下按组件名加版本号建目录方便以后多版本共存。路径里不要出现空格、中文、特殊符号否则后面写spark-defaults.conf时容易出转义问题。# 建立统一安装根目录 sudo mkdir -p /opt/bigdata sudo chown -R $(whoami):$(whoami) /opt/bigdata # 进入目录准备解压 cd /opt/bigdatachown这一步是为了避免后面解压、写配置时反复 sudo权限问题在分布式环境里是最容易被忽略的坑之一。目录建好后把下载好的spark-2.3.0-bin-hadoop2-without-hive.tgz放到这个目录下下一章开始解压和配置。3. 解压与基础配置SPARK_HOME 和三个关键配置文件3.1 解压并建立软链接拿到压缩包后先校验完整性再解压。软链接的作用是让后续所有配置都指向一个固定路径将来换版本只改链接不用动一堆脚本。cd /opt/bigdata # 校验压缩包完整性避免传输损坏 tar -tzf spark-2.3.0-bin-hadoop2-without-hive.tgz /dev/null echo archive ok # 解压 tar -xzf spark-2.3.0-bin-hadoop2-without-hive.tgz # 建立软链接固定入口路径 ln -s /opt/bigdata/spark-2.3.0-bin-hadoop2-without-hive /opt/bigdata/sparktar -tzf只做列表校验不解压能提前发现包是否损坏。解压后目录名很长软链接spark让后面SPARK_HOME/opt/bigdata/spark保持稳定。如果机器上已经有旧版本 Spark先确认软链接指向别直接覆盖多版本共存时用ln -sfn切换更稳妥。3.2 配置 spark-env.sh把 JDK、Hadoop 和内存钉死conf/spark-env.sh是 Spark 启动时读取的环境脚本模板文件是spark-env.sh.template。这里要写清 JDK 路径、Hadoop 配置目录、master 相关参数。without-hive 包不需要在这里指定 HiveHive 侧通过hive-site.xml反向指向 Spark。cd /opt/bigdata/spark/conf cp spark-env.sh.template spark-env.sh然后在spark-env.sh里加入以下内容# JDK 路径按实际安装位置调整 export JAVA_HOME/usr/lib/jvm/java-1.8.0 # Hadoop 配置目录让 Spark 能读到 HDFS 相关配置 export HADOOP_CONF_DIR/opt/bigdata/hadoop/etc/hadoop # Spark 主节点地址standalone 模式下使用 export SPARK_MASTER_HOST127.0.0.1 export SPARK_MASTER_PORT7077 # 驱动内存提交任务时也可覆盖 export SPARK_DRIVER_MEMORY2gJAVA_HOME必须指向 JDK 8 的实际路径写错会导致JAVA_HOME is not set直接退出。HADOOP_CONF_DIR是让 Spark 读取core-site.xml、hdfs-site.xml的关键不配的话访问 HDFS 会报No FileSystem for scheme: hdfs。SPARK_MASTER_HOST在单机或伪分布式下写本机地址即可真集群要写 master 节点主机名。SPARK_DRIVER_MEMORY给个保守值后面按任务调。3.3 配置 spark-defaults.confhistory server 和序列化spark-defaults.conf管的是提交任务时的默认参数。老集群上我一般先把 history server 打开方便事后查任务黑匣子再把序列化方式定下来。cd /opt/bigdata/spark/conf cp spark-defaults.conf.template spark-defaults.conf写入以下配置# 开启事件日志供 history server 读取 spark.eventLog.enabled true spark.eventLog.dir hdfs:///spark-history # history server 地址 spark.history.fs.logDirectory hdfs:///spark-history spark.history.ui.port 18080 # 序列化方式Kryo 在多数场景下更省内存 spark.serializer org.apache.spark.serializer.KryoSerializer # 动态资源分配按需开启老集群建议先关 spark.dynamicAllocation.enabled falsespark.eventLog.dir指向 HDFS 目录需要提前建好否则 history server 起不来。spark.serializer换成 Kryo 是常见做法但要注意自定义类需要注册否则序列化会退化成 Java 序列化。spark.dynamicAllocation.enabled在资源紧张的老集群上容易引发 executor 频繁上下线先关掉观察一段时间更稳。3.4 配置 slaves 与日志级别conf/slaves在 standalone 模式下指定 worker 节点单机就写本机。日志级别通过log4j.properties调整默认 INFO 在排查时噪音太大。cd /opt/bigdata/spark/conf cp slaves.template slaves echo 127.0.0.1 slaves cp log4j.properties.template log4j.properties sed -i s/log4j.rootCategoryINFO/log4j.rootCategoryWARN/ log4j.propertiesslaves文件在 standalone 集群里决定 worker 分布伪分布式写本机即可。日志级别调到 WARN 能压掉大量心跳和调度日志真出问题时再临时调回 INFO这个习惯能省不少翻日志的时间。4. 打通 hive on sparkHive 侧配置和 jar 放置4.1 在 hive-site.xml 中指定 Spark 引擎hive on spark的核心是让 Hive 知道用 Spark 作为执行引擎并且能找到 Spark 的 jar。在 Hive 的conf/hive-site.xml里加入以下属性property namehive.execution.engine/name valuespark/value /property property namespark.master/name valuespark://127.0.0.1:7077/value /property property namespark.home/name value/opt/bigdata/spark/value /property property namespark.executor.memory/name value2g/value /property property namespark.executor.cores/name value2/value /property property namespark.driver.memory/name value2g/value /propertyhive.execution.engine设为spark是开关不设就还是 MR。spark.master要和spark-env.sh里的 master 地址一致写成spark://前缀不是yarn。spark.home指向软链接路径Hive 会从这里加载 Spark 的 jar。spark.executor.memory和spark.executor.cores按节点实际资源给老集群别贪大executor 内存超过容器限制会被 kill。4.2 把 Spark 的 jar 放进 Hive 的 auxlibwithout-hive 包本身不带 Hive 依赖反过来 Hive 需要 Spark 的 jar 才能把任务交给 Spark 执行。常见做法是把 Spark 的 jars 目录整体链接或复制到 Hive 的auxlib下。# 进入 Hive 的 auxlib 目录 cd /opt/bigdata/hive/auxlib # 用软链接方式引入 Spark jars避免重复占用空间 ln -s /opt/bigdata/spark/jars/* . # 确认关键 jar 存在 ls | grep -E spark-core|spark-sql|spark-catalyst | head软链接比复制更省空间也方便 Spark 升级后自动生效。spark-core、spark-sql、spark-catalyst这几个是必须能看到的缺了会在提交任务时报ClassNotFoundException。如果 Hive 版本较老可能还需要把scala-library对应版本一并放进去注意别和 Hive 自带的 Scala 版本冲突。4.3 验证 Spark 自身能起在动 Hive 之前先确认 Spark 自己能正常启动把问题范围缩小。启动 standalone master 和 worker# 启动 master /opt/bigdata/spark/sbin/start-master.sh # 启动 worker /opt/bigdata/spark/sbin/start-slave.sh spark://127.0.0.1:7077 # 查看进程 jps | grep -E Master|Workerjps能看到Master和Worker进程说明 standalone 模式起来了。如果只有 Master 没有 Worker检查slaves文件和 worker 启动脚本的 master 地址是否一致。这一步过了再进 Hive 侧验证出问题就能定位到是 Hive 配置还是 Spark 本身。5. 避坑与排查hive on spark 最常见的四类翻车5.1 提交任务一直 ACCEPTED 不动现象Hive 里执行一条简单 SQL任务状态长时间停在ACCEPTED日志没有明显报错。原因通常是 Spark 的 executor 没有真正分配到资源或者spark.master指向的 master 上没有可用 worker。解决先用jps确认 Worker 进程在再看 Spark master UI 的 8080 端口是否有 alive worker如果 worker 在但资源为 0检查spark-env.sh里的SPARK_WORKER_CORES和SPARK_WORKER_MEMORY是否被设成 0 或过小。5.2 NoSuchMethodError 或类冲突现象任务提交后抛NoSuchMethodError堆栈指向 Hive 或 Spark 的某个类。原因多半是 Hive 的auxlib里同时存在多个版本的同一 jar或者 Spark 包和 Hive 自带依赖版本不一致。解决清理auxlib下重复 jar只保留一套确认用的是 without-hive 包没有再混入带 hive 的 Spark jar必要时用ls -l看软链接是否指向了错误版本。5.3 HiveServer2 启动失败现象改完hive-site.xml后 HiveServer2 起不来日志报ClassNotFoundException或NoClassDefFoundError。原因通常是spark.home路径写错或者auxlib下缺少 Spark 的关键 jar。解决核对spark.home是否指向真实存在的目录用ls /opt/bigdata/spark/jars | wc -l确认 jar 数量正常再检查auxlib软链接是否失效。5.4 内存溢出与容器被 kill现象任务跑到一半 executor 丢失日志出现Container killed或OutOfMemoryError。原因是spark.executor.memory给得超过节点实际可用内存或者 driver 内存不足。解决把 executor 内存降到节点内存的 60% 左右driver 内存单独调老集群上先关掉动态资源分配避免 executor 频繁申请释放放大问题。6. 装完怎么验证三条命令确认 hive on spark 真的跑通装完不验证等于没装。我一般按从下到上的顺序验三层Spark 自身、Hive 连 Spark、SQL 真正跑在 Spark 上。第一层在 4.3 已经做过这里重点看后两层。先确认 Hive 能识别到 Spark 引擎配置# 进入 Hive CLI hive # 在 Hive 中查看当前执行引擎 set hive.execution.engine;输出应该是hive.execution.enginespark。如果还是mr说明hive-site.xml没生效检查文件位置和 XML 格式常见问题是属性写在了错误的configuration外面。接着跑一条会触发 Spark 任务的 SQL用EXPLAIN看执行计划里是否出现 Spark 相关算子-- 建一张测试表并插入少量数据 CREATE TABLE IF NOT EXISTS spark_check (id INT, name STRING); INSERT INTO spark_check VALUES (1, a), (2, b); -- 查看执行计划确认走的是 Spark EXPLAIN SELECT count(*) FROM spark_check;EXPLAIN输出里如果出现SparkSubmitOperator或类似 Spark 任务节点说明 Hive 已经把执行权交给 Spark。如果还是MapReduce相关节点回到 4.1 检查hive.execution.engine是否真的写进了生效的hive-site.xml。最后看 Spark master UI 和 history server。浏览器打开http://127.0.0.1:8080看是否有 running application再打开http://127.0.0.1:18080看历史任务是否落盘。两个页面都能看到刚才那条 SQL 对应的 application才算整条链路通了。验证项命令或入口通过标准执行引擎set hive.execution.engine;输出 spark执行计划EXPLAIN SELECT ...出现 Spark 任务节点运行实例master UI 8080有对应 application历史日志history UI 18080事件日志可读有一次我在一台老节点上验证时前两步都过了但 history server 一直空白最后发现是spark.eventLog.dir指向的 HDFS 目录权限不对Spark 写不进去也不报错属于典型的静默失败。从那以后我每次装完这套环境都会强制走一遍「引擎 → 执行计划 → UI」三步少一步都不算完。希望这套流程能帮到你少在依赖冲突上耗一个下午。本文还有配套的精品资源点击获取