Tiempo de espera de conexión con Elasticsearch

84
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'])

Este código simple devuelve el siguiente error:

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

Muy extraño, porque el servidor está listo y configurado ( http: // localhost: 9200 / está devolviendo algo de json).

Johann Gomes
fuente

Respuestas:

91

De forma predeterminada, el valor de tiempo de espera se establece en 10 segundos. Si se desea cambiar el valor de tiempo de espera global, esto se puede lograr configurando el indicador timeout = your-time mientras se crea el objeto.

Si ya ha creado el objeto sin especificar el valor de tiempo de espera, puede establecer el valor de tiempo de espera para una solicitud en particular utilizando el indicador request_timeout = your-time en la consulta.

es.search(index="my_index",
          doc_type="document",
          body=get_req_body(),
          request_timeout=30)
Rahul
fuente
¿Se puede establecer en 60? Tengo tiempo de espera incluso después de configurarlo 30
Kishan Mehta
@Kishan ¿Qué tan grande es tu cuerpo de doc?
Rohit Patwa
Hola, @RohitPatwa, mi problema se resolvió reduciendo la longitud del documento. No recuerdo qué tan grande era el cuerpo en este momento. Gracias por la ayuda :)
Kishan Mehta
¿Qué pasa si mi jefe no me deja cambiar el tiempo de espera y falla en un solo registro?
Jonathan Rys
18

El problema de tiempo de conexión agotado podría ocurrir si está utilizando el servicio Amazon Elastic Search.

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

El código de Python anterior en el que anula el puerto predeterminado de 9200 a 443 y establece el SSL en verdadero resolverá el problema.

Si no se especifica ningún puerto, está intentando conectarse al puerto 9200 en el host especificado y falla después del tiempo de espera

Mukund
fuente
O puede usar el puerto 80 es = Elasticsearch ([{'host': 'xxxxxx.us-east-1.es.amazonaws.com', 'port': 80}])
Olga Akhmetova
6

Esto no tiene nada que ver con aumentar el tiempo de espera a 30 segundos. ¿La gente realmente piensa que la búsqueda elástica debería necesitar hasta 30 segundos para devolver un pequeño acierto?

La forma en que solucioné este problema fue ir a config / elasticsearch.yml y descomentar lo siguiente

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

Network.host podría estar configurado en 192.168.0.1, lo que podría funcionar, pero lo acabo de cambiar a 'localhost'

whoopididoo
fuente
17
Si el servidor está demasiado ocupado, sí, puede tener este error con un pequeño golpe.
ᐅ devrimbaris
o si hay un problema con la resolución de DNS, hay muchas razones para un tiempo de espera
Ethranes
4

Tenga en cuenta que una de las razones más comunes por las que se agota el tiempo de espera al realizar es.search(o es.index) es un tamaño de consulta grande. Por ejemplo, en mi caso de un índice ES bastante grande (> 3M de documentos), realizar una búsqueda de una consulta con 30 palabras tomó alrededor de 2 segundos, mientras que realizar una búsqueda de una consulta con 400 palabras tomó más de 18 segundos. Entonces, para una consulta lo suficientemente grande, incluso el tiempo de espera = 30 no lo salvará. Una solución sencilla es recortar la consulta al tamaño que se pueda responder por debajo del tiempo de espera.

Aumentar el tiempo de espera o hacer reintentos en el tiempo de espera le ayudará si la causa fue el tráfico; de lo contrario, este podría ser el culpable.

vlyubin
fuente
3

elasticsearch.exceptions.ConnectionTimeout: ConnectionTimeout caused by - ReadTimeoutError(HTTPConnectionPool(host='localhost', port=9200): Read timed out. (read timeout=10)) significa que la solicitud no terminó en el tiempo especificado (por defecto, tiempo de espera = 10).

Esto funcionará con 30 segundos:

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

Mir Ilias
fuente
2

Intente configurar el tiempo de espera en la inicialización de Elasticsearch:

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

Incluso puede configurar retry_on_timeoutpara Truey dar al max_retriesun número opcional:

es = Elasticsearch([{'host': HOST_ADDRESS, 'port': THE_PORT}], timeout=30, max_retries=10, retry_on_timeout=True)
Alex Jolig
fuente
1

se resolvió mi problema personal con el (timeout = 10000)que prácticamente nunca se alcanzó porque las entradas en el servidor eran solo 7.000 pero tenía mucho tráfico y sus recursos estaban siendo acaparados y por eso la conexión se estaba cayendo

GGEv
fuente
1

Las razones del tiempo de espera pueden ser muchas y parece que vale la pena revisar los registros en el lado de elasticsearch ( logs/elasticsearch.log) para ver el error detallado. En nuestro caso, el error en ES fue:

primary shard is not active Timeout: [1m]

Como se describe en esta publicación , esto se debió a que nuestro disco estaba lleno. Lo habíamos redimensionado (y la partición) hace un día para encargarnos de eso, pero ES debe reiniciarse si la marca de agua alta / baja se ha tocado una vez (estamos en 5.5.x) lo cual no habíamos hecho.

Simplemente reiniciar el ES en producción nos resolvió el problema.

Anupam
fuente
0

Dos opciones que ayudan:

1: aumenta el tiempo de espera

Establecer un tiempo de espera resolvió este problema para mí. Tenga en cuenta que las versiones más nuevas necesitan una unidad, por ejemplo timeout="60s":

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

Sin una unidad, por ejemplo timeout=60, configurando , obtendrá

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: reducir la longitud del texto

También ayuda a reducir la longitud del texto, por ejemplo, cortando textos largos, de modo que elástico pueda almacenar el texto más rápido, lo que también evitará tiempos de espera:

es.index(index=index_name, doc_type="domains", id=domain.id, body=text[:5000], timeout="60s")
Lorey
fuente
Esto no funcionará ya que el error sigue ahí indicando el valor de tiempo de espera como 10
Alex Jolig