Ingeniería

Mejores prácticas de autodescubrir de Elasticsearch: Qué, cuándo, por qué, cómo

Elasticsearch impulsa experiencias de búsqueda para muchas de las herramientas y apps que se usan en la actualidad, desde dashboards analíticos operativos hasta mapas que muestran los restaurantes más cercanos con patio para que puedas salir de tu casa. Y en todas esas implementaciones, la conexión entre la aplicación y el cluster se hace a través de un cliente Elasticsearch.

Optimizar la conexión entre el cliente y el cluster de Elasticsearch es sumamente importante para la experiencia del usuario final. La configuración típica de un cliente Elasticsearch es la URL del nodo al que debes conectarte. Pero puedes hacer mucho más, y una forma de optimizar esta conexión es con autodescubrir.

Aquí explicamos cómo funciona autodescubrir, cuándo debes usarlo y cómo saber cuándo debes evitarlo.

¿Qué es autodescubrir?

Elasticsearch es un sistema distribuido, lo que significa que sus índices residen en varios nodos conectados entre sí, que forman un cluster. Una de las principales ventajas de ser un sistema distribuido, además de la tolerancia a fallas, es que los datos se dividen en shards en varios nodos, lo que permite que las búsquedas se ejecuten mucho más rápido que aquellas que se ejecutan en un único nodo enorme.

Una configuración de cliente típico es una sola URL que apunta a un nodo del cluster de Elasticsearch. Si bien esta es la configuración más simple, la principal desventaja de esta configuración es que todas las solicitudes que realices se enviarán a ese nodo de coordinación específico. Como esto pone un solo nodo bajo estrés, el rendimiento general puede verse afectado.

Una solución es pasar una lista estática de nodos al cliente, de modo que tus solicitudes se distribuyan de forma equitativa entre los nodos.

O puedes habilitar una característica llamada autodescubrir.

Con una lista estática de nodos, no hay garantías de que los nodos estén siempre en funcionamiento. Por ejemplo, ¿qué sucede si quitas un nodo para actualizarlo o agregas nodos nuevos?

Si habilitas autodescubrir, el cliente comenzará a llamar el endpoint _nodes/_all/http, y la respuesta será una lista de todos los nodos presentes en el cluster junto con sus direcciones IP. Luego, el cliente actualizará su grupo de conexiones para usar todos los nodos nuevos y mantener el estado del cluster sincronizado con el grupo de conexiones del cliente. Ten en cuenta que incluso si los clientes descargan la lista completa de nodos, los nodos "solo maestro" no se usarán para llamadas de API genéricas.

Autodescubrir resuelve este problema de descubrimiento. ¿Por qué no está habilitado de forma predeterminada? Gran pregunta.

¿Cuándo autodescubrir?

Autodescubrir puede ser un arma de doble filo. Si intentas llamar el endpoint _nodes/_all/http, verás una lista de nodos y sus endpoints respectivos. Pero hay algunas cuestiones que debes tener en cuenta:

  • ¿Qué sucede si tu cluster de Elasticsearch reside en su propia red?
  • ¿Qué sucede si tu cluster de Elasticsearch reside detrás de un balanceador de carga?

La respuesta corta a ambas preguntas: obtendrás direcciones IP completamente inútiles porque estarás en una red diferente.

Puedes probar esto por tu cuenta con Docker. Activa una instancia de Elasticsearch (una es suficiente) y llama _nodes/_all/http desde tu máquina local. Verás que la dirección IP de tu nodo no será la misma dirección IP que acabas de usar.

Úsala con el comando siguiente para iniciar una instancia de Elasticsearch:

docker run \ 
-p 9200:9200 \
-e "discovery.type=single-node" \
docker.elastic.co/elasticsearch/elasticsearch:7.8.0

Ahora puedes leer la IP del nodo con el comando siguiente. (En el fragmento siguiente usamos jq para que sea más fácil leer la respuesta.):

curl -s localhost:9200/_nodes/_all/http | jq .nodes[].http.publish_address

Por último, puedes copiar la dirección IP impresa en la terminal e intentar enviarle una solicitud:

curl {ip_address}:9200 | jq .

Como puedes ver, no obtendrás una respuesta exitosa.

Esto significa que si habilitas autodescubrir en un cliente mientras el cluster se encuentra en otra red, el cliente agregará todos los nodos nuevos a su grupo de conexiones. Eso es porque no tiene forma de comprender que esas direcciones IP están mal, y cada búsqueda que se realice en uno de esos nodos fallará.

Como el nodo inicial con la dirección IP correcta ya no está en el estado del cluster, se descartará, y recibirás rápidamente un error "no living connections" (sin conexiones activas).

Pero podemos solucionarlo.

