Hive 开发人员常见问题解答

Maven

运行测试并使用适当的-Dtest生成输出文件。Hive 使用Maven作为其构建工具。 0.13 之前的版本使用的是 Ant。

Developing

如何移动某些文件?

发布补丁以进行测试,只需添加和删除即可。 SVN 不会理解这些补丁实际上是移动的,因此,您应该按 Sequences 实际上上传以下内容,以便最后一次上传是用于测试目的的补丁:

  • 仅具有不可更改的提交的补丁,例如 HIVE-XXX-commit.patch

  • 进行移动 HIVE-XXX-moves.sh 所需的命令脚本

  • 用于测试目的的修补程序 HIVE-XXX.patch

该脚本应该是一组svn mv命令以及查找/替换所需的任何perl命令。例如:

$ svn mv MyCLass.java MyClass.java
$ perl -i -pe 's<at:var at:name="MyCLass" />MyClass@g' MyClass.java

如何添加新的 MiniDriver 测试?

有关 MiniDriver 和 Beeline 测试的信息,请参见MiniDriver Tests

有关如何运行测试的常见问题解答,请参见下面的HiveDeveloperFAQ#Testing

Building

Maven settings

您可能必须在某些系统上设置以下 Maven 选项才能进行构建:将 MAVEN_OPTS 设置为“ -Xmx2g -XX:MaxPermSize = 256M”。

如何构建所有来源?

Maven 的设置方式在 master 分支和 branch-1 之间有所不同。在 branch-1 中,由于同时支持 Hadoop 1.x 和 2.x,因此您需要指定是否要针对 Hadoop 1.x 或 2.x 构建 Hive。这是通过 Maven 配置文件完成的。每个 Hadoop 版本hadoop-1hadoop-2都有一个配置文件。对于大多数 Maven 操作,需要指定这些配置文件之一,否则构建将失败。

在 master 中,仅支持 Hadoop 2.x,因此无需为大多数构建操作指定 Maven 配置文件。

In master:

mvn clean install -DskipTests
cd itests 
mvn clean install -DskipTests

在分支 1 中,MVN:

mvn clean install -DskipTests -Phadoop-2
cd itests 
mvn clean install -DskipTests -Phadoop-2

要针对 Hadoop 1.x 进行构建,请将以上内容切换为-Phadoop-1

在此页面的其余部分,我们将假定为主用户,不显示配置文件。但是,如果您在使用 Branch-1,请记住,您需要添加适当的配置文件。

如何导入 Eclipse?

生成并生成Eclipse个文件(保守方法)。

对于主服务器-不使用本地 Maven 存储库:

$ mkdir workspace
$ cd workspace
$ git clone https://github.com/apache/hive.git
$ cd hive
$ mvn clean package eclipse:clean eclipse:eclipse -Pitests -DskipTests -DdownloadSources -DdownloadJavadocs

注意: package 目标的存在对于成功生成项目文件至关重要。

注意:建议在生成项目文件之前擦除或重命名本地 m2 存储库的* org/apache/hive *子树;并且您可能想要在执行后检查它是否不包含任何文件-如果它确实包含某些内容,则您的项目文件可能并不完全独立于下载的 Maven 工件。

这将适用于所有分支机构;但是请记住,在这种情况下,您要将 Hive 工件安装到本地存储库中。

$ mkdir workspace
$ cd workspace
$ git clone https://github.com/apache/hive.git
$ cd hive
$ mvn clean install -DskipTests
$ mvn eclipse:clean
$ mvn eclipse:eclipse -DdownloadSources -DdownloadJavadocs
$ cd itests
$ mvn clean install -DskipTests
$ mvn eclipse:clean
$ mvn eclipse:eclipse -DdownloadSources -DdownloadJavadocs

在 Eclipse 中,在偏好设置-> Java->构建路径->Classpath 变量中将 M2_REPO 定义为:

Mac Example

/Users/$USER/.m2/repository

Linux Example

/home/$USER/.m2/repository

Windows Example

C:/users/$USER/.m2/repository

然后导入工作区。如果您收到有关 Beeline 和 CLI 的“限制使用 signal”的错误,请遵循these instructions

