Тайм-аут подключения с 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'])

Этот простой код возвращает следующую ошибку:

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

Очень странно, потому что сервер готов и настроен ( http: // localhost: 9200 / возвращает какой-то json).

Иоганн Гомес
источник

Ответы:

92

По умолчанию значение тайм-аута составляет 10 секунд. Если кто-то хочет изменить значение глобального тайм-аута, этого можно достичь, установив флаг timeout = your-time при создании объекта.

Если вы уже создали объект без указания значения тайм-аута, вы можете установить значение тайм-аута для конкретного запроса, используя в запросе флаг request_timeout = your-time .

es.search(index="my_index",
          doc_type="document",
          body=get_req_body(),
          request_timeout=30)
Рахул
источник
Можно ли установить значение 60? у меня тайм-аут даже после установки 30
Кишан Мета
@Kishan, насколько велик твой документ?
Рохит Патва
Привет, @RohitPatwa, моя проблема была решена уменьшением длины документа. Я не помню, насколько большим было тело прямо сейчас. Спасибо за помощь :)
Кишан Мета
1
Что, если мой босс не позволит мне изменить тайм-аут, и он не справится с одной записью?
Джонатан Рис,
19

Проблема с тайм-аутом подключения может возникнуть, если вы используете службу Amazon Elastic Search.

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

Приведенный выше код Python, в котором вы переопределяете порт по умолчанию с 9200 на 443 и устанавливаете для SSL значение true, решит проблему.

Если порт не указан, он пытается подключиться к порту 9200 на указанном хосте и завершается неудачно по истечении времени ожидания.

Мукунд
источник
Или вы можете использовать порт 80 es = Elasticsearch ([{'host': 'xxxxxx.us-east-1.es.amazonaws.com', 'port': 80}])
Ольга Ахметова
5

Это не имеет ничего общего с увеличением тайм-аута до 30 секунд. Неужели люди действительно думают, что эластичному поиску требуется до 30 секунд, чтобы вернуть один крошечный результат?

Я исправил эту проблему в config / elasticsearch.yml, раскомментируйте следующие

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

Network.host может быть установлен на 192.168.0.1, что может работать, но я просто изменил его на localhost

гудок
источник
18
Если сервер слишком занят, да, вы можете получить эту ошибку одним крошечным попаданием.
ᐅ devrimbaris
или если есть проблема с разрешением DNS, есть много причин для тайм-аута
Ethranes
4

Обратите внимание, что одна из распространенных причин тайм-аутов при выполнении es.search(илиes.index ) является большой размер запроса. Например, в моем случае довольно большого размера индекса ES (> 3 млн документов) поиск запроса с 30 словами занял около 2 секунд, а поиск запроса с 400 словами занял более 18 секунд. Так что для достаточно большого запроса даже timeout = 30 не спасет. Простое решение - обрезать запрос до размера, на который можно будет ответить ниже тайм-аута.

Увеличение тайм-аута или повторных попыток по таймауту поможет вам, если причина была в пробке, иначе это может быть вашим виновником.

влюбин
источник
4

Попробуйте установить тайм-аут в инициализации Elasticsearch:

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

Вы даже можете установить retry_on_timeoutна Trueи дать max_retriesдополнительный номер:

es = Elasticsearch([{'host': HOST_ADDRESS, 'port': THE_PORT}], timeout=30, max_retries=10, retry_on_timeout=True)
Алекс Джолиг
источник
3

elasticsearch.exceptions.ConnectionTimeout: ConnectionTimeout caused by - ReadTimeoutError(HTTPConnectionPool(host='localhost', port=9200): Read timed out. (read timeout=10)) означает, что запрос не завершился в указанное время (по умолчанию тайм-аут = 10).

Это будет работать с 30 секундами:

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

Мир Илиас
источник
1

моя личная проблема была решена, с (timeout = 10000)которой практически никогда не было достигнуто, потому что записей на сервере было всего 7.000, но у него был большой трафик, и его ресурсы были перегружены, и поэтому соединение прерывалось

ГГЕв
источник
1

Причин тайм-аута может быть много, и, похоже, стоит проверить журналы на стороне elasticsearch ( logs/elasticsearch.log), чтобы увидеть подробную ошибку. В нашем случае ошибка на ES была:

primary shard is not active Timeout: [1m]

Как описано в этом посте , это произошло потому, что наш диск был заполнен. Мы изменили его размер (и раздел) день назад, чтобы позаботиться об этом, но ES необходимо перезапустить, если водяной знак высокого / низкого уровня был достигнут один раз (мы на 5.5.x), чего мы не сделали.

Простой перезапуск ES в производственной среде решил проблему для нас.

Анупам
источник
0

Два варианта, которые помогут:

1: увеличить тайм-аут

Установка тайм-аута решила для меня эту проблему. Обратите внимание, что более новым версиям требуется модуль, например timeout="60s":

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

Без юнита, например установив timeout=60, вы получите

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: уменьшить длину текста

Это также помогает уменьшить длину текста, например, путем вырезания длинных текстов, чтобы эластичный текст мог быстрее сохранять текст, что также позволит избежать тайм-аутов:

es.index(index=index_name, doc_type="domains", id=domain.id, body=text[:5000], timeout="60s")
лори
источник
Это не сработает, так как ошибка все еще существует с указанием значения тайм-аута как 10
Alex Jolig