2013-03-14 20 views
9

これは、this questionへのフォローアップの質問です。ここで、Hiveserver 2 thrift JavaクライアントAPIの内容を尋ねます。これ以上の文脈を必要としないなら、この質問はその背景なしに立つことができるはずです。Hiveserver2 Thrift Javaクライアントを使用するとリクエストがハングする

hiverserver2スリフトAPIの使い方に関するドキュメントが見つかりませんでした。私はこれをまとめました。私が見つけた最高の参考資料はApache JDBC implementationでした。

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(); 

は私がデバッグ、私は、クライアントは単にタイムアウトに達するとされてハングまで

TOpenSessionResp openResp = client.OpenSession(openReq); 

ラインを乗り越えることがないときは

export HIVE_SERVER2_THRIFT_PORT=10002;hive --service hiveserver2 

で作成Hiverserver2インスタンスに対してこのコードを実行しますサーバはstdoutやログに何も書き込まない。 Wiresharkを使用すると、OpenSession()のTCPセグメントが送信され、ACKされたことがわかります。

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に関する限り、私のクライアントはそれをゴミ箱に送ります。

私はどこが間違っているのか3つの可能性を見ています。

1)私のクライアントAPIの使用は間違っています。 JDBCの実装では、サンプルコードで使用していない認証と接続パラメータを使用していることがわかりました。私はその周りを遊んだが、私は暗闇の中で撮影していたし、それ以上は得られなかった。

2)セットアップ手順が間違っています。 hive-servive-0.10.0のjarファイルでTCLIServiceを見つけることができませんでしたが、HortonworksがHDP 1.2でリリースしたhive-servive-0.10.0.21 jarファイルでそのファイルを見つけることができました。問題を明らかにする。または、おそらく、私がODBCを使ってハイブに接続できる理由を説明するサーバ側を設定する必要があるのですが、私の倹約クライアントではありません。

3)この時点で、hiveserver2クライアントAPIに対して書き込むことは不可能である可能性があります。これは、文書化の欠如とインターネット上での成功例が明らかに不足していることに基づいていますが、JDBCがそうしているようです。私はこれが最も可能性の低いオプションであることを知っています。

修正プログラムがわからなくても、修正プログラムが1,2、または3に該当するかどうかを知ることで、検索の絞り込みに役立ちます。

答えて

15

この問題がまだ発生していても、同じ問題に直面して解決したため(確かに説明が間違っている可能性があります)、他の誰かが必要とする場合に備えてここに解決策を投稿します。

これは、トランスポート接続を開いたときに、リフトサーバーがSASLを使用して認証するためです。ハイブサーバー2はデフォルトでSASLを使用します - 残念ながらPHPにはトランスポート接続を開く際にSASLネゴシエーションを処理するTSaslClientTransport(別のTTransportオブジェクトのラッパーとして使用される)のバージョンがありません。

今のところ最も簡単な解決策は、ハイブサイトに次のプロパティを設定することです。xml

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

解決されました。 –

+0

私は持っています。しかし、私はカスタム認証をセットアップする必要があり、私はPHPを使用して接続する必要がある場合、この場合の解決策は何ですか? – Jaymin

関連する問題