我试图提高针对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次这样的测试时,它也非常慢。
我尝试解决此问题的方法是查询pending cluster jobs以查看是否还有任何待完成的任务。但是,这不起作用,并且此代码将在没有断言错误的情况下运行。
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完成更新它的索引?
答案 0 :(得分:16)
从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={
....
}
)
你不应该进行任何睡眠或民意调查。
答案 1 :(得分:3)
似乎对我有用:
els.indices.refresh(index)
els.cluster.health(wait_for_no_relocating_shards=True,wait_for_active_shards='all')
答案 2 :(得分:0)
如果您不想等待群集刷新间隔,也可以调用elasticsearch.Refresh('blog')
答案 3 :(得分:0)
如果您使用批量助手,您可以这样做:
from elasticsearch.helpers import bulk
bulk(client=self.es, actions=data, refresh='wait_for')