我正在尝试使用Hive Thrift和JDBC接口编写一个非平凡的Hive作业,而我在设置一个像样的JUnit测试时遇到了麻烦。非重要的是,我的意思是这项工作至少会产生一个MapReduce阶段,而不是只处理Metastore阶段。
测试应该启动一个Hive服务器,将一些数据加载到一个表中,在该表上运行一些非平凡的查询,并检查结果。
我根据Spring reference连接了一个Spring上下文。但是,MapReduce阶段的作业失败,抱怨没有Hadoop二进制文件存在:
java.io.IOException:无法运行程序“/ usr / bin / hadoop”(in 目录“/ Users / yoni / opower / workspace / intellij_project_root”): error = 2,没有这样的文件或目录
问题是Hive Server在内存中运行,但依赖于Hive的本地安装才能运行。为了让我的项目自成一体,我需要嵌入Hive服务,包括HDFS和MapReduce集群。我尝试使用相同的Spring方法启动Hive服务器并将其指向MiniDFSCluster和MiniMRCluster,类似于Hive QTestUtil源和{{3}中使用的模式}。但是,我无法让它发挥作用。
经过三天试图纠缠Hive集成测试后,我想我会问社区:
我看过的其他资源:
编辑: 我完全清楚,针对Hadoop集群(无论是本地还是远程),可以针对全栈Hive实例运行集成测试。如上所述,问题在于这不是有效测试Hive工作流的可行解决方案。
答案 0 :(得分:12)
理想情况下,人们可以使用LocalJobRunner
测试配置单元查询,而不是使用迷你集群测试。但是,由于HIVE-3816运行配置单元mapred.job.tracker=local
会导致调用系统上安装的配置单元CLI可执行文件(如您的问题中所述)。
在解决HIVE-3816之前,迷你集群测试是唯一的选择。下面是我针对CDH 4.4测试的hive测试的最小迷你集群设置。
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:///
答案 1 :(得分:5)
我来找一个非常好的工具:HiveRunner。 它是jUnit之上的框架,用于测试hive脚本。 在引擎盖下,它启动了一个独立的HiveServer,内存HSQL作为Metastore。
答案 2 :(得分:1)
Hive仅支持嵌入模式,因为存储Hive表的元信息的RDBMS可以在本地或独立服务器上运行(有关详细信息,请参阅https://cwiki.apache.org/confluence/display/Hive/HiveClient)。此外,带有它的附带数据库的配置单元只是一串MapReduce作业的协调器,这也需要Hadoop框架也能运行。
我建议使用具有预先配置的Hadoop堆栈http://hortonworks.com/products/hortonworks-sandbox/的虚拟机。 Hortonworks是两家领先的Hadoop分发提供商之一,因此得到了很好的支持。
答案 3 :(得分: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等)可以解决潜在的内存问题。
答案 4 :(得分:1)
我已经实施了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
答案 5 :(得分:0)
另一位Hive JUnit选手位于https://github.com/edwardcapriolo/hive_test