@(hive)[JDBC|进度|日志] hive的JDBC提供了java链接hiveserver2查询的能力,可是hive JDBC有别于关系型数据库,一个查询语句可能要在十几分钟到几十分钟才会返回结果,而hive JDBC并不会实时显示进度和日志,这样在查询的时候对用户不是很友好,须要在执行sql的时候显示进度。html
在后台查看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 查询进度。java
完整API地址为 ---HiveStatementsql
具体实现以下数据库
// 代码不完整,仅供参考 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(); } } } }