集成测试Hive职位


71

我正在尝试使用Hive Thrift和JDBC接口编写不平凡的Hive作业,并且在设置像样的JUnit测试方面遇到困难。所谓“平凡”,是指该工作至少在一个MapReduce阶段完成,而不是仅与元存储打交道。

该测试应启动Hive服务器,将一些数据加载到表中,对该表运行一些非平凡的查询,然后检查结果。

我已经根据Spring参考连接了Spring上下文。但是,该作业在MapReduce阶段失败,抱怨说不存在Hadoop二进制文件:

java.io.IOException:无法运行程序“ / usr / bin / hadoop”(在目录“ / Users / yoni / opower / workspace / intellij_project_root”中):error = 2,没有这样的文件或目录

问题是Hive服务器正在内存中运行,但是要运行Hive则要依靠Hive的本地安装。为了使我的项目自成一体,我需要嵌入Hive服务,包括HDFS和MapReduce集群。我尝试使用相同的Spring方法启动Hive服务器,并将其指向MiniDFSClusterMiniMRCluster,类似于Hive QTestUtil源代码和HBaseTestUtility中使用的模式。但是,我无法使其正常工作。

在尝试破坏Hive集成测试三天后,我想我会问社区:

  1. 您如何建议我对Hive作业进行集成测试?
  2. 您是否有一个可用的JUnit示例,用于使用内存HDFS,MR和Hive实例集成测试Hive作业?

我看过的其他资源:

编辑:我完全知道,通过对Hadoop集群(本地或远程)进行处理,可以对全栈Hive实例运行集成测试。如上所述,问题在于这不是有效测试Hive工作流程的可行解决方案。


由于它正在寻找安装,为什么不创建一个可以指向它的RAM磁盘呢?除此之外,您必须开始检查源代码,以查看源代码如何使用您提供的配置。然后,您可以编写自己的粘连剂来绕过配置,并直接运行功能。
武器等级

2
您能否分享一下最终解决方案的示例?
古斯塔沃·马蒂亚斯

@ oby1应该具有添加支持的补丁,但我无权访问。
yoni

我将尽快为此开源我们的JUnit测试规则。
oby1 2014年

