Limit czasu połączenia z Elasticsearch

86
from datetime import datetime
from elasticsearch import Elasticsearch
es = Elasticsearch()

doc = {
    'author': 'kimchy',
    'text': 'Elasticsearch: cool. bonsai cool.',
    'timestamp': datetime(2010, 10, 10, 10, 10, 10)
}
res = es.index(index="test-index", doc_type='tweet', id=1, body=doc)
print(res['created'])

Ten prosty kod zwraca następujący błąd:

elasticsearch.exceptions.ConnectionTimeout: ConnectionTimeout caused by - ReadTimeoutError(HTTPConnectionPool(host='localhost', port=9200): Read timed out. (read timeout=10))

Bardzo dziwne, ponieważ serwer jest gotowy i ustawiony ( http: // localhost: 9200 / zwraca jakiś plik json).

Johann Gomes
źródło

Odpowiedzi:

92

Domyślnie wartość limitu czasu jest ustawiona na 10 sekund. Jeśli ktoś chce zmienić globalną wartość limitu czasu, można to osiągnąć ustawiając flagę timeout = twój-czas podczas tworzenia obiektu.

Jeśli obiekt został już utworzony bez określenia wartości limitu czasu, możesz ustawić wartość limitu czasu dla konkretnego żądania, używając w zapytaniu flagi request_timeout = your-time .

es.search(index="my_index",
          doc_type="document",
          body=get_req_body(),
          request_timeout=30)
Rahul
źródło
Czy można to ustawić na 60? Dostaję limit czasu nawet po ustawieniu go na 30
Kishan Mehta
@Kishan, jak duże jest twoje ciało dokumentu?
Rohit Patwa
Cześć, @RohitPatwa, mój problem został rozwiązany poprzez zmniejszenie długości dokumentu. Nie pamiętam, jak duże było teraz ciało. Dzięki za pomoc :)
Kishan Mehta
1
Co jeśli mój szef nie pozwoli mi zmienić limitu czasu i nie powiedzie się przy jednym nagraniu?
Jonathan Rys
19

Jeśli korzystasz z usługi Amazon Elastic Search, może wystąpić problem z przekroczeniem limitu czasu połączenia.

es = Elasticsearch([{'host': 'xxxxxx.us-east-1.es.amazonaws.com', 'port': 443,  'use_ssl': True}])

Powyższy kod w Pythonie, w którym nadpisujesz domyślny port z 9200 na 443 i ustawiasz SSL na true, rozwiąże problem.

Jeśli nie określono portu, próba nawiązania połączenia z portem 9200 w określonym hoście kończy się niepowodzeniem po przekroczeniu limitu czasu

Mukund
źródło
Lub możesz użyć portu 80 es = Elasticsearch ([{'host': 'xxxxxx.us-east-1.es.amazonaws.com', 'port': 80}])
Olga Achmetowa
5

Nie ma to nic wspólnego ze zwiększeniem limitu czasu do 30 sekund. Czy ludzie rzeczywiście myślą, że wyszukiwanie elastyczne powinno potrzebować nawet 30 sekund, aby zwrócić jedno małe trafienie?

Sposób, w jaki naprawiłem ten problem, to przejście do config / flexiblesearch.yml odkomentuj następujące

http.port: 9200
network.host: 'localhost' 

Network.host może być ustawiony na 192.168.0.1, co może działać, ale właśnie zmieniłem go na „localhost”

whoopididoo
źródło
18
Jeśli serwer jest zbyt zajęty, tak, możesz mieć ten błąd jednym małym trafieniem.
ᐅ devrimbaris
lub jeśli występuje problem z rozwiązywaniem DNS, jest wiele przyczyn
przekroczenia
5

Zauważ, że jednym z typowych powodów przekroczenia limitu czasu podczas wykonywania es.search(lubes.index ) jest duży rozmiar zapytania. Na przykład w moim przypadku dość dużego rozmiaru indeksu ES (> 3M dokumentów) wyszukanie zapytania zawierającego 30 słów zajęło około 2 sekund, podczas gdy wyszukiwanie zapytania zawierającego 400 słów zajęło ponad 18 sekund. Więc dla wystarczająco dużego zapytania nawet timeout = 30 nie uratuje cię. Łatwym rozwiązaniem jest przycięcie zapytania do rozmiaru, na który można odpowiedzieć poniżej limitu czasu.

Zwiększenie limitu czasu lub wykonanie ponownych prób po przekroczeniu limitu czasu pomoże Ci, jeśli przyczyną był ruch, w przeciwnym razie może to być Twój winowajca.

vlyubin
źródło
5

Spróbuj ustawić limit czasu podczas inicjalizacji Elasticsearch:

es = Elasticsearch([{'host': HOST_ADDRESS, 'port': THE_PORT}], timeout=30)

Można nawet ustawić retry_on_timeoutsię Truei podać max_retriesnumer opcjonalne:

es = Elasticsearch([{'host': HOST_ADDRESS, 'port': THE_PORT}], timeout=30, max_retries=10, retry_on_timeout=True)
Alex Jolig
źródło
3

elasticsearch.exceptions.ConnectionTimeout: ConnectionTimeout caused by - ReadTimeoutError(HTTPConnectionPool(host='localhost', port=9200): Read timed out. (read timeout=10)) oznacza, że ​​żądanie nie zakończyło się w określonym czasie (domyślnie limit czasu = 10).

To zadziała przez 30 sekund:

res = es.index(index="test-index", doc_type='tweet', id=1, body=doc, timeout=30)

Mir Ilias
źródło
1

mój osobisty problem został rozwiązany, z (timeout = 10000)którym praktycznie nigdy nie został osiągnięty, ponieważ wpisy na serwerze były tylko 7.000 ale miał duży ruch i jego zasoby były zapchane i dlatego połączenie było przerywane

GGEv
źródło
1

Przyczyn przekroczenia limitu czasu może być wiele i wydaje się, że warto sprawdzić dzienniki po stronie Elasticsearch ( logs/elasticsearch.log), aby zobaczyć szczegółowy błąd. W naszym przypadku błąd na ES to:

primary shard is not active Timeout: [1m]

Jak opisano w tym poście , było to spowodowane tym, że nasz dysk był pełny. Zmieniliśmy jego rozmiar (i partycję) dzień temu, aby się tym zająć, ale ES musi zostać ponownie uruchomiony, jeśli znak wodny wysokiego / niskiego został raz trafiony (jesteśmy na 5.5.x), czego nie zrobiliśmy.

Po prostu ponowne uruchomienie ES na produkcji rozwiązało problem.

Anupam
źródło
0

Dwie pomocne opcje:

1: zwiększ limit czasu

Ustawienie limitu czasu rozwiązało ten problem. Pamiętaj, że nowsze wersje wymagają jednostki, np . timeout="60s":

es.index(index=index_name, doc_type="domains", id=domain.id, body=body, timeout="60s")

Bez jednostki, na przykład przez ustawienie timeout=60, otrzymasz

elasticsearch.exceptions.RequestError: RequestError(400, 'illegal_argument_exception', 'failed to parse setting [timeout] with value [60] as a time value: unit is missing or unrecognized')

2: zmniejsz długość tekstu

Pomaga również zmniejszyć długość tekstu, np. Poprzez wycinanie długich tekstów, dzięki czemu elastyczny może szybciej przechowywać tekst, co również pozwoli uniknąć przekroczenia limitów czasu:

es.index(index=index_name, doc_type="domains", id=domain.id, body=text[:5000], timeout="60s")
lorey
źródło
To nie zadziała, ponieważ błąd nadal występuje, podając wartość limitu czasu jako 10
Alex Jolig