简介:本资源为基于 hortonworks/hive-testbench 编译的 Hive 性能测试程序,面向大数据开发工程师、数据仓库从业者及需要评估 Hive 性能的测试人员。它提供了一套完整的测试用例与脚本,可模拟数据加载、查询执行等操作,帮助定位 Hive 在稳定性、资源消耗与执行效率上的瓶颈,为调优提供量化依据。压缩包共约 2000 个文件,大小 64.25MB,以 class 编译产物、log 运行日志、sql 测试脚本、ans 预期结果、tpl 模板及 jar 依赖为主,另含少量 sh 启动脚本、properties 与 xml 配置,覆盖编译、运行与结果比对全流程。已有 395 人学习下载。通过该资源,读者可获取可直接运行的测试程序与配套脚本,结合日志与预期结果对比,快速复现性能场景并分析差异,同时理解 Hive 与 Hadoop、Metastore 的协作机制,为集群调优和性能验证提供可复用的实践参考。
1. 从一次编译翻车说起:Hive 性能测试程序到底装什么
第一次在测试集群上编译 Hive 性能测试程序,我按着 README 一路mvn clean package,结果卡在依赖下载上整整四十分钟,最后抛出一堆Could not resolve dependencies。当时以为是网络问题,换了台机器重来,还是同样的报错。后来才发现,问题出在 JDK 版本和 Maven 镜像配置上——这套东西对编译环境比想象中挑剔。Hive 性能测试程序(hive-testbench)是给 Hive 做基准压测用的工具集,能生成 TPC-DS 和 TPC-H 两种标准数据集,再配合查询脚本跑出性能数据。它本身不是 Hive 的一部分,而是一个独立的编译型项目,需要你自己把源码拉下来、编译打包、上传到集群,最后才能跑测试。装不好会怎样?轻则编译失败反复重来,重则生成的测试数据格式不对,跑出来的性能数字全是错的,白白浪费集群资源。这篇文章适合两类人:一是刚接手 Hive 性能测试、需要从零搭环境的新手;二是换过几次机器、每次都要重新踩一遍编译坑的老手。下面我把整套流程拆开,从环境准备到编译打包再到验证跑通,一步步走完。
2. 编译前把环境钉死:JDK、Maven 和 Hadoop 版本怎么选
2.1 版本对照表:别让 JDK 和 Maven 互相打架
hive-testbench 的编译对版本很敏感,尤其是 JDK 和 Maven 的搭配。我一般会先确认三件事:JDK 用 8,Maven 用 3.6.x,Hadoop 客户端版本要和集群一致。JDK 9 以上会触发模块化相关的编译错误,Maven 3.8 以上对 HTTP 仓库的拦截策略变严,容易在下载依赖时直接失败。下面这张表是我在几台机器上验证过的组合,照着选基本不会翻车。
| 组件 | 推荐版本 | 最低要求 | 备注 |
|---|---|---|---|
| JDK | 1.8.0_292 | 1.8 | 必须 8,不支持 11+ |
| Maven | 3.6.3 | 3.5.0 | 3.8+ 需额外配置镜像 |
| Hadoop | 与集群一致 | 2.7.0+ | 仅需客户端依赖 |
| Hive | 与集群一致 | 1.2.0+ | 用于后续跑查询 |
| 操作系统 | CentOS 7 / Ubuntu 18.04 | 64 位 | 内核 3.10+ |
选 JDK 8 不是保守,而是 hive-testbench 里引用的部分 Hive 依赖包在编译期会调用tools.jar,这个包在 JDK 9 之后被移除,直接导致mvn package报package com.sun.tools.javac does not exist。Maven 3.6.3 是我用得最顺的版本,它对settings.xml里的镜像配置兼容性最好,不会像 3.8 那样默认阻断 HTTP 仓库。
2.2 安装 JDK 8 和 Maven 3.6.3 的具体命令
先装 JDK。我习惯用包管理器装,省得手动配环境变量。以 CentOS 为例:
# 安装 OpenJDK 8 sudo yum install -y java-1.8.0-openjdk-devel # 验证版本,确认输出是 1.8.0 java -version # 配置 JAVA_HOME,写入 profile echo 'export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk' >> ~/.bashrc echo 'export PATH=$JAVA_HOME/bin:$PATH' >> ~/.bashrc source ~/.bashrcjava-1.8.0-openjdk-devel比java-1.8.0-openjdk多出编译所需的头文件和工具,必须装 devel 版本。JAVA_HOME指向/usr/lib/jvm/java-1.8.0-openjdk,这个路径在 CentOS 上是固定的,Ubuntu 下通常是/usr/lib/jvm/java-8-openjdk-amd64,可以用update-alternatives --list java确认。
接着装 Maven。不建议用yum install maven,因为仓库里的版本往往偏新。手动下载 3.6.3 的二进制包:
# 下载 Maven 3.6.3 wget https://archive.apache.org/dist/maven/maven-3/3.6.3/binaries/apache-maven-3.6.3-bin.tar.gz # 解压到 /opt sudo tar -zxvf apache-maven-3.6.3-bin.tar.gz -C /opt/ # 配置环境变量 echo 'export MAVEN_HOME=/opt/apache-maven-3.6.3' >> ~/.bashrc echo 'export PATH=$MAVEN_HOME/bin:$PATH' >> ~/.bashrc source ~/.bashrc # 验证 mvn -versionmvn -version输出里要确认Java version: 1.8.0和Maven home: /opt/apache-maven-3.6.3两行都对。如果 Java 版本显示成 11 或 17,说明JAVA_HOME没生效,回头检查~/.bashrc里的顺序,JAVA_HOME的 export 要放在PATH之前。
2.3 配置 Maven 镜像和本地仓库
Maven 默认从中央仓库拉依赖,国内环境经常超时。我一般会在~/.m2/settings.xml里加一个镜像,同时把本地仓库指到一个空间够大的盘。这个文件默认不存在,需要手动创建:
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"> <localRepository>/data/maven-repo</localRepository> <mirrors> <mirror> <id>central-mirror</id> <name>Central Mirror</name> <url>https://maven.aliyun.com/repository/central</url> <mirrorOf>central</mirrorOf> </mirror> </mirrors> </settings>localRepository指向/data/maven-repo,是因为编译 hive-testbench 会下载几百 MB 的依赖,放在系统盘容易撑爆。mirrorOf写central表示只代理中央仓库,不会影响项目里自定义的其他仓库。改完settings.xml后,可以用mvn help:effective-settings确认配置已生效。
提示:如果公司内网有私服,把
url换成私服地址,mirrorOf写成*可以代理所有仓库,但要注意私服是否完整同步了 Hive 相关依赖。
3. 拉源码与编译打包:从 git clone 到生成 tar.gz
3.1 获取源码并切换到稳定分支
hive-testbench 的源码托管在 GitHub 上,直接 clone 即可。但要注意分支选择,master 分支有时会引入未测试的改动,我一般会切到最近一个带 tag 的稳定版本。
# 克隆仓库 git clone https://github.com/hortonworks/hive-testbench.git # 进入目录 cd hive-testbench # 查看可用分支和标签 git branch -a git tag # 切换到稳定标签,例如 hdp3 分支对应的版本 git checkout hdp3hdp3分支是适配 HDP 3.x 的稳定分支,如果你的集群是 CDH 或原生 Apache Hive,可以选master或对应分支。切换分支后,建议先看一眼pom.xml里的<hive.version>和<hadoop.version>,确认和集群版本一致。不一致的话,编译出来的测试程序可能连不上集群的 HiveServer2。
3.2 执行编译命令与关键参数说明
编译命令本身不复杂,但参数加不加,结果差别很大。我常用的命令是:
# 跳过测试,并行编译,指定 Hadoop 版本 mvn clean package -DskipTests -T 2C \ -Dhadoop.version=3.1.1 \ -Dhive.version=3.1.0clean package是先清理再打包,-DskipTests跳过单元测试,能省掉大量时间,因为测试用例会尝试连本地 Hive,没装 Hive 的机器必然失败。-T 2C表示用 2 倍 CPU 核数的线程并行编译,能明显加快速度。-Dhadoop.version和-Dhive.version是覆盖pom.xml里的默认版本,必须和集群实际版本对齐,否则生成的 jar 包在运行时可能报NoSuchMethodError。
编译过程大概持续 3 到 8 分钟,取决于机器性能和依赖下载速度。成功的话,会在target/目录下看到几个 tar.gz 包,比如hive-testbench-hdp3.tar.gz。如果编译失败,先看报错关键词:Could not resolve dependencies是镜像或网络问题,package com.sun.tools.javac does not exist是 JDK 版本不对,Failed to execute goal后面跟的通常是具体插件问题。
3.3 编译产物清单与目录结构
编译成功后,target/目录下会生成以下内容:
| 文件/目录 | 用途 |
|---|---|
| hive-testbench-hdp3.tar.gz | 完整测试工具包,含生成脚本和查询 SQL |
| hive-testbench-hdp3/ | 解压后的目录,可直接上传集群 |
| bin/ | 数据生成和查询执行的 shell 脚本 |
| ddl/ | 建表语句,TPC-DS 和 TPC-H 各一套 |
| queries/ | 标准查询 SQL,按模板编号 |
| tools/ | 辅助 jar 包,用于数据生成 |
这个 tar.gz 就是最终要上传到集群的东西。我一般会先解压看一眼bin/下的脚本,确认runSuite.sh和genData.sh都在,这两个是后续跑测试的核心入口。
4. 上传集群与配置:让测试程序连上 HiveServer2
4.1 上传解压与目录规划
编译产物在本地,要传到集群的某个节点上。我习惯放在/opt/testbench下,权限设成当前用户可读写:
# 上传 tar.gz 到集群节点 scp target/hive-testbench-hdp3.tar.gz user@cluster-node:/tmp/ # 登录集群节点后解压 ssh user@cluster-node sudo mkdir -p /opt/testbench sudo tar -zxvf /tmp/hive-testbench-hdp3.tar.gz -C /opt/testbench/ sudo chown -R $USER:$USER /opt/testbench/opt/testbench这个路径没有特殊要求,只要空间够大就行,因为生成 TPC-DS 数据会占用几十 GB。chown是为了避免后续脚本写日志时权限不足。解压后,/opt/testbench/hive-testbench-hdp3/就是工作目录。
4.2 配置 Hive 连接参数与环境变量
测试程序通过beeline或hive命令连 HiveServer2,连接信息写在脚本的环境变量里。核心是HIVE_SERVER2和HIVE_DATABASE两个变量。我一般会在工作目录下建一个env.sh,每次跑之前 source 一下:
# env.sh export HIVE_SERVER2="jdbc:hive2://hive-server-host:10000" export HIVE_DATABASE="testbench" export HADOOP_HOME="/opt/hadoop" export HIVE_HOME="/opt/hive" export PATH=$HIVE_HOME/bin:$HADOOP_HOME/bin:$PATHHIVE_SERVER2的格式是jdbc:hive2://主机:端口,端口默认 10000,如果集群改了端口要对应调整。HIVE_DATABASE是测试数据写入的库名,建议单独建一个库,不要和业务库混在一起。HADOOP_HOME和HIVE_HOME指向集群客户端的安装路径,PATH里加上 bin 目录是为了让脚本能直接调用beeline和hadoop命令。
注意:如果集群开了 Kerberos,还需要额外配置
kinit和HADOOP_OPTS,这部分不在本文范围内,但一定要在跑测试前确认认证已通过。
4.3 建库建表与数据生成脚本的调用方式
配置好环境后,先建库,再建表。建表语句在ddl/目录下,TPC-DS 和 TPC-H 各有一套:
# 建库 beeline -u $HIVE_SERVER2 -e "CREATE DATABASE IF NOT EXISTS $HIVE_DATABASE" # 建 TPC-DS 表 beeline -u $HIVE_SERVER2 -d $HIVE_DATABASE -f ddl/tpcds.sql # 生成 100GB 测试数据,并行度 10 ./bin/genData.sh --scale 100 --parallel 10genData.sh的--scale参数指定数据规模,单位是 GB,常用值有 100、300、1000。--parallel是并行执行的 map 任务数,根据集群规模调整,太小会慢,太大会挤占资源。脚本底层调用的是hadoop jar跑 MapReduce 任务,所以执行前要确保 YARN 资源充足。生成 100GB 数据大概需要 20 到 40 分钟,取决于集群负载。
5. 避坑与排查:编译和运行中最容易翻车的五个点
5.1 现象:编译卡在下载依赖,最后超时失败
原因:Maven 默认中央仓库在国内访问不稳定,或者settings.xml里的镜像没生效。解决:确认~/.m2/settings.xml存在且mirrorOf写的是central,然后执行mvn help:effective-settings看输出里有没有你的镜像地址。如果没有,检查文件路径和 XML 格式,<mirror>标签必须闭合。
5.2 现象:编译报package com.sun.tools.javac does not exist
原因:JDK 版本不是 8,tools.jar不存在。解决:java -version确认输出是 1.8,如果不是,检查JAVA_HOME和PATH的优先级。有时候系统里装了多个 JDK,/usr/bin/java指向了 11,但JAVA_HOME指向 8,Maven 会优先用JAVA_HOME,但javac可能还是走/usr/bin。用which javac确认,必要时在PATH里把$JAVA_HOME/bin放到最前面。
5.3 现象:生成的 tar.gz 解压后脚本没有执行权限
原因:tar打包时权限丢失,或者上传过程中权限被重置。解决:解压后手动加权限,chmod +x bin/*.sh。如果脚本里还调用了其他可执行文件,一并加上。我一般会在解压后直接跑一遍find . -name "*.sh" -exec chmod +x {} \;,省得逐个检查。
5.4 现象:跑genData.sh时报ClassNotFoundException
原因:HADOOP_CLASSPATH没包含测试程序的 jar 包,或者HIVE_HOME下的依赖和编译时用的版本不一致。解决:在env.sh里显式设置export HADOOP_CLASSPATH=$HIVE_HOME/lib/*:$HADOOP_CLASSPATH,确保 Hive 的依赖能被加载。如果还报错,检查pom.xml里的hive.version和集群实际版本是否一致,不一致就重新编译。
5.5 现象:数据生成到一半卡住,YARN 任务一直处于 ACCEPTED 状态
原因:集群资源不足,或者队列配置限制了并行度。解决:先看 YARN 的 ResourceManager 页面,确认可用内存和 vcore。如果资源够但任务不跑,检查--parallel是不是设得太大,超过了队列上限。我一般会先把--parallel降到 5 试跑,确认能跑通再逐步调大。另外,genData.sh默认用的队列是default,如果集群有专门的数据生成队列,需要在脚本里改-Dmapreduce.job.queuename参数。
6. 装完怎么验证跑通:用 1GB 数据做一次冒烟测试
编译和配置都完成后,别急着上 100GB 数据。我习惯先用 1GB 规模跑一次完整流程,确认从建表到查询都能走通。这一步能提前暴露 90% 的环境问题,比直接上大规模数据省时间得多。
具体做法是:先建库建表,然后用--scale 1生成最小数据集,再跑一个简单的查询看结果。命令如下:
# 建库建表 beeline -u $HIVE_SERVER2 -e "CREATE DATABASE IF NOT EXISTS testbench_smoke" beeline -u $HIVE_SERVER2 -d testbench_smoke -f ddl/tpcds.sql # 生成 1GB 数据 ./bin/genData.sh --scale 1 --parallel 2 # 跑一个 TPC-DS 查询,比如 query1 beeline -u $HIVE_SERVER2 -d testbench_smoke -f queries/tpcds/query1.sql--scale 1生成的数据量很小,通常两三分钟就能跑完。--parallel 2是为了减少资源占用,冒烟测试不需要高并行。查询能返回结果集,哪怕只有几行,就说明整条链路是通的。如果查询报错,重点看beeline输出的错误码:Error while compiling statement通常是表没建全,Error running query可能是数据没生成完整。
验证通过后,我会再检查两个细节:一是genData.sh的日志里有没有SUCCESS字样,二是beeline查询的耗时是否在合理范围内。1GB 数据的简单查询应该在 10 秒内返回,如果超过 30 秒,可能是 YARN 队列资源紧张或者 HiveServer2 负载高,需要进一步排查。
从那以后我每次编译完这套测试程序,都强制走一遍 1GB 冒烟测试,确认建表、生成、查询三步都通,再上大规模数据。这个习惯帮我省掉了好几次“编译成功但跑不起来”的尴尬。希望帮到你。
本文还有配套的精品资源,点击获取