簡體   English   中英

使用Hiveserver2 Thrift Java客戶端時請求掛起

[英]Requests hang when using Hiveserver2 Thrift Java client

這是該問題的后續問題,在這里我問什么是Hiveserver 2舊版Java客戶端API。 如果您不需要更多背景信息,那么這個問題應該能夠在沒有背景的情況下得以解決。

找不到有關如何使用hiverserver2舊版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<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在HDP 1.2中發布的hive-servive-0.10.0.21 jar中找到它,所以也許您會對此進行深入研究揭示問題。 也許我需要在服務器端進行配置,這說明了為什么可以使用ODBC而不是使用Thrift客戶端連接到Hive。

3)可能此時無法針對hiveserver2客戶端api進行編寫。 基於缺乏文檔和互聯網上顯然沒有成功的例子,這是合理的,但是JDBC似乎做到了。 我發現這是最不可能的選擇。

即使您不知道修復程序,知道該修復程序是否低於1、2或3也將有助於縮小搜索范圍。

不知道您是否仍然遇到此問題,但是由於我也遇到了相同的問題並已解決(也許繞過的是更准確的描述),因此我會在此處發布解決方案,以防萬一其他人需要它。

這是因為當您打開傳輸連接時,舊服務器希望通過SASL進行身份驗證。 Hive Server 2默認使用SASL-不幸的是,PHP缺少TSaslClientTransport版本(用作另一個TTransport對象的包裝),該版本在打開傳輸連接時處理SASL協商。

目前最簡單的解決方案是在hive-site.xml中設置以下屬性

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM