@(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(); } } } }