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”中):错误=2,没有这样的文件或目录

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

在尝试了三天的 Hive 集成测试之后,我想我会问社区:

  1. 你如何推荐我集成测试 Hive 工作?
  2. 您是否有一个有效的 JUnit 示例,用于使用内存中的 HDFS、MR 和 Hive 实例集成测试 Hive 作业?

我看过的其他资源:

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

4

6 回答 6

13

理想情况下,可以使用LocalJobRunner而不是诉诸小型集群测试来测试配置单元查询。但是,由于HIVE-3816运行 hivemapred.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:///

于 2014-02-16T21:48:23.110 回答
6

我来找一个很好的工具:HiveRunner。它是 jUnit 之上的框架,用于测试 hive 脚本。在引擎盖下,它启动了一个独立的 HiveServer,内存中的 HSQL 作为元存储。

于 2014-08-29T19:31:53.307 回答
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,假设 severla win utils for linux 可以通过。

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

于 2018-01-23T18:46:56.023 回答
1

Hive 仅在存储 Hive 表的元信息的 RDBMS 可以在本地或独立服务器上运行的意义上支持嵌入式模式(有关详细信息,请参阅https://cwiki.apache.org/confluence/display/Hive/HiveClient)。此外,hive 及其附带的数据库只是一系列 MapReduce 作业的编排器,这也需要运行 Hadoop 框架。

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

于 2013-11-01T22:16:16.110 回答
1

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

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

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

确定本地任务(通常是 mapjoin 哈希表生成阶段)是否在单独的 JVM 中运行(真正推荐)。避免产生新 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 等)来解决潜在的内存问题。

于 2016-10-18T18:49:50.000 回答
0

另一个 Hive JUnit 运行器位于https://github.com/edwardcapriolo/hive_test

于 2015-04-05T20:00:51.637 回答