经过一番搜索后,我设法使用 Hortonworks Data Platform 1.2 中的 cli_service.thrift 为 hiveserver 2 生成了 Java thrift 服务器和客户端。如果有人感兴趣,你可以在这个 tarball中找到它。一旦我这样做并导入了结果文件,我的 IDE 就会让我知道 Hiveserver2 客户端 API 在我一直拥有的 jar 中。不幸的是,我无法在 Apache hive jar 中找到它,所以在 Maven 中,将它添加到 pom.xml 并不能完全消除它。
<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-service</artifactId>
<version>0.10.0</version>
</dependency>
我将 HDP 1.2 版本的 0.10.0.21 版本的 hive-server 添加到我的存储库中,并改为引用它。然后我手动将它的所有依赖项添加到我的 pom.xml 中,包括来自 HDP 的其他几个 0.10.0.21 hive jar。由于这个过程与我的回答有些相切,除非有人要求,否则我不会对此进行更详细的说明。
实际上让 API 工作完全是另一回事。通过查看 thrift 生成的数十个文件、查看 cli_service.thrift 和查看Apache JDBC 实现(这是我所知道的针对 Hiveserver2 thrift API 编写的唯一示例),我想出了以下代码几乎是 Hiveserver (1) 示例的直接翻译:
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();
这是针对使用以下命令启动的 Hiveserver2 服务器运行的:
export HIVE_SERVER2_THRIFT_PORT=10002;hive --service hiveserver2
不幸的是,当我尝试针对 Hiveserver2 运行 Hiveserver (1) 客户端时,我得到了相同的行为。transport.open()
工作,但第一个请求(在 hiverserver2 的情况下client.OpenSession()
,而不是 hiveserver 的 (1) client.execute()
)挂起。Wireshark 显示 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
似乎有人在 Python 客户端上遇到了类似的问题。我缺乏发布链接的声誉,所以如果你想查看他们(未解决的)问题谷歌hiveserver2 thrift client python grokbase
由于它不起作用,这只是我问题的部分答案。但是,现在我有了 API,我将提出一个新问题来让它工作。我也无法链接到该链接,因此如果您想在我的用户历史记录中查看后续内容。