@yoni您可以在这里发布最终得到的完整解决方案吗?我处于与您完全相同的情况,并且当我运行Hive JDBC客户端,并且下面的MiniDFSCluster代码正常工作时,当我尝试同时运行两者(使用“ jdbc:hive2:///” URL)时,一个“创建表...”查询,我得到:java.sql.SQLException:处理语句时出错:FAILED:执行错误,从org.apache.hadoop.hive.ql.exec.DDLTask返回代码1
Nishant Kelkar

Answers:


13

理想情况下,人们将能够使用LocalJobRunner而不是迷你集群测试来测试配置单元查询。但是,由于HIVE-3816运行hive并mapred.job.tracker=local导致调用系统上安装的hive CLI可执行文件(如您的问题所述)。

在解决HIVE-3816之前,迷你集群测试是唯一的选择。以下是针对CDH 4.4测试的配置单元测试的最小迷你集群设置。

Configuration conf = new Configuration();

/* Build MiniDFSCluster */
MiniDFSCluster miniDFS = new MiniDFSCluster.Builder(conf).build();

/* Build MiniMR Cluster */
System.setProperty("hadoop.log.dir", "/path/to/hadoop/log/dir"); // MAPREDUCE-2785
int numTaskTrackers = 1;
int numTaskTrackerDirectories = 1;
String[] racks = null;
String[] hosts = null;
miniMR = new MiniMRCluster(numTaskTrackers, miniDFS.getFileSystem().getUri().toString(),
                           numTaskTrackerDirectories, racks, hosts, new JobConf(conf));

/* Set JobTracker URI */
System.setProperty("mapred.job.tracker", miniMR.createJobConf(new JobConf(conf)).get("mapred.job.tracker"));

无需运行单独的hiveserver或hiveserver2进程进行测试。您可以通过将jdbc连接URL设置为来对嵌入式hiveserver2进程进行测试jdbc:hive2:///


1
您能否提供一个更完整的示例?我的意思是,包括使用HiveInterface设置和执行一些查询的部分?非常感谢
Gustavo Matias 2014年

ggy带上公认的答案:从Hive 1.2.0开始,还有另一种解决方法:stackoverflow.com/a/40115876/973963
Andrey

6

我来找一个很好的工具:HiveRunner。它是jUnit之上的框架,用于测试配置单元脚本。它在后台启动了一个独立的HiveServer,并将内存中的HSQL作为元存储。


2
非常有趣的项目。似乎Hive版本有一些限制,但是我肯定会在下一个项目中研究它。目前,我将@ oby1的答案作为最佳选择,但是如果人们继续报告HiveRunner成功,我将继续进行切换。
yoni 2014年

很棒的测试套件,但是我遇到了版本兼容性问题。我们仅限于Hive 2.0.0,版本兼容性从Hive 1.2.1跃升至2.3.3。
布莱恩·奥尔森

2

我已经实现了HiveRunner。

https://github.com/klarna/HiveRunner

我们在Mac上对其进行了测试,但在Windows上遇到了一些麻烦,但是该实用工具下面列出了一些更改,效果很好。

对于Windows,这里是为了使HiveRunner在Windows环境中工作而进行的一些更改。完成这些更改后,便可以对所有Hive查询进行单元测试。

1.将位于https://github.com/steveloughran/winutils的项目克隆到计算机上的任何位置,添加一个新的环境变量HADOOP_HOME,指向该文件夹的/ bin目录。不允许使用正斜杠或空格。2.将项目https://github.com/sakserv/hadoop-mini-clusters克隆到计算机上的任何位置。添加一个新的环境变量HADOOP_WINDOWS_LIBS,指向该文件夹的/ lib目录。同样,不允许使用正斜杠或空格。3.我还安装了cygwin,假设可以通过linux使用severla win utils。

gitbub的这种功能有助于使其在Windows上运行, https://github.com/klarna/HiveRunner/pull/63


1

Hive仅在存储Hive表元信息的RDBMS可以在本地或独立服务器上运行的情况下才支持嵌入式模式(有关详细信息,请参见https://cwiki.apache.org/confluence/display/Hive/HiveClient))。此外,与之配套的数据库只是配置一串MapReduce作业的协调器,这要求Hadoop框架也要运行。

我建议使用具有预配置Hadoop堆栈http://hortonworks.com/products/hortonworks-sandbox/的虚拟机 。Hortonworks是2个领先的Hadoop发行提供商之一,因此受到了充分的支持。


1
谢谢德米特里桑。我知道您可能会安装并启动要运行的本地Hadoop集群,但是我正在寻找一些不同的东西。一种可靠的解决方案是不需要集成测试控制范围内的任何解决方案。对于HBase而言,这是存在的,它还需要启动HDFS和MapReduce服务,但尚未为Hive正确开发。零件都在那里,它们只需要连接即可(我没有时间进行连接)。无论是Hortonworks,CDH还是其他任何类型的Hadoop都没有任何区别。
yoni

2
自5月以来,您的问题一直悬而未决,我认为您没有要求的解决方案(至少在公共访问中)。无论如何,对尝试提供帮助(并建议存在的解决方案和可行的解决方案)的否决是不利的。
Dmitriusan

知道了 否决票是因为您的回答并不代表该问题的解决方案。但是,如果这不是拒绝投票的理由,那么我想我的SO礼节可能不适合这样做,所以感谢您对我的纠正。
yoni 2013年

1

我不确定自2014年2月接受答案以来发生了什么变化,但是从Hive 1.2.0开始,以下解决了OP描述的问题:

System.setProperty(HiveConf.ConfVars.SUBMITLOCALTASKVIACHILD.varname, "false");

请注意配置文档中给出的警告:

确定本地任务(通常为mapjoin哈希表生成阶段)是否在单独的JVM中运行(建议为true)。避免了产生新JVM的开销,但是可能导致内存不足的问题。

可以解决此问题,因为MapredLocalTask.java

  @Override
  public int execute(DriverContext driverContext) {
    if (conf.getBoolVar(HiveConf.ConfVars.SUBMITLOCALTASKVIACHILD)) {
      // send task off to another jvm
      return executeInChildVM(driverContext);
    } else {
      // execute in process
      return executeInProcess(driverContext);
    }
  }

默认的config值使该executeInChildVM()方法被调用,该方法从字面上调用hadoop jar。到目前为止,我的测试中已经找到了另一个代码路径。通过调整Java堆配置(Xmx,Xms等),可以解决潜在的内存问题。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.