我试图在针对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一些时间来更新其索引。
time.sleep
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完成对其索引的更新?
从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={ .... } )
而且您不需要任何睡眠或轮询。