具有多线程的ElasticSearch Scroll API

时间:2018-05-16 17:20:18

标签: multithreading elasticsearch elasticsearch-py

首先,我想让大家知道我了解ElasticSearch Scroll API如何工作的基本工作逻辑。要使用滚动 API,首先,我们需要使用 1m 等滚动值调用搜索方法,然后返回 _scroll_id 将用于Scroll上的下一次连续调用,直到所有文档在循环内返回。但问题是我只想在多线程的基础上使用相同的过程,而不是串行。例如:

如果我有300000个文档,那么我想以这种方式处理/获取文档

  • 第一个主题将处理初始 100000个文档
  • 第二个主题将处理下一个 100000个文档
  • 第三个主题将处理剩余 100000个文档

所以我的问题是因为我没有找到任何方法在滚动API上设置来自值如何使用线程更快地使滚动过程更快。不要以序列化的方式处理文档。

我的示例python代码

if index_name is not None and doc_type is not None and body is not None:
   es = init_es()
   page = es.search(index_name,doc_type, scroll = '30s',size = 10, body = body)
   sid = page['_scroll_id']
   scroll_size = page['hits']['total']

   # Start scrolling
   while (scroll_size > 0):

       print("Scrolling...")
       page = es.scroll(scroll_id=sid, scroll='30s')
       # Update the scroll ID
       sid = page['_scroll_id']

       print("scroll id: " + sid)

       # Get the number of results that we returned in the last scroll
       scroll_size = len(page['hits']['hits'])
       print("scroll size: " + str(scroll_size))

       print("scrolled data :" )
       print(page['aggregations'])

3 个答案:

答案 0 :(得分:3)

你试过sliced scroll吗?根据链接的文档:

  

对于返回大量文档的滚动查询,可以执行此操作   将滚动分割成可以消耗的多个切片   独立地

  

每个滚动都是独立的,可以像任何滚动一样并行处理   滚动请求。

我自己没有用过(我需要处理的最大结果集是~50k文件),但这似乎是你正在寻找的。

答案 1 :(得分:2)

您应该使用切片滚动,请参阅https://github.com/elastic/elasticsearch-dsl-py/issues/817#issuecomment-372271460有关如何在python中执行此操作。

答案 2 :(得分:1)

滚动必须是同步的,这是逻辑。

你可以使用多线程,这正是elasticsearch适用于:parallelism的原因。

elasticsearch索引,由分片组成,这是数据的物理存储。碎片可以在同一节点上(更好)。

另一方面,搜索API提供了一个非常好的选择:_preferencehttps://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-preference.html

回到你的应用程序:

  1. 获取索引分片(和节点)列表
  2. 通过分片创建线程
  3. 在每个帖子上进行滚动搜索
  4. Etvoilà!

    另外,你可以使用elasticsearch4hadoop插件,它完全适用于Spark / PIG / map-reduce / Hive。