9

これは、Hiveserver 2 thrift Java クライアント API とは何かを尋ねるこの質問のフォローアップの質問です。これ以上のコンテキストが必要ない場合、この質問はその背景なしで立つことができるはずです.

hiverserver2 thrift 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 セグメントが送信され、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

これは、hiveserver2 に対して hiveserver (1) クライアントを誤って使用しようとしたときに受け取ったのとまったく同じエラーであることは興味深いことです。これは、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 を使用してハイブに接続できるが、thrift クライアントでは接続できない理由を説明する、サーバー側を構成する必要があるものがあるかもしれません。

3) この時点で、hiveserver2 クライアント API に対して書き込むことができない可能性があります。これは、ドキュメントの欠如とインターネット上での成功例の明らかな欠如に基づいてもっともらしいですが、JDBC はそれを行うようです。これは最もありそうもない選択肢だと思います。

修正方法を知らなくても、修正方法が 1、2、または 3 のどれに該当するかがわかれば、検索を絞り込むのに役立ちます。

4

1 に答える 1

15

この問題がまだ発生しているかどうかはわかりませんが、同じ問題に直面して解決したため (おそらくバイパスしたほうが正確な説明です)、他の誰かがそれを必要とする場合に備えて、ここに解決策を投稿します.

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

今のところ最も簡単な解決策は、hive-site.xml で次のプロパティを設定することです。

<property><name>hive.server2.authentication</name><value>NOSASL</value></property>
于 2013-04-12T23:00:32.140 に答える