使用hiveserver2 thrift java客户端时请求挂起

brgchamk  于 2021-06-03  发布在  Hadoop
关注(0)|答案(1)|浏览(523)

这是这个问题的后续问题,我想问一下hiveserver 2 thrift java客户端api是什么。如果你不需要更多的背景知识,这个问题应该可以在没有背景知识的情况下解决。
找不到任何关于如何使用hiverserver2 thrift api的文档,我把这些放在一起。我能找到的最好的参考是apachejdbc实现。

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<TRow> 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

我发现有趣的是,这与我在错误尝试对hiveserver2使用hiveserver(1)客户端时收到的错误完全相同,这表明就hiverserver2而言,我的客户端正在发送垃圾。
我看到了三种可能的错误。
1) 我使用客户端api是错误的。我看到在jdbc实现中有一些关于身份验证和连接参数的东西,我在示例代码中没有使用这些东西。我到处玩,但我是在黑暗中拍摄,没有得到任何进一步。
2) 我把安装步骤弄错了。我在hive-servive-0.10.0 jar中找不到tcliservice,但在hortonworks在hdp1.2中发布的hive-servive-0.10.0.21 jar中找到了它,所以也许仔细研究一下会发现这个问题。或者可能有什么我需要配置服务器端,这解释了为什么我可以连接到hive使用odbc,而不是与我的旧客户端。
3) 可能是此时不可能针对hiveserver2客户机api进行编写。基于缺乏文档和互联网上明显缺乏成功的例子,这是合理的,但是jdbc似乎做到了这一点。我觉得这是最不可能的选择。
即使您不知道修复程序,知道修复程序是否在1、2或3之下也有助于缩小搜索范围。

xeufq47z

xeufq47z1#

不确定您是否仍然遇到此问题,但由于我遇到了相同的问题并解决了它(也许绕过是更准确的描述),我将在这里发布一个解决方案,以防其他人需要它。
这是因为当您打开传输连接时,thrift服务器希望通过sasl进行身份验证。HiveServer2默认使用sasl—不幸的是,php缺少一个版本的tsaslclienttransport(它用作另一个TTTransport对象的 Package 器),当您打开传输连接时,它会处理sasl协商。
目前最简单的解决方案是在hive-site.xml中设置以下属性

<property><name>hive.server2.authentication</name><value>NOSASL</value></property>

相关问题