请注意,如果将 Hive git 基本目录用作 Eclipse 工作区,则它不会选择正确的项目名称(例如,选择“ ant”而不是“ hive-ant”)。因此,建议将工作空间目录从 git 目录上移至上一个。例如,workspaces/* hive-workspace / hive ,其中 hive-workspace 是 Eclipse 工作区, hive *是 git 基本目录。

如何生成 tarball?

mvn clean package -DskipTests -Pdist

然后它将位于包装/目标/目录中。

如何生成 protobuf 代码?

cd ql
mvn clean install -DskipTests -Pprotobuf

如何生成 Thrift 代码?

mvn clean install -Pthriftif -DskipTests -Dthrift.home=/usr/local

更改后如何运行 findbug?

mvn site -Pfindbugs

注意:从 Hive 1.1.0 开始可用(请参阅HIVE-8327)。

如何编译 ODBC?

cd odbc
mvn compile -Podbc -Dthrift.home=/usr/local -Dboost.home=/usr/local

如何将 Hive 工件发布到本地 Maven 存储库?

mvn clean install -DskipTests
cd itests 
mvn clean install -DskipTests

Testing

有关一般信息,请参阅《开发人员指南》中的单元测试和调试

如何在补丁上运行预提交测试?

将文件上传到 JIRA 故障单时,将自动触发 Hive 预提交测试:

  • 将补丁文件附加到 JIRA 票证上:在票证的“更多”选项卡中,选择“附加文件”,然后使用“选择文件”上载文件,然后添加描述性 Comments。

  • 将补丁放入审核队列:单击“提交补丁”按钮。按钮名称将更改为“取消补丁程序”,并且票证状态将更改为“可用补丁程序”。

有关更多详细信息,请参见Hive PreCommit 补丁测试

如何在同一补丁程序上重新运行预提交测试?

对于补丁更新,我们的惯例是将它们编号为 HIVE-1856.1.patch,HIVE-1856.2.patch 等。然后,在上载新补丁时,再次单击“提交补丁”按钮;这样可以确保它重新进入审核队列。

如何运行单个测试?

ITests

请注意,itests 目录中的任何测试都需要从 itests 目录中执行。由于技术原因,pom 与父项目断开了连接。

单项测试班:

mvn test -Dtest=ClassName

单一测试方法:

mvn test -Dtest=ClassName#methodName

请注意,还可以将模式提供给-Dtests,以运行与该模式匹配的多个测试:

mvn test -Dtest='org.apache.hive.beeline.*'

有关更多用法,请参见Maven Surefire 插件的文档。

如何运行所有单元测试?

mvn test 
cd itests 
mvn test

请注意,您需要预先构建和安装 jars:

mvn clean install -DskipTests 
cd itests 
mvn clean install -DskipTests

除少数几个测试外,我如何运行所有单元测试?

与运行所有测试类似,但是定义 test.excludes.additional 以指定要从测试运行中排除的测试/模式。例如,以下将运行除 CliDriver 测试以外的所有测试:

cd itests 
mvn test -Dtest.excludes.additional='**/Test*CliDriver.java'

如何运行 Client 端阳性/Client 端阴性单元测试?

以下所有条件均要求您先前已运行ant package

运行 Client 端阳性测试

cd itests/qtest
mvn test -Dtest=TestCliDriver

运行单个 Client 端阴性测试 alter1.q

cd itests/qtest
mvn test -Dtest=TestNegativeCliDriver -Dqfile=alter1.q

运行与正则表达式匹配的所有 Client 端肯定测试,例如 partition_wise_fileformat 测试

cd itests/qtest
mvn test -Dtest=TestCliDriver -Dqfile_regex=partition_wise_fileformat.* 

# Alternatively, you can specify comma separated list with "-Dqfile" argument
mvn test -Dtest=TestMiniLlapLocalCliDriver -Dqfile='vectorization_0.q,vectorization_17.q,vectorization_8.q'

要运行一个 contrib 测试 alter1.q 并覆盖结果文件

cd itests/qtest
mvn test -Dtest=TestContribCliDriver -Dqfile=alter1.q -Dtest.output.overwrite=true

如何远程调试 qtest?

cd itests/qtest
mvn -Dmaven.surefire.debug="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 -Xnoagent -Djava.compiler=NONE" test -Dtest=TestCliDriver -Dqfile=<test>.q

测试时如何修改初始化脚本?

Hive 2.0 中添加了跳过初始化脚本或提供自定义初始化脚本的选项(请参见HIVE-11538)。

要跳过初始化:

mvn test -Dtest=TestCliDriver -Phadoop-2 -Dqfile=test_to_run.q  -DinitScript=

要提供自定义脚本:

mvn test -Dtest=TestCliDriver -Phadoop-2 -Dtest.output.overwrite=true -Dqfile=test_to_run.q  -DinitScript=custom_script.sql

