我想以异步方式在服务器上执行Hive查询。 Hive查询可能需要很长时间才能完成,所以我不想阻止通话。我目前正在使用Thirft进行阻塞调用(在client.execute()上阻塞),但我还没有看到如何进行非阻塞调用的示例。这是阻止代码:
TSocket transport = new TSocket("hive.example.com", 10000);
transport.setTimeout(999999999);
TBinaryProtocol protocol = new TBinaryProtocol(transport);
Client client = new ThriftHive.Client(protocol);
transport.open();
client.execute(hql); // Omitted HQL
List<String> rows;
while ((rows = client.fetchN(1000)) != null) {
for (String row : rows) {
// Do stuff with row
}
}
transport.close();
上面的代码缺少try / catch块以保持简短。
有没有人有任何想法如何进行异步调用? Hive / Thrift可以支持吗?还有更好的方法吗?
谢谢!
答案 0 :(得分:2)
AFAIK,在撰写本文时,Thrift不会生成异步客户端。这个链接here(“异步”的搜索文本)中解释的原因是Thrift是为假设延迟较低的数据中心而设计的。
不幸的是,您知道在呼叫和结果之间经历的延迟并不总是由网络引起,而是由正在执行的逻辑引起的!我们从Java应用程序服务器调用Cassandra数据库时遇到此问题,我们希望限制总线程数。
总结:现在你要做的就是确保你有足够的资源来处理所需数量的被阻塞并发线程并等待更有效的实现。
答案 1 :(得分:2)
现在可以在放入此补丁后在Java thrift客户端中进行异步调用: https://issues.apache.org/jira/browse/THRIFT-768
使用新的thrift生成异步Java客户端并按如下方式初始化客户端:
TNonblockingTransport transport = new TNonblockingSocket("127.0.0.1", 9160);
TAsyncClientManager clientManager = new TAsyncClientManager();
TProtocolFactory protocolFactory = new TBinaryProtocol.Factory();
Hive.AsyncClient client = new Hive.AsyncClient(protocolFactory, clientManager, transport);
现在,您可以像在同步接口上一样在此客户端上执行方法。唯一的变化是所有方法都需要一个额外的回调参数。
答案 2 :(得分:1)
我对Hive一无所知,但作为最后的手段,你可以使用Java的并发库:
Callable<SomeResult> c = new Callable<SomeResult>(){public SomeResult call(){
// your Hive code here
}};
Future<SomeResult> result = executorService.submit(c);
// when you need the result, this will block
result.get();
或者,如果您不需要等待结果,请使用 Runnable 而不是 Callable 。
答案 3 :(得分:1)
在与Hive邮件列表交谈后,Hive不支持使用Thirft进行异步调用。
答案 4 :(得分:0)
我并不特别了解Hive,但任何阻止调用都可以通过生成新线程并使用回调来在异步调用中启用。您可以查看java.util.concurrent.FutureTask
,它旨在允许轻松处理此类异步操作。
答案 5 :(得分:0)
我们触发对AWS Elastic MapReduce的异步调用。 AWS MapReduce可以通过调用AWS MapReduce Web服务在Amazon的云上运行hadoop / hive作业。
您还可以监控作业的状态,并在作业完成后从S3中获取结果。
由于对Web服务的调用本质上是异步的,因此我们永远不会阻止其他操作。我们继续在一个单独的线程中监控我们的工作状态,并在工作完成后获取结果。