2010-02-02 4 views
3

Я хотел бы выполнить запрос на улей на сервере асинхронным образом. Запрос на улов, вероятно, займет много времени, поэтому я бы предпочел не блокировать вызов. В настоящее время я использую Thirft, чтобы сделать блокирующий вызов (блоки на client.execute()), но я не видел примера, как сделать неблокирующий вызов. Вот код блокировки:Как сделать асинхронный вызов Hive в Java?

 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, чтобы сократить его.

Есть ли у кого-нибудь идеи, как сделать асинхронный вызов? Can Hive/Thrift поддерживает его? Есть ли способ лучше?

Спасибо!

+0

Я действительно мало что знаю о Trrift только сейчас, но не могу ли вы обернуть его в runnable и создать новую тему? – brindy

+0

Да, ясно, что я могу сделать работу самостоятельно, но есть вещи, которые заставляют меня думать, что она уже встроена в Thrift, как TNonblockingSocket. Я не могу найти примеров того, как его использовать, или даже если Hive поддерживает его. –

ответ

1

После разговора с списком рассылки Hive, Hive не поддерживает асинхронные вызовы с использованием Thirft.

0

Я не знаю о Hive, в частности, но любой блокирующий вызов может быть превращен в асинхронный вызов, создавая новый поток и используя обратный вызов. Вы можете посмотреть java.util.concurrent.FutureTask, который был разработан, чтобы обеспечить удобство управления такой асинхронной работой.

1

Я ничего не знаю о улье, но в крайнем случае, вы можете использовать библиотеку параллелизма в 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 вместо Вызываемый.

0

Мы запускаем асинхронные вызовы AWS Elastic MapReduce. AWS MapReduce может запускать рабочие задания adoop/hive в облаке Amazon с призывом к веб-сервисам AWS MapReduce.

Вы также можете следить за состоянием своих заданий и получать результаты с S3 после завершения задания.

Поскольку вызовы в веб-службы носят асинхронный характер, мы никогда не блокируем другие операции. Мы продолжаем следить за состоянием наших рабочих мест в отдельном потоке и получать результаты, когда работа завершена.

2

AFAIK, на момент написания статьи Thrift не генерирует асинхронные клиенты. Причина, поясняемая в этой ссылке here (текст поиска для «асинхронный») заключается в том, что Thrift был разработан для центра обработки данных, где предполагается, что время ожидания является низким.

К сожалению, как вы знаете, латентность между вызовом и результатом не всегда вызвана сетью, а логикой выполняется! У нас есть эта проблема, вызывающая базу данных Cassandra с сервера приложений Java, где мы хотим ограничить общий поток.

Резюме: на данный момент все, что вы можете сделать, это убедиться, что у вас достаточно ресурсов для обработки требуемых номеров заблокированных параллельных потоков и ожидания более эффективной реализации.

2

Теперь можно сделать асинхронный вызов клиента бережливость Java после этого патч был поставлен в: https://issues.apache.org/jira/browse/THRIFT-768

Генерирование клиента асинхронной 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); 

Теперь вы можете выполнять методы на этом клиенте, как на синхронном интерфейсе. Единственное изменение заключается в том, что все методы принимают дополнительный параметр обратного вызова.