如何更新 CliDriver 测试用例的输出?

cd itests/qtest
mvn test -Dtest=TestCliDriver -Dqfile=alter1.q -Dtest.output.overwrite=true

如何更新许多测试用例的结果?

假设您有一个像下面这样的文件,您想要为其重新生成输出文件。可以通过复制预提交测试的输出来创建这样的文件。

head -2 /tmp/failed-TestCliDriver-file-tests
org.apache.hadoop.hive.cli.TestCliDriver.testCliDriver_allcolref_in_udf
org.apache.hadoop.hive.cli.TestCliDriver.testCliDriver_annotate_stats_join

您可以使用以下命令以 20 个为单位重新生成所有这些输出文件

egrep 'TestCliDriver' /tmp/failed-TestCliDriver-file-tests | perl -pe 's@.*testCliDriver_@@g' | awk '{print $1 ".q"}' | xargs -n 30 | perl -pe 's@ @,@g' | xargs -I{} mvn test -Dtest=TestCliDriver -Dtest.output.overwrite=true -Dqfile={}

要使用多个驱动程序从预提交结果的输出中执行相同的操作,可以执行

import re
from itertools import groupby
s = """
org.apache.hadoop.hive.cli.TestBeeLineDriver.testCliDriver[drop_with_concurrency] (batchId=231)
org.apache.hadoop.hive.cli.TestCliDriver.testCliDriver[comments] (batchId=35)
org.apache.hadoop.hive.cli.TestMiniLlapLocalCliDriver.testCliDriver[vector_if_expr] (batchId=141)
"""
PAT = re.compile("org.apache.hadoop.hive.cli.([^\.]*).*\[([^\]]*).*")
l = [PAT.match(x.strip()) for x in s.split("\n") if x.strip()]
for driver,q in groupby(sorted([a.groups() for a in l if a]), key=lambda a:a[0]):
	print """mvn clean test -Dtest=%s '-Dqfile=%s' -Dtest.output.overwrite=true""" % (driver, ",".join(["%s.q" % a[1] for a in q]))

测试的日志输出在哪里?

日志放置在几个位置:

From the root of the source tree: find . -name hive.log
/tmp/$USER/ (Linux) or $TMPDIR/$USER/ (MacOS)

有关日志文件(包括备用配置)的详细信息,请参见Hive Logging

如何添加测试用例?

首先,将测试用例添加到 qfile 测试套件中:

  • 将测试复制到ql/src/test/queries/clientpositive/<filename>.q(如果是否定测试,则返回/clientnegative)下的新文件。

  • 如果新测试创建任何表,视图,函数等,请确保名称在测试中唯一。例如,在测试文件foo.qfoo_t1中命名一个表,而不是t1。这将有助于减少测试运行中的松懈感,因为 Jenkins 将运行测试和批处理,并且当前在运行每个 q 文件后它不会恢复到以前的状态。

    • 如果与文件系统发生任何交互,请使用唯一的文件夹进行测试,以避免与其他测试发生冲突。
  • <filename.q>itests/src/test/resources/testconfiguration.properties添加到适当的变量(例如minimr.query.files)。

接下来,第一次运行测试用例时,生成金色(输出)文件:

  • 从顶级 Hive 目录编译 Hive 源:
mvn clean install -DskipTests
  • 编译 itest:
cd itests
mvn clean install -DskipTests
  • 运行测试并使用适当的-Dtest(例如TestCliDriver;有关其他测试套件的名称,请参见itests/qtest/pom.xml)生成输出文件:
cd qtest
mvn test -Dtest=TestCliDriver -Dqfile=<filename>.q -Dtest.output.overwrite=true
  • 将您的输出文件添加到ql/src/test/results/clientpositive/<filename>.q.out(如果是阴性测试,则添加到/clientnegative)。

通过上述步骤,您可以创建一个补丁拥有.java文件,.q文件和.q.out文件。

