【问题标题】:Hiveserver2 Java APIHiveserver2 Java API
【发布时间】:2013-03-12 21:21:38
【问题描述】:

我已经能够连接到使用

创建的 hiveserver (1)
hive --service hiveserver -v -p 10001

使用以下java:

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 Data Platform 1.2 上运行

【问题讨论】:

    标签: java hadoop hive thrift hortonworks-data-platform


    【解决方案1】:

    服务器进程期待来自客户端的 SASL 握手(这就是您可以在堆栈跟踪中看到 TSaslServerTransport 的原因)。使用 TSaslClientTransport 作为 TSocket 连接的包装器 - 您还需要将适当的配置 SaslClient 实例传递给构造函数。或者,您可以修改 hive-site.xml 以关闭 SASL 身份验证。

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

    【讨论】:

    • 谢谢,karieanis。对于这个问题的所有未来读者,karieanis 可能缺少使我的答案起作用的部分。接受种子头而不是卡里埃尼斯的原因是我已经验证了希海德的答案“有效”,但我无法验证卡里埃尼斯的答案。如果有人尝试并成功,请告诉我,我会将 krieanis 标记为已接受。
    【解决方案2】:

    您是否考虑过使用HiveClient JDBC interface?

    【讨论】:

    • 在我们开始采用节俭方法之前,我团队中的其他人考虑并拒绝了它。我会找出原因以及它是否需要直接使用 hiveserver2 或者只是更有吸引力(假设它有效)。
    • 我们实际上是在尝试从 ColdFusion 启动它,并且到目前为止还无法使用 Hive ODBC 作为 ColdFusion 数据源。由于 thrift 方法无论如何都需要调用 Java,我们将尝试调用 Java,然后使用 JDBC 而不是直接使用 thrift。我还没有放弃节俭,但希望 JDBC 能正常工作。
    【解决方案3】:

    经过一番搜索,我设法使用 Hortonworks Data Platform 1.2 中的 cli_service.thrift 为 hiveserver 2 生成了 Java thrift 服务器和客户端。如果有人有兴趣,可以在this tarball 找到。一旦我这样做并导入了结果文件,我的 IDE 就会让我知道 Hiveserver2 客户端 API 在我一直拥有的 jar 中。不幸的是,我无法在 Apache hive jars 中找到它,所以在 Maven 中,将它添加到 pom.xml 并不能完全解决它。

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

    我将 HDP 1.2 版本的 0.10.0.21 版本的 hive-server 添加到我的存储库并引用了它。然后我手动将它的所有依赖项添加到我的 pom.xml 中,包括来自 HDP 的其他几个 0.10.0.21 hive 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,我将提出一个新问题来让它工作。我也无法链接到那个,所以如果你想在我的用户历史记录中查看后续内容。

    【讨论】:

    • 我认为您的方法非常好。你找到答案了吗?
    • 我选择了seedhead 的答案建议的Hive JDBC,因为我找不到答案。在我改变方法后,karieanis 的答案出现了。 krieanis 的回答听起来很有希望(我给了它一个赞成票),但我现在致力于 JDBC,所以我没有挖出我的旧代码来测试它。如果您或其他任何人可以验证我的回答 + karieanis 的回答是否能正常工作,我会接受 krieanis 的回答。
    猜你喜欢
    • 1970-01-01
    • 2017-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多