集成测试Hive作业

71
我正在尝试使用Hive Thrift和JDBC接口编写一个非平凡的Hive作业,但我在设置一个良好的JUnit测试时遇到了问题。所谓的非平凡是指该作业至少产生一个MapReduce阶段,而不仅仅处理元数据存储库。
该测试应启动一个Hive服务器,将一些数据加载到表中,在该表上运行一些非平凡查询,并检查结果。
我已经按照Spring参考连接了Spring上下文。然而,作业在MapReduce阶段失败,抱怨没有Hadoop二进制文件:

java.io.IOException: Cannot run program "/usr/bin/hadoop" (in directory "/Users/yoni/opower/workspace/intellij_project_root"): error=2, No such file or directory

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

尝试了三天来处理Hive集成测试后,我想向社区寻求帮助:

  1. 您如何推荐我集成测试Hive作业?
  2. 您是否有使用内存HDFS、MR和Hive实例进行Hive作业集成测试的可行JUnit示例?

我查看过的其他资源:

编辑: 我完全意识到针对Hadoop集群(无论是本地还是远程)进行操作可以运行全栈Hive实例的集成测试。但问题在于,这不是有效测试Hive工作流的可行解决方案。


既然它正在寻找安装位置,为什么不创建一个RAM磁盘并将其指向呢?除此之外,您将不得不开始检查源代码以了解它如何使用您提供的配置。然后,您可以编写自己的粘合剂来绕过配置,并直接运行功能。 - WeaponsGrade
2
请问您能否分享一下您最终解决方案的示例? - Gustavo Matias
我会尽快将我们的JUnit测试规则开源。 - oby1
@yoni,你能否在这里发布你最终的完整解决方案?我正处于与你相同的情况,在我将Hive JDBC客户端和下面的MiniDFSCluster代码同时运行(使用“jdbc:hive2:///” URL)进行“CREATE TABLE...”查询时,我遇到了这个问题: java.sql.SQLException: Error while processing statement: FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask - Nishant Kelkar
嗨,Nishant。很抱歉听到你遇到了麻烦。我没有完整解决方案的访问权限,但也许@oby1有。无论如何,我建议您添加一个完整的示例 - 可能是在单独的Stack Overflow问题中 - 并提供您的确切设置和完整的堆栈跟踪。 - yoni
显示剩余2条评论
6个回答

13

理想情况下,人们可以使用LocalJobRunner测试hive查询,而不是使用mini-cluster测试。然而,由于HIVE-3816的存在,运行具有mapred.job.tracker=local的hive会导致调用已安装在系统上的hive CLI可执行文件(如您的问题中所述)。

在HIVE-3816得到解决之前,小型集群测试是唯一的选择。以下是我的一个最小化的针对CDH 4.4测试的hive mini-cluster设置。

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设置为jdbc:hive2:///来使用嵌入式hiveserver2进程进行测试。


1
请问您能否提供一个更完整的例子?我的意思是,包括使用HiveInterface设置和执行一些查询的部分。非常感谢。 - Gustavo Matias
借鉴已接受的答案:从Hive 1.2.0开始,有一种替代解决方案:https://dev59.com/zGQn5IYBdhLWcg3wmH8s#40115876 - Andrey

6

我找到了一个相当不错的工具:HiveRunner。它是基于jUnit的框架,用于测试Hive脚本。在内部,它启动了一个独立的HiveServer,并使用内存中的HSQL作为元数据存储。


测试套件很棒,但我遇到了版本兼容性问题。我们被限制在hive版本2.0.0上,而版本兼容性跳跃从hive 1.2.1到2.3.3。 - Brian Olsen

2

我已经实现了HiveRunner。

https://github.com/klarna/HiveRunner

我们在Mac上进行了测试,在Windows上遇到了一些问题,但是通过以下列出的几个更改后,这个工具很好地服务了。

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

1.克隆https://github.com/steveloughran/winutils项目到计算机上的任何位置,在这个文件夹的/bin目录下添加一个新的环境变量HADOOP_HOME,不允许使用斜杠或空格。 2.克隆https://github.com/sakserv/hadoop-mini-clusters项目到计算机上的任何位置。添加一个新的环境变量HADOOP_WINDOWS_LIBS,指向该文件夹的/lib目录。同样,不允许使用斜杠或空格。 3.我还安装了Cygwin,假设有几个Linux上的Win工具可用。

这个Github请求帮助它在Windows上运行, https://github.com/klarna/HiveRunner/pull/63


1

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

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

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

确定本地任务(通常是映射联接哈希表生成阶段)是否在单独的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);
    }
  }

默认的配置值会导致调用executeInChildVM()方法,该方法实际上调用了hadoop jar。在我的测试中,其他代码路径到目前为止都可以正常工作。潜在的内存问题可能可以通过调整Java堆配置(Xmx、Xms等)来解决。

1
Hive仅支持嵌入式模式,也就是说存储Hive表元信息的关系型数据库可以在本地运行或独立服务器上运行(有关详细信息,请参见https://cwiki.apache.org/confluence/display/Hive/HiveClient)。此外,Hive及其随附的数据库只是一组MapReduce作业的编排器,需要同时运行Hadoop框架。
我建议使用预配置了Hadoop堆栈的虚拟机http://hortonworks.com/products/hortonworks-sandbox/。Hortonworks是两家领先的Hadoop发行商之一,因此得到了很好的支持。

1
谢谢你,Dmitriusan。我知道你可以安装和启动本地Hadoop集群来运行,但我正在寻找一些略微不同的东西。强大的解决方案是不需要在集成测试之外控制任何东西的解决方案。这对于HBase存在,它还需要HDFS和MapReduce服务处于活动状态,但尚未为Hive正确开发。所有的部件都在那里,只需要连接起来(而我没有时间去连接)。无论是Hortonworks、CDH还是任何其他版本的Hadoop都不应该有任何区别。 - yoni
2
你的问题自五月以来一直悬而未决,我想你所要求的解决方案可能并不存在(至少在公共领域中没有)。无论如何,因为试图帮助(并提出已经存在且应该可行的解决方案)而被投反对票是不积极的。 - Dmitriusan
明白了。你被踩是因为你的回答并没有解决问题。但如果这不足以让人踩你,那么我想我的 SO 礼仪可能有些偏差,所以感谢你纠正我。 - yoni

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接