Con la evolución de las aplicaciones modernas que sirven cada vez más necesidades de procesamiento y recuperación de datos en tiempo real, la escalabilidad también lo hace. Uno de los motores de búsqueda y análisis distribuidos de código abierto es Elasticsearch, que es muy eficiente en el manejo de datos en conjuntos grandes y consultas de alta velocidad. Sin embargo, el proceso para escalar Elasticsearch de manera efectiva puede ser sutil, ya que se necesita una comprensión adecuada de la arquitectura detrás de él y de los compromisos de rendimiento.
Si bien la naturaleza distribuida de Elasticsearch le permite escalar horizontalmente, esto también introduce más complejidades en cómo se distribuyen los datos y se sirven las consultas. Uno de los desafíos teóricos asociados con la escalabilidad de Elasticsearch es su naturaleza inherentemente distribuida. En la mayoría de los escenarios prácticos, las lecturas en un nodo independiente siempre superarán a las lecturas en un clúster dividido. Esto se debe a que, en un clúster dividido, la propiedad de los datos se distribuye en varios nodos. Esto significa que cada consulta puede tener que enviar múltiples solicitudes a diferentes nodos, agregar los resultados de nuevo en el nodo coordinador y devolver el resultado. Este gasto adicional de red fácilmente resultará en un aumento de la latencia en comparación con una arquitectura de un solo nodo donde el acceso a los datos es directo.
En este sentido, los clústeres divididos son fundamentales para escalar Elasticsearch a conjuntos de datos grandes, alto tráfico e indexación casi en tiempo real. Conocer el equilibrio entre distribuir los datos entre nodos y mantener baja la latencia de consulta es clave para lograr un rendimiento óptimo. Además, el artículo cubre los aspectos teóricos de la escalabilidad de Elasticsearch, estrategias prácticas de optimización del rendimiento del clúster y lecciones aprendidas de experiencias de implementación del mundo real.
En Swoo, nuestra aplicación de transmisión en vivo y juegos, Elasticsearch era la columna vertebral de todas las búsquedas, y funcionaba bien a medida que crecía nuestra base de usuarios. En el momento en que el número de usuarios en paralelo superó los 150,000, la página de búsqueda comenzó a fallar de vez en cuando, y estaba bastante claro que había algún cuello de botella en el clúster de Elasticsearch. Esto pronto se volvió inaceptable para un entorno de juego en vivo y nos llevó a realizar una serie de optimizaciones, que finalmente estabilizaron tanto nuestras experiencias de búsqueda como de página de inicio.
Comprender la Arquitectura de Elasticsearch para la Escalabilidad
Elasticsearch admite nativamente una arquitectura distribuida, lo que hace que el sistema sea altamente escalable pero, al mismo tiempo, más complejo en comparación con las soluciones tradicionales de un solo nodo. Elasticsearch divide los datos en índices, y a su vez, cada índice se divide en fragmentos. El fragmento es la unidad básica de almacenamiento de datos e indexación en Elasticsearch, ya que el sistema distribuye y paraleliza las operaciones de búsqueda en múltiples nodos del clúster.
Un clúster típico contendría varios nodos de datos que alojan un subconjunto de los datos que ejecutan las consultas de búsqueda. De forma predeterminada, Elasticsearch puede distribuir automáticamente los datos entre los nodos, por lo que cada nodo ejecuta solo una parte de la carga de consulta. De esta manera, Elasticsearch escala horizontalmente: procesa más y más datos y atiende más y más solicitudes simplemente agregando nodos a él.
Este compromiso en la escalabilidad con el rendimiento de las consultas es, por supuesto, una de las cosas más importantes a considerar al diseñar clústeres de Elasticsearch, especialmente para aquellas aplicaciones que requieren un alto rendimiento de escritura en combinación con una baja latencia de lectura. Este desafío realmente requiere una configuración cuidadosa del clúster junto con una combinación de técnicas de optimización.
Por lo tanto, en esencia, nuestro clúster de Elasticsearch tenía algunos nodos de datos para el caso de Swoo y tres nodos maestros dedicados. Cada nodo funcionaba en una CPU de 8 núcleos con 16 GB de RAM, principalmente destinados a la indexación en tiempo real y búsquedas instantáneas de los eventos de juegos que tenían lugar. Dado que trabajamos con una alta concurrencia, necesitamos dedicar un ancho de banda de red realmente sustancial para garantizar una latencia mínima entre los nodos.
Planificación de su estrategia de escalado
En otras palabras, escalar Elasticsearch de manera efectiva requiere el análisis de las métricas de rendimiento actuales, la identificación de cuellos de botella y objetivos claros en cuanto a la escalabilidad. Por ejemplo, será excelente monitorear la latencia de las consultas, el rendimiento y la salud del clúster para comprender las limitaciones de su clúster. Podrá crear una hoja de ruta para la optimización identificando fragmentos activos, picos en la CPU y problemas de memoria.
Otra actividad importante que requiere atención al escalar Elasticsearch es la planificación de capacidad. Estimar el uso del disco, el patrón de tráfico y los requisitos de retención de datos garantizará que su clúster tenga el tamaño correcto. En general, la escalabilidad horizontal (agregar nodos al clúster) es generalmente el mejor enfoque para aumentar el volumen de datos y tráfico. En este caso, sin embargo, la escalabilidad vertical-mejorar los recursos de los nodos individuales-puede ser efectiva.
Nuestras proyecciones indicaron un crecimiento de usuarios activos de aproximadamente 10-15% mensual, con cada usuario generando un volumen considerable de datos de eventos durante el uso del juego. Basándonos en estas proyecciones, esperábamos que nuestro clúster mantuviera un aumento saludable en consultas concurrentes junto con un aumento en el volumen de documentos indexados. Por lo tanto, analizamos si escalar horizontalmente agregando más nodos de datos o escalar verticalmente mejorando nuestros nodos actuales sería más adecuado para este aumento.
Técnicas Básicas de Escalabilidad
La optimización de Elasticsearch implicará una serie de estrategias, cada una dirigida a diferentes aspectos del sistema. Entre estas, las técnicas más efectivas incluyen la optimización de la ingestión de datos, la gestión de fragmentos y la optimización del uso de memoria.
Las principales áreas de enfoque serán la ingestión de datos. Elasticsearch admite nativamente la indexación por lotes, lo que significa que puedes enviar lotes de documentos muy grandes en una sola solicitud. Eso reduce la sobrecarga y generalmente acelera el proceso de indexación. En segundo lugar, ajustar el intervalo de actualización puede marcar la diferencia al ingerir datos rápidamente. Puedes sobrescribir el intervalo de actualización predeterminado de un segundo a un valor más alto, digamos, diez segundos, porque eso reducirá el estrés de actualizaciones demasiado frecuentes en tu clúster, y tus escrituras serán más rápidas.
Otras razones clave que conforman la característica de escalabilidad de Elasticsearch incluyen la gestión de fragmentos. Si bien Elasticsearch puede escalar horizontalmente a través del fragmentado, un dimensionamiento inapropiado de los fragmentos en realidad conduce a un rendimiento degradado. Un número de fragmentos demasiado alto o demasiado bajo resulta en una velocidad de indexación y/o rendimiento de consultas degradados. El truco está en el equilibrio para un rendimiento óptimo en Elasticsearch.
Por supuesto, la gestión de memoria es otro factor muy importante en la escalabilidad de Elasticsearch. Definitivamente reduces el consumo de recursos y mejoras el rendimiento de tus consultas optimizando el tamaño del heap de JVM, configurando la caché de datos de campo y habilitando la caché de consultas. El uso adecuado de la memoria y la configuración adecuada de la caché pueden evitar errores de falta de memoria y minimizar la sobrecarga de la recolección de basura.
Una buena cantidad de la carga de Elasticsearch se debía a la ingestión continua de datos de juegos en tiempo real. Optimizamos los pipelines de ingestión mediante la agrupación de documentos a través de la API de Bulk. En períodos de carga pico específica, podríamos aumentar aún más el tamaño de los lotes y aumentar el período de actualización para lograr un equilibrio adecuado entre la indexación casi en tiempo real y la estabilidad general del clúster.
Soluciones Avanzadas de Escalabilidad
Cuando la escala se vuelve enorme, Elasticsearch requiere técnicas más avanzadas para ser eficiente. Entre ellas, la optimización de consultas se destaca. También puedes reducir en gran medida la latencia de las consultas escribiendo consultas eficientes que minimicen el número de fragmentos que están involucrados en la búsqueda. Por ejemplo, puedes hacer enrutamiento personalizado para dirigir las consultas a los fragmentos específicos utilizando una clave, como el ID del cliente o la categoría del producto. Esto evita que Elasticsearch busque en todos los fragmentos; por lo tanto, se reduce el tiempo y los recursos utilizados.
ILM, o Gestión del Ciclo de Vida del Índice, es otra característica impresionante para ajustar Elasticsearch a medida que tus datos envejecen. Podrás mover datos más antiguos a un almacenamiento más lento y económico mientras mantienes los más relevantes en un almacenamiento más rápido y accesible mediante la escalabilidad de una arquitectura caliente-cálido-frío. Esto mantiene un gran rendimiento del clúster a medida que este crece.
Los temas finales de discusión sobre la escalabilidad de Elasticsearch son consideraciones de hardware. A medida que tu clúster crezca, querrás asegurarte de que el hardware esté debidamente provisionado para la carga aumentada. Esto significaría asegurarse de que los nodos tengan CPU, memoria y E/S de disco apropiados para operar eficientemente. Las unidades SSD o NVMe mejorarán en gran medida el rendimiento, especialmente para operaciones de indexación y búsqueda, que requieren altas velocidades de acceso a los datos.
Una de las lecciones aprendidas fue que asignar solo el recuento de fragmentos predeterminado a los índices más nuevos nos llevaría a problemas de concentración de carga. También encontramos un punto óptimo donde ningún fragmento estaba realmente sobrecargado con la mayor parte de las actualizaciones en tiempo real provenientes de nuestra plataforma de juegos al redistribuir los índices de escritura intensiva en múltiples fragmentos más pequeños, ajustando las réplicas en consecuencia.
Perspectivas Teóricas y Compensaciones de Optimización
Además de las optimizaciones prácticas anteriores, hay algunas consideraciones teóricas interesantes para escalar Elasticsearch. Una idea clave implica compensaciones entre escalabilidad y rendimiento de consultas dentro de un sistema distribuido. En particular, se señala que si bien los clústeres fragmentados son horizontalmente escalables, aumentan la sobrecarga de consultas porque los resultados de múltiples nodos deben combinarse. Esto contrasta con un solo nodo donde los datos residen en la máquina local y las consultas pueden ejecutarse sin tener que ‘hablar’ con otros nodos. Comprender esta compensación es importante si se diseña un clúster de Elasticsearch que necesita equilibrar el rendimiento con la escalabilidad.
Otro aspecto más teórico de escalar Elasticsearch es el concepto de localidad de datos. Puede ejecutar consultas solo contra el nodo local que alberga los datos de fragmento relevantes utilizando el parámetro de consulta preference=local
. Esto minimiza la comunicación entre nodos y reduce la latencia de la consulta. Esto puede disminuir los desafíos que provienen de la replicación de datos y el equilibrio de carga. El algoritmo de Selección de Réplica Adaptativa de Elasticsearch intenta optimizar la ejecución de consultas eligiendo el mejor nodo de réplica según las condiciones actuales. Sin embargo, no necesariamente garantiza la ejecución más efectiva de una consulta.
La primera oleada de fallos que hemos experimentado en nuestro entorno se relaciona con una alta presión en la memoria heap de JVM. Los servidores de Elasticsearch funcionaban inicialmente con asignaciones mínimas de heap, lo que resultaba en ciclos de recolección de basura bastante frecuentes bajo una carga de consultas elevada. Resolvimos esto ajustando la JVM, en particular alineando el tamaño mínimo y máximo de heap a 8 GB, lo que le dio a Elasticsearch suficiente espacio para procesar consultas sin sobrecargar la memoria heap.
Errores Comunes y Soluciones
Por supuesto, escalar Elasticsearch no está exento de desafíos. Entre los errores comunes que una persona querría evitar se encuentran un dimensionamiento deficiente de los fragmentos, la falta de monitoreo, depender demasiado de la caché y no utilizar una Gestión de Ciclo de Vida de Índices adecuada. Estos ahorran mucho tiempo y recursos si se diagnostican temprano mediante una configuración proactiva.
Uno de los principales errores fue no ajustar la configuración predeterminada de Elasticsearch, tanto en cuanto a la asignación de memoria como a la gestión de fragmentos. Los valores predeterminados funcionaban bien bajo condiciones de tráfico moderadas pero fallaban bajo tráfico pico. Nuestra solución fue multietapa: revisó la asignación de heap, la replicación de índices en caliente y la caché a corto plazo para consultas repetidas. En conjunto, evitó fallos repetidos en todo el clúster y redujo significativamente los tiempos de espera.
Guía de Implementación en el Mundo Real
Escalar Elasticsearch implicará planificación, pruebas, implementación y mantenimiento posterior. Por lo tanto, seguir buenas prácticas, plantillas de configuración y realizar pruebas exhaustivas en su clúster antes de implementar nuevos cambios en producción proporcionará un escalado sin problemas hacia un clúster estable a largo plazo.
- Ajuste fino de los parámetros de JVM. Configuramos tanto Xms como Xmx en 8 GB en cada servidor de Elasticsearch, logrando un equilibrio entre la memoria del sistema disponible y los requisitos de la heap.
- Optimización de la distribución de shards. Los índices grandes se dividieron en shards de menor tamaño para evitar puntos críticos y escalar réplicas para los índices más activos. Esto aseguró que el tráfico de consultas se distribuyera uniformemente en todo el clúster.
- Activar el almacenamiento en caché de corta duración. Aplicamos una ventana de caché de 1 segundo en consultas estáticas frecuentemente utilizadas en la página de inicio y notamos que esto reduce considerablemente la carga en Elasticsearch para solicitudes repetitivas sin perder capacidad de respuesta en tiempo real.
- Monitoreo e iteración. Utilizamos Kibana, con algunos paneles personalizados para la observación en tiempo real de la salud de los shards, el rendimiento de la JVM y las latencias de las consultas. Con base en estas métricas, se realizaron ajustes continuamente.
Planes futuros o expansiones en la pila tecnológica
Además, para el crecimiento, nos gustaría explorar la gestión de un ciclo de vida de índice caliente-tibio-frío moviendo datos menos accesibles con frecuencia a nodos más económicos mientras mantenemos hardware de primera categoría para indexación y consultas en tiempo real. Estamos considerando soluciones avanzadas de monitoreo y detección de anomalías impulsadas por IA para asegurarnos de que los picos o ralentizaciones en consultas inusuales se detecten con suficiente antelación para no afectar la experiencia del usuario.
Conclusión
La escalabilidad de Elasticsearch requiere comprender la arquitectura, una planificación cuidadosa y la implementación de las mejores prácticas. A pesar de que Elasticsearch se escala horizontalmente a través de fragmentación, presenta varios desafíos que deben ser controlados para un rendimiento óptimo. La alta escalabilidad y rendimiento de un clúster de Elasticsearch pueden garantizarse mediante una adecuada ingestión de datos, gestión de fragmentos, uso de memoria y optimización de consultas.
Si bien la migración a Elasticsearch también fue necesaria para Solr en nuestro caso, sin lugar a dudas, además de las cuestiones puramente técnicas, se hizo una importante contribución en cuanto a comprender las dificultades teóricas que realmente están ocultas en los Sistemas Distribuidos. Este tipo de ajustes cuidadosos y la resolución creativa de problemas podrían permitir un crecimiento significativo: un clúster de Elasticsearch único de varios proveedores, que debería recibir millones de consultas al día al mejorar su rendimiento de consulta con tiempos de respuesta considerablemente reducidos. Los elementos teóricos y prácticos se mezclan al escalar la implementación de Elasticsearch para garantizar el éxito a largo plazo.
Source:
https://dzone.com/articles/how-to-scale-elasticsearch-to-solve-scalability-issues