讨论的版本为: HiveServer2 版本 : 2.3.1 + tez
由于最近在弄WEBIDE,其中在连接Hiveserver2的时候,在Hiveserver2的获取日志的方式,发现了两个坑,找了许多文献,也没有找到解决的办法。
其中一个坑,有一个同事在看到hive的BUG反馈中,看到一些类似情况,解决的。
而另外一个坑,是走了很多很多崎岖的路途,一步一步的发现出来的解决办法。
1.HIVESERVER 2 没有日志
在其他配置(启动日志配置,log4j,等等)都没有别的问题的时候,依然没有日志.
这是因为hive-site文件中设置了一个async的log配置,这个log配置,设为true的时候,无法查看到进度日志。
2.JAVA JDBC HIVESERVER2 看不到进度日志
在上一个问题解决之后,发现JAVA JDBC HIVESERVER2 拿不到进度日志,只能看到一些执行信息。
即使是将日志的级别调整到VERBOSE , 也只是获取到一些简单的进度信息。
而在命令行上执行beeline的连接方式,却有进度日志。进度日志包括 map 的数量 ,reducer的数量,以及其运行情况(KILL , SUCCEED , FAILED ...)
1.认为这个是日志输出的问题.单纯从beeline 的日志的输出跟JAVA JDBC的不一样。于是乎,将beeline的log配置和JAVA JDBC的log配置都玩了个转。没有变化。
2.通过在hive-env的文件上,添加一段开启debug的命令,开启了hiveserver2的debug之旅,刚开始就debug了tez task,慢慢的发现了一个tez progress 的一个类,
然后,JAVA JDBC 方法的时候 , 发现里面的hedaer()和 row() 返回都是空。而beeline 就都有正确的进度返回。
再往上看堆栈的信息,发现其他因素都没问题,是一个属性名字为isProgressUpdate导致JAVA JDBC的时候,返回的进度管理器是空类,beelline的时候,是tez 正确的进度类。而这个值在JAVA JDBC 的时候为false , beeline的时候为true。再往上一层层的挖后发现,这个值时tcl写过来的。于是乎就想在认证后,在连接之前,先将tclservice的对应这个值或者是kv的属性的东西,先写过去设置为true,以期能解决这个进度日志不输出的问题。最后发现,找不到入口。
3.在进行第二步后,不断的去寻找isProgressUpdate关键词相关的文献。最后发现了HIVE JDBC 2.3.1(jar)对应的Hivestament 有一个setInPlaceUpdateStream。以为找到了解决的道路。然后发现这个stream里没有任何数据输出。也重新debug了hiveserver2 ,发现isProgressUpdate = true ,无论是 HIVE JDBC 或者是 beeline。
但是,就是没有数据输出。然后找了beeline client 也是没解决这个问题。最后发现InPlaceUpdateStream还有一个方法是getEventNotifer。这个方法返回的new EventNotifer() ,默认是关闭进度输出的。最后调用方法,将进度输出打开。最后在InPlaceUpdateStream中找到了进度输出。
总结 , JAVA 的 HiveStatement将日志输出分为了两个部分 。
第一个部分是日志的运行输出,主要输出是一些运行的详细日志,例如application-id之类的
第二个部分是日志的进度输出,这个输出则是被放在了InplaceUpdateStream,随时通知,随时输出进度。