异步配置单元查询执行:一旦查询发起者客户端断开连接,OperationHandle 就会在服务器端被清理

Asynchronous hive query execution : OperationHandle gets cleaned up at server side as soon as the query initiator client disconnects

是否可以在 Hive 服务器中异步执行查询?

例如,我如何/是否可以从客户端做这样的事情-

QueryHandle handle = executeAsyncQuery(hiveQuery);
Status status = handle.checkStatus();
if(status.isCompleted()) {
    QueryResult result = handle.fetchResult();
}

我也看了How do I make an async call to Hive in Java?。但没有帮助。答案主要围绕接受回调参数的节俭客户。

如有任何帮助,我们将不胜感激。谢谢!

[编辑 1]

我在 hive-jdbc 中检查了 HiveConnection.java。 hive-jdbc 默认使用异步 thrift API。因此,它提交查询并轮询结果集(查看 HiveStatement.java)。现在我可以写一段纯非阻塞的代码了。但问题是一旦客户端断开连接,关于查询的足迹就丢失了。

客户端 1

final TCLIService.Client client = new TCLIService.Client(createBinaryTransport(host, port, loginTimeout, sessConf, false)); // from HiveConnection.java
TSessionHandle sessionHandle = openSession(client) // from HiveConnection.java
TExecuteStatementReq execReq = new TExecuteStatementReq(sessionHandle, sql);
execReq.setRunAsync(true);
execReq.setConfOverlay(sessConf);
final TGetOperationStatusReq handle = client.ExecuteStatement(execReq)
writeHandleToFile("~/handle", handle)

客户端 2

final TGetOperationStatusReq handle = readHandleFromFile("~/handle")
final TCLIService.Client client = new TCLIService.Client(createBinaryTransport(host, port, loginTimeout, sessConf, false));
while (true) {
    System.out.println(client.GetOperationStatus(handle).getOperationState());
    Thread.sleep(1000);
}

只要客户端 1 还活着,客户端 2 就会一直打印 FINISHED_STATE。但是,如果客户端 1 进程完成或被杀死,客户端 2 开始打印 null,这意味着 hiveserver2 在客户端断开连接后立即清理资源。

是否可以配置 hiveserver2 以根据时间或其他方式配置此清理过程?

谢谢!

做了一些研究,发现只有二进制传输 (tcp) 才会发生这种情况

  @Override
  public void deleteContext(ServerContext serverContext,
      TProtocol input, TProtocol output) {
    Metrics metrics = MetricsFactory.getInstance();
    if (metrics != null) {
      try {
        metrics.decrementCounter(MetricsConstant.OPEN_CONNECTIONS);
      } catch (Exception e) {
        LOG.warn("Error Reporting JDO operation to Metrics system", e);
      }
    }
    ThriftCLIServerContext context = (ThriftCLIServerContext) serverContext;
    SessionHandle sessionHandle = context.getSessionHandle();
    if (sessionHandle != null) {
      LOG.info("Session disconnected without closing properly, close it now");
      try {
        cliService.closeSession(sessionHandle);
      } catch (HiveSQLException e) {
        LOG.warn("Failed to close session: " + e, e);
      }
    }
  }

上面的存根(来自 ThriftBinaryCLIService)通过 ThriftBinaryCLIService 使用的 TThreadPoolServer 的这段代码执行。

eventHandler.deleteContext(connectionContext, inputProtocol, outputProtocol);

显然 http 传输 (ThriftHttpCLIService) 具有不同的清理操作句柄的策略(不像 tcp 那样贪婪)

将就此与 Hive 社区核实以了解更多信息,并查看是否已经有解决此问题的问题。