2015-05-06 29 views
1

我創建使用Python API類似這樣的Elasticsearch索引:索引創建成功TransportError(503,U「」)試圖用一個最近創建elasticsearch指數

from elasticsearch import Elasticsearch 

es = Elasticsearch() 

index_body = {"mappings": {".percolator": {"properties": {"message": {"type": "string", "analyzer": "english"}}}}} 
# Creates the index if it doesn't exist 
if not es.indices.exists('test'): 
    es.indices.create(index='test', body=index_body) 

print es.exists(index='test', id='1') 

,但是當我檢查該指數中的文檔存在失敗與此錯誤:

Traceback (most recent call last): 
    File "main.py", line 12, in <module> 
    print es.exists(index='test', id='1') 
    File "/usr/local/lib/python2.7/dist-packages/elasticsearch/client/utils.py", line 68, in _wrapped 
    return func(*args, params=params, **kwargs) 
    File "/usr/local/lib/python2.7/dist-packages/elasticsearch/client/__init__.py", line 282, in exists 
    self.transport.perform_request('HEAD', _make_path(index, doc_type, id), params=params) 
    File "/usr/local/lib/python2.7/dist-packages/elasticsearch/transport.py", line 307, in perform_request 
    status, headers, data = connection.perform_request(method, url, params, body, ignore=ignore, timeout=timeout) 
    File "/usr/local/lib/python2.7/dist-packages/elasticsearch/connection/http_urllib3.py", line 86, in perform_request 
    self._raise_error(response.status, raw_data) 
    File "/usr/local/lib/python2.7/dist-packages/elasticsearch/connection/base.py", line 102, in _raise_error 
    raise HTTP_EXCEPTIONS.get(status_code, TransportError)(status_code, error_message, additional_info) 
elasticsearch.exceptions.TransportError: TransportError(503, u'') 

如果我運行此腳本第二次,指數已經創建它工作得很好。 有沒有人有什麼可能會出錯的想法?

+0

請看你的'/ var/log/elasticsearch/.log',它可以包含更多的信息。 '503'通常以某種方式表示集羣存在問題。當您已經發送下一個請求時,可能索引尚未創建(在集羣中)?如果您在嘗試使用'es.exists'之前等待一秒鐘,它會起作用嗎? – mark

+0

感謝您的回答!如果我在'es.exists(index ='test',id ='1')之前添加'time.sleep(1)',它可以很好地工作。儘管在日誌文件中沒有信息。 –

回答

1

創建新索引時,需要等到分配完所有分片。

我知道怎麼做的最好的方法是這樣的:

  1. <your_index>/_status
  2. 迭代所有indices.<your_index>.shards並驗證routing.state = STARTED到處
  3. 轉到1)除非所有的碎片都開始

Here's a (PHP) project這是做單元測試的:

protected function _waitForAllocation(Index $index) 
{ 
    do { 
     $settings = $index->getStatus()->get(); 
     $allocated = true; 
     foreach ($settings['shards'] as $shard) { 
      if ($shard[0]['routing']['state'] != 'STARTED') { 
       $allocated = false; 
      } 
     } 
    } while (!$allocated); 
} 

錯誤答案:

您已在繼續之前給ES 一些空間。 ES是附近實時,所以延遲是預計。特別是當你按順序運行你的代碼時,毫不拖延。

我想你只需撥打_refresh endpoint即可。

在實踐中,我必須在我的單元測試中做同樣的事情。它們執行速度非常快,創建/抽取數據/銷燬索引需要時間,因此在我移交給各自的test*()方法之前,我撥打了_refresh。而在一些測試中,我在索引數據時,還必須撥打_refresh電話。

通常,在正常操作你不需要調用它不應該。請記住,默認refresh_interval1s。如果您定期更新索引並希望反映次秒更新(例如,我正在討論_search),那就是您需要開始的地方。

+0

感謝您的回答!調用刷新端點一次沒有幫助,但是如果我將它調用兩次,它確實如此。我認爲它與你所說的_space_有關。看起來像ES需要一到兩秒才能真正創建索引。 –

+0

啊我明白了。儘管我知道這個問題,但我走錯了路。你需要等待所有分片的分配 - >我已經更新了答案。對不起:) – mark