Hive本地调试

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zteny/article/details/79313056

虽然已经很习惯看静态代码了,但是这种方式始终很不方便,需要来来回回翻找代码不说,还得自己分析每个变量的值、和路径。因此决定花点时间让代码在IDE上跑起来,然而这个过程在Windows下十分麻烦。

你是否正在尝试,或是多次尝试失败在windows调试Hive呢?本文将从零重现笔者在搭建hive在windows下运行环境的出现的问题。带你解决本地调试的各种问题、各种坑,直接吃鸡。

一、准备

开始之前先重申一下我们的目的,我们的目的是让hive在IDE(windows)上跑起来。

  1. 如果你是mac/linux的话,相对简单一些。可以省去成吨的操作,至少我用ubuntu弄的话就很简单。
  2. 其实,如你所以Hive依赖Hadoop的MapReduce或者tez、Spark计算引擎完成计算的,那么毕竟离不到Hadoop。

    但其实你可以不需要把hadoop的环境搭起来,只要把它的发行包解压,并能让hive找到hadoop.cmd即可。

此时我们有多种方式去实现,简单可以有如下两种,对这两种我们都简单介绍一下。
1. 下载源码,导入IDE
1. 下载Apache发行码
2. 从github clone
2. 建个项目,把包引进来

hive-0.13.0以后,Hive的构建工具从Ant迁移到Maven。那不管你是下载Apache发行版本的源码包,还是从github克隆源码都是一样的,下载了之后最好能在CMD下完成构建。即是在CMD下完成如下操作将源码转成eclipse/idea项目

  • 对于Eclipse
mvn eclipse:eclipse -Phadoop-2
  • 对于Intellj
mvn idea:idea -Phadoop-2

当然,你也可以通过maven直接导入成一个maven项目

然后如果你觉得这也是挺麻烦的,那还可以直接在任意一个maven项目中引入Hive相关的包,通过相关提示加入必要的包即可。比如org.apache.hadoop:hadoop-minicluster
好了,不管你选择哪种最终都会遇到以下提及的所有问题。

扫描二维码关注公众号,回复: 4646809 查看本文章

那我们知道把Hive的CliDriver在本地跑起来,当然需要把配置为Local模式,按官方Wiki文档的说明配置即可。只不过,我们要做的远不仅仅如此。

export HIVE_OPTS=’–hiveconf mapred.job.tracker=local –hiveconf fs.default.name=file:///tmp \
–hiveconf hive.metastore.warehouse.dir=file:///tmp/warehouse \
–hiveconf javax.jdo.option.ConnectionURL=jdbc:derby:;databaseName=/tmp/metastore_db;create=true’

二、事情远没这么简单呢

如果,按着WIKI文档说的做一些配置即可的话,那我也不必写这篇文章了啦。其实问题还挺多的,接下来我会按着问题发生的顺序,一步步的解决,并把每个问题报错提示和我的解决方案一起贴出来。

2.1 winutils.exe找不到

首先是这个:

ERROR util.Shell: Failed to locate the winutils binary in the hadoop binary path
java.io.IOException: Could not locate executable null\bin\winutils.exe in the Hadoop binaries.

Exception in thread "main" java.lang.RuntimeException: java.lang.NullPointerException
    at org.apache.hadoop.hive.ql.session.SessionState.start(SessionState.java:522)
    at org.apache.hadoop.hive.ql.session.SessionState.start(SessionState.java:466)

Caused by: java.lang.NullPointerException
    at java.lang.ProcessBuilder.start(Unknown Source)
    at org.apache.hadoop.util.Shell.runCommand(Shell.java:483)

找不到winutils.exe,这个谷歌一下就能很容易得知了。详细见这里。一开始我并没有在意找不到winutils.exe的问题,而是先去找下面那个NullPointerException的问题。然后发现这里的问题是需要执行中,少了一个hadoopCMD。跟在它后面是ls -la /tmp/hive,然后我大概就能懂了。原来winutils.exe真心不是随便能不要的,到这里下载winutils.exe。然后把对应hadoop版本的winutils拿出来并把配置系统变量Path上。

2.2 系统找不到指定的文件

并在启动时加入如下参数,(当然你也能把它直接写到hive-site.xml的配置文件上)

-Dhadoop.home.dir=D:\hadoop-2.7.5\

java.io.IOException: Cannot run program "\usr\bin\hadoop.cmd" (in directory "D:\daming\workspace\hive"): CreateProcess error=2, 系统找不到指定的文件。
    at java.lang.ProcessBuilder.start(Unknown Source)
    at java.lang.Runtime.exec(Unknown Source)
    at java.lang.Runtime.exec(Unknown Source)
    at org.apache.hadoop.hive.ql.exec.mr.MapRedTask.execute(MapRedTask.java:271)
    at org.apache.hadoop.hive.ql.exec.Task.executeTask(Task.java:160)
    at org.apache.hadoop.hive.ql.exec.TaskRunner.runSequential(TaskRunner.java:88)
    at org.apache.hadoop.hive.ql.Driver.launchTask(Driver.java:1653)
    at org.apache.hadoop.hive.ql.Driver.execute(Driver.java:1412)
    at org.apache.hadoop.hive.ql.Driver.runInternal(Driver.java:1195)
    at org.apache.hadoop.hive.ql.Driver.run(Driver.java:1059)
    at org.apache.hadoop.hive.ql.Driver.run(Driver.java:1049)
    at com.watsons.hive.SemanticAnalyzerTest.main(SemanticAnalyzerTest.java:49)
