`
tangjunliang
  • 浏览: 109556 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

使用JDBC执行impala SQL出现的问题

阅读更多
   impala版本:1.1.1
   hive版本:0.10

   最近在使用JDBC执行impala sql的时候遇到一个问题,使用JDBC执行insert overwrite/into table...select...语句的时候,执行的结果显示是成功,但是查看表中的数据的时候,发现数据并没有插入到目标表中。通过查看http://impala-node-hostname:25000/queries 发现刚才执行的SQL的状态是Exception.说明确实执行失败。

   出现这种情况的原因是由于hive驱动的bug造成的,因为sessions在执行的时候,impala将取消正在运行的查询。现在hive 0.10以及 0.11的驱动都存在这样的问题,估计能在0.12的版本中解决这个问题。

   解决方案: 我们到/hive/src/jdbc/src/java/org/apache/hive/jdbc这个目录下找到HiveStatement.java这个文件,在这个类中有个execute方法,我们提交的SQL就是通过这个方法来执行的,它的代码如下:
  public boolean execute(String sql) throws SQLException {
    if (isClosed) {
      throw new SQLException("Can't execute after statement has been closed");
    }

    try {
      closeClientOperation();
      TExecuteStatementReq execReq = new TExecuteStatementReq(sessHandle, sql);
      execReq.setConfOverlay(sessConf);
      TExecuteStatementResp execResp = client.ExecuteStatement(execReq);
      if (execResp.getStatus().getStatusCode().equals(TStatusCode.STILL_EXECUTING_STATUS)) {
        warningChain = Utils.addWarning(warningChain, new SQLWarning("Query execuing asynchronously"));
      } else {
        Utils.verifySuccessWithInfo(execResp.getStatus());
      }
      stmtHandle = execResp.getOperationHandle();
    } catch (SQLException eS) {
      throw eS;
    } catch (Exception ex) {
      throw new SQLException(ex.toString(), "08S01", ex);
    }

    if (!stmtHandle.isHasResultSet()) {
      return false;
    }
    resultSet =  new HiveQueryResultSet.Builder().setClient(client).setSessionHandle(sessHandle)
        .setStmtHandle(stmtHandle).setMaxRows(maxRows).setFetchSize(fetchSize)
        .setScrollable(isScrollableResultset)
        .build();
    return true;
  }


修改上述代码的
    if (!stmtHandle.isHasResultSet()) {
      return false;
    }

部分,修改后的代码如下:
  public boolean execute(String sql) throws SQLException {
    if (isClosed) {
      throw new SQLException("Can't execute after statement has been closed");
    }

    try {
      closeClientOperation();
      TExecuteStatementReq execReq = new TExecuteStatementReq(sessHandle, sql);
      execReq.setConfOverlay(sessConf);
      TExecuteStatementResp execResp = client.ExecuteStatement(execReq);
      if (execResp.getStatus().getStatusCode().equals(TStatusCode.STILL_EXECUTING_STATUS)) {
        warningChain = Utils.addWarning(warningChain, new SQLWarning("Query execuing asynchronously"));
      } else {
        Utils.verifySuccessWithInfo(execResp.getStatus());
      }
      stmtHandle = execResp.getOperationHandle();
    } catch (SQLException eS) {
      throw eS;
    } catch (Exception ex) {
      throw new SQLException(ex.toString(), "08S01", ex);
    }

    if (!stmtHandle.isHasResultSet()) {
       // Poll until the query has completed one way or another. DML queries will not return a result
       // set, but we should not return from this method until the query has completed to avoid
       // racing with possible subsequent session shutdown, or queries that depend on the results
       // materialised here.
       TGetOperationStatusReq statusReq = new TGetOperationStatusReq(stmtHandle);
       boolean requestComplete = false;
       while (!requestComplete) {
       try {
       TGetOperationStatusResp statusResp = client.GetOperationStatus(statusReq);
       Utils.verifySuccessWithInfo(statusResp.getStatus());
       if (statusResp.isSetOperationState()) {
       switch (statusResp.getOperationState()) {
       case CLOSED_STATE:
       case FINISHED_STATE:
         return false;
       case CANCELED_STATE:
       // 01000 -> warning
       throw new SQLException("Query was cancelled", "01000");
       case ERROR_STATE:
       // HY000 -> general error
       throw new SQLException("Query failed", "HY000");
       case UKNOWN_STATE:
       throw new SQLException("Unknown query", "HY000");
       case INITIALIZED_STATE:
       case RUNNING_STATE:
        break;
         }
        }
       } catch (Exception ex) {
         throw new SQLException(ex.toString(), "08S01", ex);
       }
       try {
          Thread.sleep(100);
       } catch (InterruptedException ex) {
          // Ignore
         }
       }
      return false;
    }
    resultSet =  new HiveQueryResultSet.Builder().setClient(client).setSessionHandle(sessHandle)
        .setStmtHandle(stmtHandle).setMaxRows(maxRows).setFetchSize(fetchSize)
        .setScrollable(isScrollableResultset)
        .build();
    return true;
  }

通过上面的修改,会一直等待查询结束。
然后,我们使用ant把hive重新编译一遍,替换掉其中的驱动包。

期望hive能在0.12版本中解决这个问题。
分享到:
评论

相关推荐

    jdbc 连接impala或者jdbc连接hive

    在这个场景下,JDBC提供了连接Hive和Impala的功能,使得开发者可以通过编写Java程序或使用支持JDBC的任何其他工具来执行查询和操作数据。下面将详细介绍如何使用JDBC连接Hive和Impala。 1. **JDBC连接Hive** Hive...

    JDBC-impala驱动包

    这两个文件是Cloudera官方提供的Impala JDBC驱动程序,它们允许Java应用程序通过JDBC接口与Impala进行通信,执行SQL查询、数据操作和管理任务。 1. ImpalaJDBC41.jar: 这个版本的驱动支持JDBC 4.1规范,是基于Java ...

    采用jdbc连接Impala

    在本场景中,我们关注的是如何使用JDBC连接到Impala,这是一个高性能的数据处理系统,常用于大数据分析。Impala是由Cloudera开发的开源项目,它允许实时查询Hadoop集群上的数据,而无需将数据导出到其他系统。 首先...

    java通过jdbc连接impala所需jar

    在本案例中,我们讨论的是如何使用Java通过JDBC连接到Cloudera的Impala,一个高性能的数据处理引擎,主要用于处理大规模数据集。 首先,我们需要理解以下关键概念: 1. **Impala**: Impala是由Cloudera开发的MPP...

    jdbc 通过impala 连接hive库

    JDBC是Java中用于与各种数据库交互的一套标准API,它允许Java开发者使用SQL语句来操作数据库。对于Hive和Impala这样的大数据处理系统,它们都提供了JDBC驱动,使得开发者可以像操作传统关系型数据库一样进行操作。 ...

    impala数据库JDBC驱动集

    使用JDBC驱动,开发者可以编写Java代码来创建数据库连接、执行SQL语句、处理查询结果等。JDBC驱动分为几种类型,如Type 1、Type 2、Type 3和Type 4,其中Type 4是纯Java实现的,直接与数据库通信,通常效率更高且更...

    JDBC_Impala 2.5.43 jar包.zip

    5. **异常处理**:在实际应用中,需要捕获并处理可能出现的异常,比如网络问题、SQL语法错误等。 6. **配置安全连接**:如果在生产环境中,你可能需要配置SSL/TLS以加密连接,并考虑使用Kerberos或LDAP进行安全认证...

    impala_jdbc.zip

    Impala JDBC驱动是基于Java API设计的,允许Java应用程序或者任何支持JDBC的工具(如Tableau、Excel等)连接到Impala服务,执行SQL查询并获取结果。这使得开发人员无需了解底层的Hadoop生态系统细节,就能实现高效的...

    JDBC4连接Impala的jar

    4. **执行SQL查询**:有了连接后,我们可以创建`Statement`或`PreparedStatement`对象,然后使用它们来执行SQL查询。例如: ```java Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery...

    Impala的JDBC编程驱动

    标题中的“Impala的JDBC编程驱动”指的是Impala(一个开源的、高性能的SQL查询引擎,用于处理存储在Hadoop集群中的数据)与Java应用程序之间的桥梁,即JDBC(Java Database Connectivity)驱动。JDBC驱动是Java...

    Cloudera JDBC Driver for Impala

    这个驱动程序允许开发者和数据分析师使用标准的JDBC接口来与Impala进行交互,从而在Java应用程序中执行SQL查询、数据操作以及数据分析。Impala是Cloudera提供的一种高性能、实时分析的SQL查询引擎,它与Hadoop生态...

    impala jdbc jar

    总结一下,要使用JDBC连接Hive和Impala,你需要包含相应的JDBC驱动jar包,即`hive-jdbc-1.1.0.jar`和`ImpalaJDBC41.jar`。通过`Class.forName()`加载驱动,然后使用`DriverManager.getConnection()`建立连接。注意...

    HADOOP-IMAPALA JDBC -impala_jdbc_2.5.42.106.zip

    在这个场景中,`impala_jdbc_2.5.42.1062 (1)` 这个文件就是Impala的JDBC驱动,它使得Java开发者可以编写程序,直接在内存中执行对Impala的SQL查询,从而高效地处理和分析Hadoop集群上的大量数据。 使用Impala JDBC...

    JDBC Driver for Impala 的使用教程

    **JDBC Driver for Impala使用教程** 在Java编程中,JDBC(Java Database Connectivity)是连接数据库的标准接口,使得开发者可以使用Java语言与各种不同类型的数据库进行交互。Impala是Cloudera公司开发的一个高...

    impala-jdbc驱动

    它是Java应用程序与Impala之间通信的桥梁,使得开发者能够使用标准的Java SQL API来执行查询、操作数据以及管理Impala的数据源。Impala是一款高度优化的、分布式的SQL查询引擎,专为Hadoop生态系统设计,提供低延迟...

    impala_jdbc驱动包

    使用Impala的JDBC驱动,开发者可以编写Java程序来实现以下功能: - **连接管理**:创建数据库连接,执行SQL语句,关闭连接。 - **查询操作**:执行SELECT语句,获取结果集,遍历并处理数据。 - **DML操作**:INSERT...

    dbeaver impala jdbc连接包

    标题 "dbeaver impala jdbc连接包" 涉及到的是在数据管理工具DBeaver中连接Impala数据库所必需的Java Database ...正确配置和使用这个驱动,可以方便地在DBeaver中执行SQL查询、管理Impala数据和进行数据分析。

    Cloudera-JDBC-Driver-for-Impala-Install-Guide.pdf

    这意味着用户可以使用Java编写应用程序,通过JDBC驱动来与Impala进行交互和执行SQL查询。 2. 版本和版权声明:文档中提到了Cloudera JDBC Driver for Impala的版本号为2.5.28,并强调了版权声明,表明文档中的所有...

    impala-jdbc.zip

    总结来说,`impala-jdbc.zip`这个压缩包提供的示例代码展示了如何利用Java的JDBC API与Impala数据库进行交互,包括建立连接、执行SQL和管理连接池等核心功能。这对于需要在Java应用中集成Impala进行数据管理的开发者...

Global site tag (gtag.js) - Google Analytics