使用Hiveserver2 Thrift Java客户端时请求挂起

这是这个问题的后续问题 ,我在哪里询问Hiveserver 2 thrift java客户端API是什么。 如果您不需要任何更多背景,这个问题应该能够在没有背景的情况下站立。

无法找到有关如何使用hiverserver2 thrift api的任何文档,我把它放在一起。 我能找到的最佳参考是Apache JDBC实现 。

TSocket transport = new TSocket("hive.example.com", 10002); transport.setTimeout(999999999); TBinaryProtocol protocol = new TBinaryProtocol(transport); TCLIService.Client client = new TCLIService.Client(protocol); transport.open(); TOpenSessionReq openReq = new TOpenSessionReq(); TOpenSessionResp openResp = client.OpenSession(openReq); TSessionHandle sessHandle = openResp.getSessionHandle(); TExecuteStatementReq execReq = new TExecuteStatementReq(sessHandle, "SHOW TABLES"); TExecuteStatementResp execResp = client.ExecuteStatement(execReq); TOperationHandle stmtHandle = execResp.getOperationHandle(); TFetchResultsReq fetchReq = new TFetchResultsReq(stmtHandle, TFetchOrientation.FETCH_FIRST, 1); TFetchResultsResp resultsResp = client.FetchResults(fetchReq); TRowSet resultsSet = resultsResp.getResults(); List resultRows = resultsSet.getRows(); for(TRow resultRow : resultRows){ resultRow.toString(); } TCloseOperationReq closeReq = new TCloseOperationReq(); closeReq.setOperationHandle(stmtHandle); client.CloseOperation(closeReq); TCloseSessionReq closeConnectionReq = new TCloseSessionReq(sessHandle); client.CloseSession(closeConnectionReq); transport.close(); 

我针对使用创建的Hiverserver2实例运行此代码

 export HIVE_SERVER2_THRIFT_PORT=10002;hive --service hiveserver2 

调试时,我从来没有超过这条线

 TOpenSessionResp openResp = client.OpenSession(openReq); 

客户端只是挂起,直到达到超时并且服务器没有向stdout或日志写入任何内容。 使用Wireshark,我可以看到OpenSession()的TCP段被发送并确认。 一旦我终止客户端或达到超时,服务器给我以下内容:

 13/03/14 11:15:33 ERROR server.TThreadPoolServer: Error occurred during processing of message. java.lang.RuntimeException: org.apache.thrift.transport.TTransportException: java.net.SocketException: Connection reset at org.apache.thrift.transport.TSaslServerTransport$Factory.getTransport(TSaslServerTransport.java:219) at org.apache.thrift.server.TThreadPoolServer$WorkerProcess.run(TThreadPoolServer.java:189) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) at java.lang.Thread.run(Thread.java:662) Caused by: org.apache.thrift.transport.TTransportException: java.net.SocketException: Connection reset at org.apache.thrift.transport.TIOStreamTransport.read(TIOStreamTransport.java:129) at org.apache.thrift.transport.TTransport.readAll(TTransport.java:84) at org.apache.thrift.transport.TSaslTransport.receiveSaslMessage(TSaslTransport.java:182) at org.apache.thrift.transport.TSaslServerTransport.handleSaslStartMessage(TSaslServerTransport.java:125) at org.apache.thrift.transport.TSaslTransport.open(TSaslTransport.java:253) at org.apache.thrift.transport.TSaslServerTransport.open(TSaslServerTransport.java:41) at org.apache.thrift.transport.TSaslServerTransport$Factory.getTransport(TSaslServerTransport.java:216) ... 4 more Caused by: java.net.SocketException: Connection reset at java.net.SocketInputStream.read(SocketInputStream.java:168) at java.io.BufferedInputStream.read1(BufferedInputStream.java:256) at java.io.BufferedInputStream.read(BufferedInputStream.java:317) at org.apache.thrift.transport.TIOStreamTransport.read(TIOStreamTransport.java:127) ... 10 more 

我觉得有趣的是,当我错误地尝试使用hiveserver(1)客户端对抗hiveserver2时,这是我收到的完全相同的错误,这表明就hiverserver2而言,我的客户端正在发送垃圾。

我看到可能出错的三种可能性。

1)我对客户端API的使用是错误的。 我看到在JDBC实现中有一些事情正在进行身份validation和连接参数,我在我的示例代码中没有使用它。 我玩弄了这个,但是我在黑暗中拍摄并没有进一步。

2)我的安装步骤错了。 我无法在hive-servive-0.10.0 jar中找到TCLIService,但是我能够在Hortonworks在HDP 1.2中发布的hive-servive-0.10.0.21 jar中找到它,所以也许可以在那里挖掘它揭露这个问题。 或者也许我需要配置服务器端,这解释了为什么我可以使用ODBC而不是我的thrift客户端连接到配置单元。

3)可能在这一点上,不可能针对hiveserver2客户端api进行编写。 基于缺乏文档和互联网上明显缺乏成功的例子,这似乎是合理的,但JDBC似乎也是如此。 我发现这是最不可能的选择。

即使你不知道修复,知道修复是否低于1,2或3将有助于缩小搜索范围。

不确定你是否仍然遇到这个问题,但由于我遇到了同样的问题并解决了它(可能绕过了更准确的描述),我会在这里发布一个解决方案以防万一其他人需要它。

这是因为当您打开传输连接时,thrift服务器期望通过SASL进行身份validation。 Hive Server 2默认使用SASL – 遗憾的是,PHP缺少TSaslClientTransport版本(用作另一个TTransport对象的包装器),它在您打开传输连接时处理SASL协商。

现在最简单的解决方案是在hive-site.xml中设置以下属性

 hive.server2.authenticationNOSASL