Caused by: java.io.IOException: CreateProcess error=2, 系统找不到指定的文件。
    at java.lang.ProcessImpl.create(Native Method)
    at java.lang.ProcessImpl.<init>(Unknown Source)
    at java.lang.ProcessImpl.start(Unknown Source)
    ... 12 more

由于它是从HiveConf里拿hadoop.bin.path,我们知道HiveConf会读入几个配置,除了各种XML(hive-site.xml, core-site.xml,…),还整合了System.getPropertySystem.getEnv。所以你除了可以在hive-site.xml加入如下配置项,也可以直接加个JVM参数-Dhadoop.bin.path=

<property>
    <name>hadoop.bin.path</name>
    <value>D:/hadoop-2.7.5/bin/hadoop.cmd</value>
</property>

2.3 系统找不到指定的路径

到这里你以为就可以了,毕竟只是提示你找不到表而已,那大不了建个表呗。嗯,建表没问题。一直到有一天,你的SQL需要发起一个MapReduce任务了。然后它立马跟你说,找不到JAVA_HOME,此时我想你的内心立马就不能平静了。

系统找不到指定的路径。
Error: JAVA_HOME is incorrectly set.
       Please update D:\hadoop-2.7.5\conf\hadoop-env.cmd
'-Xmx512m' 不是内部或外部命令,也不是可运行的程序
或批处理文件。

WHAT!!!什么情况,JAVA_HOME,找不到吗?没JAVA_HOME,你说我是怎么运行各种各样的JavaApp呢?你可能按着它说的,在$HADOOP_HOME/conf/创建这个目录,并创建这个文件hadoop-env.cmd,把set JAVA_HOME=%JAVA_HOME%写进去。但是但是,它依然还是不行,哈哈哈。其实这个问题很容易被忽略而已,因为当你把java装在c:\Program Files时,它有个空格且没能被识别。如果是这样的话,把Java拷到一个地方即可。D:\java.tools\java,然后再hadoop-env.cmd把上面那句话改成set JAVA_HOME=D:\java.tools\java\jdk1.8.0_121

三、这样就可以了吗?

到这里,你以为就可以了吗?默默的看了一下进度条,答案很清晰,并没有

3.1 UnsatisfiedLinkError

接下来是这个问题了:

java.lang.UnsatisfiedLinkError: org.apache.hadoop.io.nativeio.NativeIO$Windows.access0(Ljava/lang/String;I)Z
...
FAILED: Execution Error, return code -101 from org.apache.hadoop.hive.ql.exec.mr.MapRedTask. org.apache.hadoop.io.nativeio.NativeIO$Windows.access0(Ljava/lang/String;I)Z

一开始没看出来这是什么问题,谷歌也很茫然。

后来我在TestCliDriver里看两行代码,才把这个问题解决了的。

HiveConf conf = new HiveConf(ExecDriver.class);
conf.setBoolVar(HiveConf.ConfVars.SUBMITVIACHILD, true);
conf.setBoolVar(HiveConf.ConfVars.SUBMITLOCALTASKVIACHILD, true);

直接这个hive-site.xml里加如下两项配置即可:

<property>
    <name>hive.exec.submitviachild</name>
    <value>true</value>
</property>

<property>
    <name>hive.exec.submit.local.task.via.child</name>
    <value>true</value>
</property>

3.2 如果还不行

那可能是提示它需要的目录权限不足,执行winutils chmod -R 777 d:/tmp/完成即可。

这要是还有问题的话,那也是我没到遇到的,请文章的评论区直接评论,我们一起来探讨咯。

四、结尾

到这里的话,其实已经完成搞定了。但总觉得日志打印有点问题,如果你也是这么觉得的话,加入这个JVM参数。-Dhive.root.logger=INFO,console,当然你可能按你的需求打到对应的日志级别即可了。

最后我还是觉得通过CliDriver的方式,还是有点慢。那么其实你可能直接写代码,直接操作Driver即可。

  • 这个过程中需要你做一些准备
    1. 如果本地没有hadoop环境,需要下载hadoop发行包,并解压。
    2. 需要安装 winutils.exe,hadoop在windows运行环境。
    3. hive-site.xml

最后的最后,把hive-site.xml文件完整的贴出来吧。

<configuration>

    <property>
        <name>mapred.job.tracker</name>
        <value>local</value>
    </property>

    <property>
        <name>fs.default.name</name>
        <value>file:///d:/tmp</value>
    </property>

    <property>
        <name>hive.metastore.warehouse.dir</name>
        <value>file:///d:/tmp/warehouse</value>
    </property>

    <property>
        <name>javax.jdo.option.ConnectionURL</name>
        <value>jdbc:derby:;databaseName=d:/tmp/metastore_db;create=true</value>
    </property>

    <property>
        <name>datanucleus.autoCreateTables</name>
        <value>True</value>
    </property>

    <property>
        <name>hadoop.bin.path</name>
        <value>D:/hadoop-2.7.5/bin/hadoop.cmd</value>
    </property>

    <property>
        <name>hive.exec.submitviachild</name>
        <value>true</value>
    </property>

    <property>
        <name>hive.exec.submit.local.task.via.child</name>
        <value>true</value>
    </property>

</configuration>

猜你喜欢

转载自blog.csdn.net/zteny/article/details/79313056