2013-03-14 11 views
9

To jest pytanie uzupełniające do this question, w którym pytam, co to jest interfejs API klienta Jive Hverserver 2. To pytanie powinno być w stanie stanąć bez tego tła, jeśli nie potrzebujesz więcej kontekstu.Żądania zawieszają się podczas korzystania z klienta Java Hiveserver2 Thrift

Nie można znaleźć żadnej dokumentacji dotyczącej sposobu korzystania z aplikacji Hiverserver2 do oszczędzania energii, umieściłem to razem. Najlepszym punktem odniesienia, jaki mogłem znaleźć, był 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(); 

ten kod w instancji Hiverserver2 utworzonego z

export HIVE_SERVER2_THRIFT_PORT=10002;hive --service hiveserver2 

podczas debugowania, nigdy nie ominąć linii

TOpenSessionResp openResp = client.OpenSession(openReq); 

Klient po prostu wisi aż timeout jest osiągnięty i serwer nie zapisuje niczego w stdout ani w logach. Używając Wireshark, widzę, że segment TCP dla OpenSession() jest wysyłany i ACK'd. Raz zabić klienta lub limit czasu zostanie osiągnięty, serwer daje mi następujące:

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 

Uważam to za ciekawy, że jest to dokładnie ten sam błąd ja otrzymywał kiedy błędnie próbuje użyć hiveserver (1) klienta przeciwko hiveserver2, co sugeruje, że jeśli chodzi o hiverserver2, mój klient wysyła mu śmieci.

Widzę trzy możliwości, w których może być źle.

1) Używanie interfejsu API klienta jest nieprawidłowe. Widziałem, że w implementacji JDBC było kilka rzeczy z uwierzytelnianiem i parametrami połączenia, których nie używam w moim przykładowym kodzie. Grałem z tym, ale kręciłem w ciemnościach i nie ruszyłem dalej.

2) Nieprawidłowy krok konfiguracji. Nie udało mi się znaleźć TCLIService w słoju hive-servive-0.10.0, ale udało mi się go znaleźć w słoju hive-servive-0.10.0.21 wydanym przez Hortonworks w HDP 1.2, więc może kopie z tym ujawnić problem. A może jest coś, czego potrzebuję skonfigurować stronę serwera, która wyjaśnia, dlaczego mogę połączyć się z ulem przy użyciu ODBC, ale nie z moim klientem oszczędzającym.

3) Możliwe, że w tym momencie niemożliwe jest napisanie na api interfejsu klienta hiveserver2. Jest to wiarygodne w oparciu o brak dokumentacji i oczywisty brak udanych przykładów w Internecie, ale wydaje się, że JDBC to robi. Uważam, że jest to najbardziej nieprawdopodobna opcja.

Nawet jeśli nie znasz poprawki, ustalenie, czy poprawka mieści się w zakresie 1, 2 lub 3, może zawęzić moje wyszukiwanie.

Odpowiedz

15

Nie jestem pewien, czy nadal występuje ten problem, ale ponieważ mam do czynienia z tym samym problemem i rozwiązany (być może obejście jest bardziej dokładny opis), będę zamieszczać rozwiązanie tutaj, na wypadek, gdyby ktoś go potrzebował .

Jest tak, ponieważ serwer oszczędnościowy oczekuje uwierzytelnienia przez SASL po otwarciu połączenia transportowego. Hive Server 2 domyślnie używa SASL - niestety, PHP nie ma wersji TSaslClientTransport (która jest używana jako wrapper wokół innego obiektu TTransport), która obsługuje negocjacje SASL po otwarciu połączenia transportowego.

Najprostszym rozwiązaniem na razie jest ustawienie następującej właściwości w swojej witrynie ula.xml

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

Rozwiązałem to dla mnie. –

+0

Mam. Ale w przypadku, gdy muszę ustawić niestandardowe uwierzytelnianie i muszę połączyć się przy użyciu PHP, to jakie jest rozwiązanie w tym przypadku? – Jaymin

Powiązane problemy