Para resolver este problemas, puedes configurar Elasticsearch para que se vincule a su host, pero que publicite otro. La opción de configuración http.publish_host hace precisamente esto. Ahora, intenta ejecutar el comando de Docker anterior con esta nueva configuración:

docker run \ 
-p 9200:9200 \
-e "discovery.type=single-node" \
-e "http.publish_host=localhost" \
docker.elastic.co/elasticsearch/elasticsearch:7.8.0

Si vuelves a ejecutar el comando siguiente:

curl -s localhost:9200/_nodes/_all/http | jq .nodes[].http.publish_address

En la terminal, verás:

"localhost/{ip_address}:9200"

Si configuras el host de publicación, los clientes oficiales (a partir de v7 en adelante) son lo suficientemente inteligentes como para usar la dirección del host en lugar de la IP.

La principal enseñanza de esto es que debes conocer tu infraestructura antes de habilitar autodescubrir. Existen muchas soluciones para este problema de direcciones IP, y no hay una solución única, porque dependerá de la configuración de tu sistema.

La configuración típica de desarrollo es tener un cluster de Elasticsearch en la misma red de tu cliente, pero esto no se puede replicar en el mundo real, dado que derivaría en problemas de seguridad; y tu infraestructura probablemente sea más compleja. Podrías configurar el balanceador de carga para que se ocupe de esas direcciones IP. O, como hace Elastic en Elastic Cloud, puedes dejar que el proxy se ocupe de los nodos con fallas, de modo que el cliente envíe siempre las búsquedas al proxy, que luego las enviará al nodo adecuado.

¿Cuándo no autodescubrir?

Hay muchas situaciones en las cuales autodescubrir podría generar problemas, entre ellas:

  • El usuario de Elasticsearch con el que se está autenticando tu cliente no tiene los permisos correctos (rol monitoring_user) para acceder a la API de nodos.
  • Estás trabajando con Proveedores Cloud.

Por lo general, los Proveedores Cloud ocultan Elasticsearch detrás de un proxy, lo cual haría que la operación de autodescubrir resulte inútil porque las direcciones y los nombres de host devueltos pueden no tener ningún significado en tu red. Habitualmente, esos Proveedores Cloud se ocupan por ti de la complejidad de crear grupos y autodescubrir, por lo que no tienes que habilitarlas.

Si usas Elastic Cloud, los clientes oficiales interrumpirán la mayoría de las operaciones de forma interna, como ocuparse del grupo de conexiones, para evitar dedicar tiempo a operaciones que ya se realizaron.

Otros problemas, como vimos antes, pueden suceder al trabajar con Docker o Kubernetes. A menos que configures la opción de publicar host, el resultado de autodescubrir no podrá usarse.

Como regla general: si Elasticsearch reside en una red diferente a la del cliente (o hay un balanceador de carga), autodescubrir debe estar deshabilitado a menos que haya cierta configuración en la infraestructura que te permita usarla con precisión.

¿Cómo autodescubrir?

Los clientes ofrecen varias estrategias de autodescubrir. Analicémoslas:

Autodescubrir al inicio

Tal como lo sugiere el nombre, al habilitar esta opción, el cliente intentará ejecutar una solicitud de autodescubrimiento solo una vez durante el primer uso o la inicialización del cliente.

Autodescubrir por una falla de conexión

Si habilitas esta opción, el cliente intentará ejecutar una solicitud de autodescubrimiento cada vez que un nodo tenga fallas, lo que significa una conexión interrumpida o un nodo inactivo.

Intervalo de autodescubrimiento

Además de autodescubrir al inicio y por fallas, autodescubrir de forma periódica puede ser beneficioso en situaciones en las que los clusters suelen escalarse horizontalmente durante las horas pico. una aplicación puede tener una visión de buen estado de un subconjunto de los nodos. Pero sin autodescubrir periódicamente, nunca encontrará los nodos que se agregaron como parte del escalado horizontal.

Configuraciones personalizadas

En algunos casos, es posible que quieras tener un control más detallado del procedimiento de autodescubrir. Los clientes son lo suficientemente flexibles para permitirte configurar un endpoint de autodescubrir personalizado, o puedes anular la lógica de autodescubrir por completo y proporcionar una propia.

Conclusiones

Al habilitar autodescubrir, harás que tu aplicación sea más resistente y capaz de adaptarse a los cambios. Antes de hacerlo, debes conocer tu infraestructura para poder decidir cuál es la mejor solución que puedes adoptar. Incluso, es posible que la mejor solución sea no adoptar autodescubrir.

Si te gustaría evitar pensar sobre la configuración del grupo de conexiones y autodescubrir, y preferirías una cadena de conexión simple, dale una oportunidad a Elastic Cloud con la prueba gratuita de 14 días de nuestro Elasticsearch Service.