基本上,有一个小的aiohttp应用程序,该应用程序接收Impala查询列表,然后将其发送给Impala。但是,某些查询可能需要很长时间才能完成,因此决定以异步/并行方式进行。在使用Threads的情况下获得了一种解决方案,但是很想看看是否有可能仅使用asyncio / tornado来达到相同的速度。
我的代码如下:
async def run(self, queries):
# Here I validate queries
query_list = await self.build_query_list(split_queries) # Format: [[queries for connection_1], [queries for connection_2], ...]
start = time.time()
# Assing group of queries to each connection and wait results
result_queue = deque()
await multi([self.execute_impala_query(connection.connection, query_list[index], result_queue) for index, connection in enumerate(connection_list)])
# Close all connections
[await self.impala_connect_advance_pool.release_connection(connection) for connection in connection_list]
# Wait for Impala responses
while len(result_queue) < connect_limit:
continue
# Send results back
async def execute_impala_query(self, impala_connect, queries, queue):
return await multi([self.impala_response_to_json_response(impala_connect.cursor(), query, queue) for query in queries])
async def impala_response_to_json_response(self, impala_cursor, query, queue):
self.logger.info('execute query: {}'.format(query))
print ('execute query: {}'.format(query))
def get_results():
impala_cursor.execute(query)
results = as_pandas(impala_cursor)
impala_cursor.close()
self.logger.info('{} completed'.format(query))
print ('{} completed'.format(query))
queue.append(results.to_json(orient='records'))
IOLoop.current().spawn_callback(get_results)
发生的事情是,一旦运行,我可以看到“执行查询:查询”消息正在标准输出中打印,并且我假设它们都已被触发并正在执行,但是,它花费了2(或更多) ),只要带有Threads的版本即可。我是在整个异步概念上弄错了还是在方法中的某个地方犯了一些愚蠢的错误?
答案 0 :(得分:0)
整个异步概念是错误的是的,仅通过使用spawn_callback
调用一个函数就不会使其异步:您的数据库连接器应支持异步IO。正如我所看到的是:我建议您看一下execute_async方法。然后,您需要编写自己的等待功能,例如Impyla's _wait_to_finish,但是用tornado.gen.sleep而不是time.sleep()
。