@(hive)[JDBC|进度|日志] hive的JDBC提供了java连接hiveserver2查询的能力,但是hive JDBC有别于关系型数据库,一个查询语句可能要在十几分钟到几十分钟才会返回结果,而hive JDBC并不会实时显示进度和日志,这样在查询的时候对用户不是很友好,需要在执行sql的时候显示进度。
在后台查看hiverserver2的日志中发现,其实hiveserver2
在执行一个sql查询的时候是会捕捉到MR运行的进度和日志的,所以只要能把hiverser2获取到MR进度的日志捕捉到,就能实现显示进度的功能。在之前的hive 0.7
和 0.9
版本中我们是直接修改了hive-jdbc
的源码来实现日志和数据的分离和重定向显示。在hive 1.1.0
中其实已经有了可以获取进度的API
了,分别是HiveStatement
中的 List<String> getQueryLog()
,List<String> getQueryLog(boolean incremental, int fetchSize)
和boolean hasMoreLogs()
三个方法,借助这三个方法,就可以实时显示sql 查询进度。
完整API地址为 —HiveStatement
具体实现如下
// 代码不完整,仅供参考
public class HiveExecuter {
static Statement stmt = null;
static class GetLogThread extends Thread {
public void run() { //真生的输出运行进度的thread
if (stmt == null) {
return;
}
HiveStatement hiveStatement = (HiveStatement) stmt;
try {
while (!hiveStatement.isClosed() && ((HiveStatement) stmt).hasMoreLogs()) {
try {
for (String log : ((HiveStatement) stmt).getQueryLog(true, 100)) {
System.out.println(log);
}
Thread.currentThread().sleep(500L);
} catch (SQLException e) { //防止while里面报错,导致一直退不出循环
e.printStackTrace();
return;
} catch (InterruptedException e) {
e.printStackTrace();
return;
}
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
// ... 一些初始化
// 加载数据连接
try {
Class.forName("org.apache.hive.jdbc.HiveDriver");
connection = DriverManager.getConnection(hiveConnection, username, "");
stmt = connection.createStatement();
new GetLogThread().start();
rs = stmt.executeQuery(preSql);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (rs != null) {
rs.close();
}
if (stmt != null) {
stmt.close();
}
if (connection != null && !connection.isClosed()) {
connection.close();
}
} catch (SQLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
转载请注明:SuperIT » hive JDBC 进度和日志查看