2013-03-12 47 views
2

我已經能夠連接到Hiveserver2的Java API

hive --service hiveserver -v -p 10001 

使用下面的Java與創建hiveserver(1):

TSocket transport = new TSocket("hive.example.com", 10001);  
transport.setTimeout(999999999); 
TBinaryProtocol protocol = new TBinaryProtocol(transport); 
Client client = new ThriftHive.Client(protocol); 

transport.open();   
client.execute("SHOW TABLES");  
System.out.println(client.fetchOne()); 
transport.close(); 

是否等同存在hiveserver2,如果是這樣它是什麼?我發現的最好的是design proposal,我還沒有找到任何文檔。它看起來像Cloudera有東西設置爲python here

或者,什麼是從Java運行任意Hive查詢的最佳方法是什麼?如果是相關的,我在Hortonworks數據平臺運行1.2

回答

3

你有沒有考慮過使用HiveClient JDBC interface?

+1

在我們開始採用節儉方法之前,我的團隊中的其他人已經考慮並拒絕了它。我會發現爲什麼,如果它直接使用hiveserver2必要或更吸引人(假設它有效)。 – 2013-03-12 21:37:41

+0

我們實際上正試圖從ColdFusion中啓動它,並且迄今爲止無法將Hive ODBC用作ColdFusion數據源。由於節儉方法需要調用Java,因此我們將嘗試調用Java,然後直接使用JDBC代替節儉。我還沒有放棄節儉,但希望JDBC能夠正常工作。 – 2013-03-14 16:26:46

1

後有點搜索的我設法生成hiveserver 2使用cli_service.thrift一個Java節約服務器和客戶端在Hortonworks Data Platform 1.2中找到。如果有人有興趣,你可以在this tarball找到它。一旦我做到了,並導入了結果文件,我的IDE讓我知道,Hiveserver2客戶端API在我一直都在的罐子裏。不幸的是,我無法在Maven中的Apache配置單元jar中找到它,將此添加到您的pom.xml中並沒有完全削減它。

<dependency> 
    <groupId>org.apache.hive</groupId> 
    <artifactId>hive-service</artifactId> 
    <version>0.10.0</version> 
</dependency> 

我將HDP 1.2版本的hive-server的0.10.0.21版本添加到我的存儲庫,並引用它。然後我手動將它的所有依賴項添加到我的pom.xml中,其中還包括HDP的其他幾個0.10.0.21配置單元jar。由於這個過程與我的答案有點相似,除非有人要求,否則我不會詳細討論這個問題。

實際上讓API工作是另一回事。通過將幾十個由thrift生成的文件進行戳動,查看cli_service.thrift,並查看Apache JDBC implementation(這是我知道的針對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,所以我會提出一個新的問題來解決它。我也無法鏈接到,所以如果你想看看我的用戶歷史中的後續觀察。

+0

我認爲你的方法非常好。你有沒有找到答案? – d0x 2013-06-27 11:39:32

+0

由於我找不到答案,我使用了seedhead的答案建議的Hive JDBC。 karieanis的答案在我改變方法後出現了。 karieanis的回答聽起來非常有希望(我給了它一個upvote),但我現在致力於JDBC,所以我沒有挖出我的舊代碼來測試它。如果你或其他人可以驗證我的答案+ karieanis的答案是否能夠實現這個目標,我會接受karieanis的答案。 – 2013-07-01 16:22:21

4

服務器進程期待來自客戶端的SASL握手(這就是爲什麼您可以在堆棧跟蹤中看到TSaslServerTransport)。使用TSaslClientTransport作爲TSocket連接的包裝 - 您還需要將適當配置的SaslClient實例傳遞給構造函數。或者,您可以修改hive-site.xml以關閉SASL身份驗證。

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

謝謝,karieanis。對於這個問題的所有未來讀者,karieanis可能有缺失的部分,這使我的答案工作。 seedhead被接受而不是karieanis的原因是我已經驗證了seehead的答案「有效」,但是我還沒有能夠驗證karieanis的答案。如果有人給這個嘗試一個成功讓我知道,我會將karieanis標記爲已接受。 – 2013-07-01 16:26:07

+0

代碼片段也將不勝感激。 – user1530580 2015-01-21 17:37:32