{#HiveDeveloperFAQ-Whyisn'ttheitestspomconnectedtotherootpom?}为什么 itests pom 没有连接到 root pom?

连接它会很棒,但是会使得在本地使用 mvn test 更加困难。最好的选择是利用故障安全插件进行集成测试。但是它需要一些不同的设置,并且现在很难使用....如果您想尝试一下,请 continue。

通过启用 -Pitests (HIVE-13490),可以将所有 itest 子项目附加到主项目。

使用它有很多利弊,它是作为配置文件引入的,目的是清楚地说明集成测试已附加到主项目中。

好的一面是,您可以自由使用 -Pitests 从根项目运行集成测试,而无需 mvn install

mvn test -q -Pitests -Dtest=TestCliDriver -Dqtest=sample2.q

不利的一面是,简单的 mvn 测试-Pitests 将开始执行所有集成测试。

为什么在 MiniDFSCluster 中测试失败并显示 NullPointerException?

如果任何测试失败并显示以下错误,则表明您的 umask 设置不正确。它应该设置为 0022.

java.lang.NullPointerException: null
    at org.apache.hadoop.hdfs.MiniDFSCluster.startDataNodes(MiniDFSCluster.java:426)
    at org.apache.hadoop.hdfs.MiniDFSCluster.<init>(MiniDFSCluster.java:284)
    at org.apache.hadoop.hdfs.MiniDFSCluster.<init>(MiniDFSCluster.java:124)

为什么 Spark 单元测试失败并出现 SecurityException?

如果在单元测试中出现以下错误:

2016-01-07T09:51:49,365 ERROR [Driver[]]: spark.SparkContext (Logging.scala:logError(96)) - Error initializing SparkContext.
java.lang.SecurityException: class "javax.servlet.FilterRegistration"'s signer information does not match signer information of other classes in the same package

发生这种情况是因为相同类“ javax.servlet:servlet-api”和“ org.eclipse.jetty.orbit:javax-servlet”的两个冲突版本。 Spark 需要 eclipse 版本,但是大多数工具(包括 Hadoop 和 Jetty)都依赖于 Javax。为避免此问题,我们需要在出现的所有地方都排除 javax 版本。幸运的是,maven 有一个工具可以做到这一点:

mvn dependency:tree -Dverbose

打印出依赖关系树。转到每个单元测试失败的目录,并在依赖树中搜索“ javax.servlet:servlet-api”,并使用 pom.xml 中的排除项将其删除。有关示例,请参见HIVE-12783

Debugging

如何在 Eclipse 中调试单个测试?

您可以先确保已构建 Eclipse 文件并将项目导入到 Eclipse 中,然后按Eclipse调试单个 JUnit 测试,如here所述。然后设置一个或多个断点,突出显示要调试到的 JUnit 测试方法的方法名称,然后执行Run->Debug

调试这些测试的另一种有用方法是附加一个远程调试器。运行测试时,请通过传递“ -Dmaven.surefire.debug”来启用 surefire 的调试模式。有关如何为 surefire 开启调试的其他详细信息,请参见here。现在,当您运行测试时,它将 await 并显示类似以下的消息

Listening for transport dt_socket at address: 5005

请注意,这假设您仍在使用默认端口 5005 来确保安全。否则,您可能会看到其他端口。看到此消息后,在 Eclipse 中右键单击要调试的项目,转到“调试方式->调试配置->远程 Java 应用程序”,然后单击最左上角的“”符号。这将弹出一个对话框。确保主机为“ localhost”,端口为“ 5005”。开始调试之前,请确保已在代码中设置了适当的调试断点。准备就绪后,点击“调试”。现在,如果您返回到终端,您应该看到测试正在运行,并且测试将在您设置用于调试的断点处停止。

如何在 Hive 中调试查询?

您还可以通过附加远程调试器在 Hive 中交互式地调试查询。为此,请使用“ --debug”选项启动Beeline

$ beeline --debug
Listening for transport dt_socket at address: 8000

看到此消息后,在 Eclipse 中右键单击要调试的项目,转到“调试方式->调试配置->远程 Java 应用程序”,然后单击最左上角的“”符号。这将弹出一个对话框。确保主机是运行 Beeline CLI 的主机,并且端口为“ 8000”。开始调试之前,请确保已在代码中设置了适当的调试断点。准备就绪后,点击“调试”。远程调试器应连接到 Beeline 并 continue。

$ beeline --debug
Listening for transport dt_socket at address: 8000
Beeline version 1.2.0 by Apache Hive
beeline>

此时,请正常运行查询,查询应在您设置的断点处停止,以便您可以开始调试。

如果查询是不启动 MapReduce 作业的简单访存查询,则此方法应该很好用。如果查询以分布式模式运行,则调试起来将非常困难。因此,建议以“本地”模式运行以进行调试。为了在本地模式下运行 Hive,请执行以下操作:

MRv1:

SET mapred.job.tracker=local

MRv2 (YARN):

SET mapreduce.framework.name=local

此时,如前所述连接远程调试器以开始调试查询。