一尘不染

ElasticSearch更新不是立即的,您如何等待ElasticSearch完成对其索引的更新?

elasticsearch

我试图在针对ElasticSearch进行测试的套件上提高性能。

测试需要很长时间,因为Elasticsearch在更新后不会立即更新其索引。例如,以下代码在运行时不会引发断言错误。

from elasticsearch import Elasticsearch
elasticsearch = Elasticsearch('es.test')

# Asumming that this is a clean and empty elasticsearch instance
elasticsearch.update(
     index='blog',
     doc_type=,'blog'
     id=1,
     body={
        ....
    }
)

results = elasticsearch.search()
assert not results
# results are not populated

目前,针对该问题的解决方案是将time.sleep调用放到代码中,以给ElasticSearch一些时间来更新其索引。

from time import sleep
from elasticsearch import Elasticsearch
elasticsearch = Elasticsearch('es.test')

# Asumming that this is a clean and empty elasticsearch instance
elasticsearch.update(
     index='blog',
     doc_type=,'blog'
     id=1,
     body={
        ....
    }
)

# Don't want to use sleep functions
sleep(1)

results = elasticsearch.search()
assert len(results) == 1
# results are now populated

显然,这并不是一件好事,因为它很容易出现故障,假设如果ElasticSearch花费多于一秒钟的时间来更新其索引,尽管测试不太可能失败。同样,当您运行100个这样的测试时,它也非常慢。

我试图解决该问题的方法是查询挂起的群集作业,以查看是否还有任何任务需要完成。但是,这不起作用,并且此代码将在没有断言错误的情况下运行。

from elasticsearch import Elasticsearch
elasticsearch = Elasticsearch('es.test')

# Asumming that this is a clean and empty elasticsearch instance
elasticsearch.update(
     index='blog',
     doc_type=,'blog'
     id=1,
     body={
        ....
    }
)

# Query if there are any pending tasks
while elasticsearch.cluster.pending_tasks()['tasks']:
    pass

results = elasticsearch.search()
assert not results
# results are not populated

所以基本上,回到我的原始问题,ElasticSearch更新不是立即的,您如何等待ElasticSearch完成对其索引的更新?


阅读 296

收藏
2020-06-22

共1个答案

一尘不染

从5.0.0版开始,elasticsearch有一个选项:

 ?refresh=wait_for

在索引,更新,删除和批量api上。这样,在结果在ElasticSearch中可见之前,请求将不会收到响应。(好极了!)

有关更多信息,请参见https://www.elastic.co/guide/en/elasticsearch/reference/master/docs-
refresh.html。

编辑:似乎此功能已经是最新的Python elasticsearch api的一部分:https :
//elasticsearch-
py.readthedocs.io/en/master/api.html#elasticsearch.Elasticsearch.index

将您的elasticsearch.update更改为:

elasticsearch.update(
     index='blog',
     doc_type='blog'
     id=1,
     refresh='wait_for',
     body={
        ....
    }
)

而且您不需要任何睡眠或轮询。

2020-06-22