Clúster de Elasticsearch de 200 TB+

Clúster de Elasticsearch de 200 TB+

Mucha gente tiene problemas con Elasticsearch. Pero, ¿qué sucede cuando desea utilizarlo para almacenar registros “en un volumen particularmente grande”? ¿Y también es indoloro experimentar el fallo de cualquiera de varios centros de datos? ¿Qué tipo de arquitectura debería hacer y con qué obstáculos se encontrará?

En Odnoklassniki decidimos utilizar elasticsearch para resolver el problema de la gestión de registros y ahora compartimos nuestra experiencia con Habr: tanto sobre arquitectura como sobre dificultades.

Soy Pyotr Zaitsev, trabajo como administrador de sistemas en Odnoklassniki. Antes de eso, también fui administrador, trabajé con Manticore Search, Sphinx Search y Elasticsearch. Quizás, si aparece otra búsqueda, probablemente trabaje con ella también. También participo en varios proyectos de código abierto de forma voluntaria.

Cuando llegué a Odnoklassniki, dije imprudentemente en la entrevista que podía trabajar con Elasticsearch. Después de dominarlo y completar algunas tareas simples, se me asignó la gran tarea de reformar el sistema de administración de registros que existía en ese momento.

Requisitos

Los requisitos del sistema se formularon de la siguiente manera:

  • Graylog iba a utilizarse como interfaz. Debido a que la empresa ya tenía experiencia en el uso de este producto, los programadores y evaluadores lo conocían, les resultaba familiar y conveniente.
  • Volumen de datos: en promedio, entre 50 y 80 mil mensajes por segundo, pero si algo se rompe, el tráfico no está limitado por nada, puede ser de 2 a 3 millones de líneas por segundo.
  • Después de discutir con los clientes los requisitos para la velocidad de procesamiento de las consultas de búsqueda, nos dimos cuenta de que el patrón típico de uso de dicho sistema es el siguiente: las personas buscan registros de su aplicación durante los últimos dos días y no quieren esperar más de un segundo para el resultado de una consulta formulada.
  • Los administradores insistieron en que el sistema fuera fácilmente escalable si fuera necesario, sin necesidad de profundizar en su funcionamiento.
  • De modo que la única tarea de mantenimiento que estos sistemas requieren periódicamente es cambiar algún hardware.
  • Además, Odnoklassniki tiene una excelente tradición técnica: cualquier servicio que lancemos debe sobrevivir a una falla del centro de datos (repentina, no planificada y absolutamente en cualquier momento).

El último requisito en la implementación de este proyecto es el que más nos costó, del que hablaré con más detalle.

miércoles

Trabajamos en cuatro centros de datos, mientras que los nodos de datos de Elasticsearch solo pueden ubicarse en tres (por varias razones no técnicas).

Estos cuatro centros de datos contienen aproximadamente 18 mil fuentes de registros diferentes: hardware, contenedores y máquinas virtuales.

Característica importante: el clúster comienza en contenedores Podman no en máquinas físicas, sino en propio producto en la nube one-cloud. Los contenedores tienen garantizados 2 núcleos, similar a 2.0Ghz v4, con posibilidad de reciclar los núcleos restantes si están inactivos.

En otras palabras:

Clúster de Elasticsearch de 200 TB+

Topología

Inicialmente vi la forma general de la solución de la siguiente manera:

  • Detrás del registro A del dominio Graylog hay 3-4 VIP, esta es la dirección a la que se envían los registros.
  • cada VIP es un equilibrador LVS.
  • Después, los registros van a la batería Graylog, algunos de los datos están en formato GELF, otros en formato syslog.
  • Luego, todo esto se escribe en grandes lotes en una batería de coordinadores de Elasticsearch.
  • Y ellos, a su vez, envían solicitudes de escritura y lectura a los nodos de datos relevantes.

Clúster de Elasticsearch de 200 TB+

Vocabulario

Quizás no todo el mundo comprenda la terminología en detalle, por lo que me gustaría detenerme un poco en ella.

Elasticsearch tiene varios tipos de nodos: maestro, coordinador y nodo de datos. Hay otros dos tipos para diferentes transformaciones de registros y comunicación entre diferentes clústeres, pero solo utilizamos los enumerados.

Dominar
Hace ping a todos los nodos presentes en el clúster, mantiene un mapa de clúster actualizado y lo distribuye entre nodos, procesa la lógica de eventos y realiza varios tipos de limpieza en todo el clúster.

Director
Realiza una única tarea: acepta solicitudes de lectura o escritura de los clientes y enruta este tráfico. En caso de que haya una solicitud de escritura, lo más probable es que le pregunte al maestro en qué fragmento del índice relevante debe colocarlo y redirigirá aún más la solicitud.

Nodo de datos
Almacena datos, realiza consultas de búsqueda que llegan desde el exterior y realiza operaciones en los fragmentos ubicados en ellos.

tronco gris
Esto es algo así como una fusión de Kibana con Logstash en una pila ELK. Graylog combina una interfaz de usuario y una canalización de procesamiento de registros. Debajo del capó, Graylog ejecuta Kafka y Zookeeper, que brindan conectividad a Graylog como un clúster. Graylog puede almacenar en caché los registros (Kafka) en caso de que Elasticsearch no esté disponible y repetir solicitudes de lectura y escritura fallidas, agrupar y marcar registros de acuerdo con reglas especificadas. Al igual que Logstash, Graylog tiene la funcionalidad de modificar filas antes de escribirlas en Elasticsearch.

Además, Graylog tiene un descubrimiento de servicios incorporado que permite, basándose en un nodo Elasticsearch disponible, obtener el mapa completo del clúster y filtrarlo por una etiqueta específica, lo que permite dirigir solicitudes a contenedores específicos.

Visualmente se parece a esto:

Clúster de Elasticsearch de 200 TB+

Esta es una captura de pantalla de una instancia específica. Aquí construimos un histograma basado en la consulta de búsqueda y mostramos filas relevantes.

Índices

Volviendo a la arquitectura del sistema, me gustaría explicar con más detalle cómo construimos el modelo de índice para que todo funcione correctamente.

En el diagrama anterior, este es el nivel más bajo: nodos de datos de Elasticsearch.

Un índice es una gran entidad virtual formada por fragmentos de Elasticsearch. En sí mismo, cada uno de los fragmentos no es más que un índice de Lucene. Y cada índice de Lucene, a su vez, consta de uno o más segmentos.

Clúster de Elasticsearch de 200 TB+

Al diseñar, pensamos que para cumplir con el requisito de velocidad de lectura en una gran cantidad de datos, necesitábamos "distribuir" estos datos de manera uniforme entre los nodos de datos.

Esto resultó en el hecho de que la cantidad de fragmentos por índice (con réplicas) debería ser estrictamente igual a la cantidad de nodos de datos. En primer lugar, para asegurar un factor de replicación igual a dos (es decir, podemos perder la mitad del cluster). Y, en segundo lugar, para procesar solicitudes de lectura y escritura en al menos la mitad del clúster.

Primero determinamos el tiempo de almacenamiento en 30 días.

La distribución de fragmentos se puede representar gráficamente de la siguiente manera:

Clúster de Elasticsearch de 200 TB+

Todo el rectángulo gris oscuro es un índice. El cuadrado rojo de la izquierda es el fragmento principal, el primero en el índice. Y el cuadrado azul es una réplica del fragmento. Están ubicados en diferentes centros de datos.

Cuando agregamos otro fragmento, va al tercer centro de datos. Y, al final, obtenemos esta estructura, que permite perder DC sin perder la coherencia de los datos:

Clúster de Elasticsearch de 200 TB+

Rotación de índices, es decir. Al crear un nuevo índice y eliminar el más antiguo, lo igualamos a 48 horas (de acuerdo con el patrón de uso del índice: las últimas 48 horas son las que se buscan con mayor frecuencia).

Este intervalo de rotación del índice se debe a las siguientes razones:

Cuando una solicitud de búsqueda llega a un nodo de datos específico, desde el punto de vista del rendimiento, es más rentable consultar un fragmento si su tamaño es comparable al tamaño de la cadera del nodo. Esto le permite mantener la parte "caliente" del índice en un montón y acceder a ella rápidamente. Cuando hay muchas "partes calientes", la velocidad de la búsqueda de índice se degrada.

Cuando un nodo comienza a ejecutar una consulta de búsqueda en un fragmento, asigna una cantidad de subprocesos igual a la cantidad de núcleos de hiperprocesamiento de la máquina física. Si una consulta de búsqueda afecta a una gran cantidad de fragmentos, la cantidad de subprocesos crece proporcionalmente. Esto tiene un impacto negativo en la velocidad de búsqueda y afecta negativamente a la indexación de nuevos datos.

Para proporcionar la latencia de búsqueda necesaria, decidimos utilizar un SSD. Para procesar rápidamente las solicitudes, las máquinas que alojaban estos contenedores debían tener al menos 56 núcleos. Se eligió la cifra 56 como un valor condicionalmente suficiente que determina la cantidad de subprocesos que Elasticsearch generará durante la operación. En Elasitcsearch, muchos parámetros del grupo de subprocesos dependen directamente de la cantidad de núcleos disponibles, lo que a su vez afecta directamente la cantidad requerida de nodos en el clúster de acuerdo con el principio "menos núcleos, más nodos".

Como resultado, descubrimos que, en promedio, un fragmento pesa alrededor de 20 gigabytes y hay 1 fragmentos por índice. En consecuencia, si los rotamos una vez cada 360 horas, tendremos 48. Cada índice contiene datos de 15 días.

Circuitos de escritura y lectura de datos.

Averigüemos cómo se registran los datos en este sistema.

Digamos que llega alguna solicitud de Graylog al coordinador. Por ejemplo, queremos indexar entre 2 y 3 mil filas.

El coordinador, después de recibir una solicitud de Graylog, pregunta al maestro: "En la solicitud de indexación, especificamos específicamente un índice, pero no se especificó en qué fragmento escribirlo".

El maestro responde: "Escriba esta información en el fragmento número 71", después de lo cual se envía directamente al nodo de datos relevante, donde se encuentra el fragmento primario número 71.

Después de lo cual, el registro de transacciones se replica en un fragmento de réplica, que se encuentra en otro centro de datos.

Clúster de Elasticsearch de 200 TB+

Llega una solicitud de búsqueda de Graylog al coordinador. El coordinador lo redirige según el índice, mientras que Elasticsearch distribuye las solicitudes entre el fragmento primario y el fragmento de réplica utilizando el principio de operación por turnos.

Clúster de Elasticsearch de 200 TB+

Los 180 nodos responden de manera desigual y, mientras responden, el coordinador acumula información que ya ha sido "escupida" por nodos de datos más rápidos. Después de esto, cuando ha llegado toda la información o la solicitud ha alcanzado el tiempo de espera, le entrega todo directamente al cliente.

En promedio, todo este sistema procesa consultas de búsqueda de las últimas 48 horas en 300-400 ms, excluyendo aquellas consultas con un comodín inicial.

Flores con Elasticsearch: configuración de Java

Clúster de Elasticsearch de 200 TB+

Para que todo funcione como queríamos originalmente, dedicamos mucho tiempo a depurar una amplia variedad de cosas en el clúster.

La primera parte de los problemas descubiertos estaba relacionada con la forma en que Java está preconfigurado de forma predeterminada en Elasticsearch.

El primer problema
Hemos visto una gran cantidad de informes que a nivel de Lucene, cuando se ejecutan trabajos en segundo plano, las fusiones de segmentos de Lucene fallan con un error. Al mismo tiempo, estaba claro en los registros que se trataba de un error OutOfMemoryError. Vimos por telemetría que la cadera estaba libre y no estaba claro por qué fallaba esta operación.

Resultó que las fusiones del índice de Lucene ocurren fuera de la cadera. Y los contenedores están estrictamente limitados en términos de recursos consumidos. Solo el montón podía caber en estos recursos (el valor heap.size era aproximadamente igual a la RAM), y algunas operaciones fuera del montón fallaban con un error de asignación de memoria si por alguna razón no cabían en los ~500 MB que quedaban antes del límite.

La solución fue bastante trivial: se aumentó la cantidad de RAM disponible para el contenedor, después de lo cual olvidamos que incluso teníamos tales problemas.

problema dos
4-5 días después del lanzamiento del clúster, notamos que los nodos de datos comenzaron a salir periódicamente del clúster y a ingresar a él después de 10 a 20 segundos.

Cuando comenzamos a resolverlo, resultó que esta memoria fuera del montón en Elasticsearch no está controlada de ninguna manera. Cuando le dimos más memoria al contenedor, pudimos llenar los grupos de búfer directos con diversa información, y se borró solo después de que se inició el GC explícito desde Elasticsearch.

En algunos casos, esta operación tomó bastante tiempo y durante este tiempo el clúster logró marcar este nodo como ya salido. Este problema está bien descrito. aquí.

La solución fue la siguiente: limitamos la capacidad de Java para usar la mayor parte de la memoria fuera del montón para estas operaciones. Lo limitamos a 16 gigabytes (-XX:MaxDirectMemorySize=16g), asegurando que la GC explícita se llamara con mucha más frecuencia y se procesara mucho más rápido, por lo que ya no desestabilizaría el clúster.

Problema tres
Si cree que se acabaron los problemas con los “nodos que abandonan el clúster en el momento más inesperado”, está equivocado.

Cuando configuramos el trabajo con índices, elegimos mmapfs para reducir el tiempo de búsqueda sobre fragmentos frescos con gran segmentación. Esto fue un gran error, porque cuando usamos mmapfs el archivo se asigna a la RAM y luego trabajamos con el archivo asignado. Debido a esto, resulta que cuando el GC intenta detener los subprocesos en la aplicación, vamos al punto seguro durante mucho tiempo y, en el camino hacia él, la aplicación deja de responder a las solicitudes del maestro sobre si está vivo. . En consecuencia, el maestro cree que el nodo ya no está presente en el clúster. Después de esto, después de 5 a 10 segundos, el recolector de basura funciona, el nodo cobra vida, ingresa nuevamente al clúster y comienza a inicializar los fragmentos. Todo se parecía mucho a “la producción que merecíamos” y no era apto para nada serio.

Para deshacernos de este comportamiento, primero cambiamos a niofs estándar y luego, cuando migramos de la quinta versión de Elastic a la sexta, probamos hybridfs, donde este problema no se reprodujo. Puedes leer más sobre los tipos de almacenamiento. aquí.

Problema cuatro
Luego hubo otro problema muy interesante que tratamos en un tiempo récord. Lo atrapamos durante 2 o 3 meses porque su patrón era absolutamente incomprensible.

A veces nuestros coordinadores iban al GC completo, generalmente después del almuerzo, y nunca regresaban de allí. Al mismo tiempo, al registrar el retraso de GC, se veía así: todo va bien, bien, bien, y de repente todo va muy mal.

Al principio pensamos que teníamos un usuario malvado que estaba lanzando algún tipo de solicitud que dejaba fuera del modo de trabajo al coordinador. Registramos solicitudes durante mucho tiempo, tratando de descubrir qué estaba pasando.

Como resultado, resultó que en el momento en que un usuario lanza una solicitud enorme y llega a un coordinador específico de Elasticsearch, algunos nodos responden más que otros.

Y mientras el coordinador espera respuesta de todos los nodos, acumula los resultados enviados por los nodos que ya respondieron. Para GC, esto significa que nuestros patrones de uso del montón cambian muy rápidamente. Y el GC que utilizamos no pudo hacer frente a esta tarea.

La única solución que encontramos para cambiar el comportamiento del clúster en esta situación es la migración a JDK13 y el uso del recolector de basura Shenandoah. Esto solucionó el problema, nuestros coordinadores dejaron de caer.

Aquí terminaron los problemas con Java y comenzaron los problemas de ancho de banda.

"Bayas" con Elasticsearch: rendimiento

Clúster de Elasticsearch de 200 TB+

Los problemas con el rendimiento significan que nuestro clúster funciona de manera estable, pero en picos de cantidad de documentos indexados y durante las maniobras, el rendimiento es insuficiente.

El primer síntoma encontrado: durante algunas "explosiones" en producción, cuando de repente se genera una gran cantidad de registros, el error de indexación es_rejected_execution comienza a parpadear con frecuencia en Graylog.

Esto se debió al hecho de que thread_pool.write.queue en un nodo de datos, hasta el momento en que Elasticsearch puede procesar la solicitud de indexación y cargar la información en el fragmento en el disco, solo puede almacenar en caché 200 solicitudes de forma predeterminada. Y en Documentación de búsqueda elástica Sobre este parámetro se habla muy poco. Sólo se indican el número máximo de subprocesos y el tamaño predeterminado.

Por supuesto, modificamos este valor y descubrimos lo siguiente: específicamente, en nuestra configuración, hasta 300 solicitudes se almacenan en caché bastante bien, y un valor más alto conlleva el hecho de que nuevamente volamos a Full GC.

Además, dado que se trata de lotes de mensajes que llegan dentro de una solicitud, fue necesario modificar Graylog para que no escriba con frecuencia y en lotes pequeños, sino en lotes grandes o una vez cada 3 segundos si el lote aún no está completo. En este caso, resulta que la información que escribimos en Elasticsearch no está disponible en dos segundos, sino en cinco (lo que nos conviene bastante), pero la cantidad de retrays que hay que hacer para avanzar en una gran cantidad La pila de información se reduce.

Esto es especialmente importante en esos momentos en los que algo falla en algún lugar y lo informa furiosamente, para no recibir un Elastic completamente spam y, después de un tiempo, nodos Graylog que no funcionan debido a buffers obstruidos.

Además, cuando tuvimos estas mismas explosiones en producción, recibimos quejas de programadores y testers: en el momento en que realmente necesitaban estos registros, se los entregaron muy lentamente.

Comenzaron a resolverlo. Por un lado, estaba claro que tanto las consultas de búsqueda como las de indexación se procesaban, esencialmente, en las mismas máquinas físicas, y de una forma u otra habría ciertas reducciones.

Pero esto podría evitarse parcialmente debido al hecho de que en la sexta versión de Elasticsearch apareció un algoritmo que permite distribuir consultas entre nodos de datos relevantes, no de acuerdo con el principio aleatorio de operación por turnos (el contenedor que indexa y contiene el principal). -shard puede estar muy ocupado, no habrá forma de responder rápidamente), pero reenvíe esta solicitud a un contenedor menos cargado con una réplica-shard, que responderá mucho más rápido. En otras palabras, llegamos a use_adaptive_replica_selection: true.

La imagen de lectura comienza a verse así:

Clúster de Elasticsearch de 200 TB+

La transición a este algoritmo permitió mejorar significativamente el tiempo de consulta en aquellos momentos en los que teníamos un gran flujo de registros para escribir.

Finalmente, el principal problema fue la eliminación sencilla del centro de datos.

Lo que queríamos del clúster inmediatamente después de perder la conexión con un DC:

  • Si tenemos un maestro actual en el centro de datos fallido, se volverá a seleccionar y se trasladará como función a otro nodo en otro DC.
  • El maestro eliminará rápidamente todos los nodos inaccesibles del clúster.
  • Según los restantes, lo entenderá: en el centro de datos perdido teníamos tal o cual fragmento primario, rápidamente promoverá réplicas complementarias de fragmentos en los centros de datos restantes y continuaremos indexando los datos.
  • Como resultado de esto, el rendimiento de escritura y lectura del clúster se degradará gradualmente, pero en general todo funcionará, aunque de forma lenta pero estable.

Al final resultó que, queríamos algo como esto:

Clúster de Elasticsearch de 200 TB+

Y obtuvimos lo siguiente:

Clúster de Elasticsearch de 200 TB+

¿Cómo sucedió eso?

Cuando el centro de datos cayó, nuestro maestro se convirtió en el cuello de botella.

¿Por qué?

El caso es que el maestro tiene un TaskBatcher, que se encarga de distribuir determinadas tareas y eventos en el clúster. Cualquier salida de nodo, cualquier promoción de un fragmento de réplica a principal, cualquier tarea para crear un fragmento en algún lugar, todo esto va primero a TaskBatcher, donde se procesa secuencialmente y en un solo hilo.

En el momento de la retirada de un centro de datos, resultó que todos los nodos de datos de los centros de datos supervivientes consideraban que era su deber informar al maestro "hemos perdido tal o cual fragmento y tal o cual nodo de datos".

Al mismo tiempo, los nodos de datos supervivientes enviaron toda esta información al maestro actual e intentaron esperar la confirmación de que la aceptaba. No esperaron por esto, ya que el maestro recibía tareas más rápido de lo que podía responder. Los nodos agotaron el tiempo de espera de las solicitudes repetidas y el maestro en ese momento ni siquiera intentó responderlas, sino que estaba completamente absorto en la tarea de clasificar las solicitudes por prioridad.

En forma de terminal, resultó que los nodos de datos enviaron spam al maestro hasta el punto de que entró en GC completo. Después de eso, nuestro rol de maestro pasó al siguiente nodo, le sucedió exactamente lo mismo y, como resultado, el clúster colapsó por completo.

Tomamos medidas y, antes de la versión 6.4.0, donde esto se solucionó, nos bastaba con generar simultáneamente solo 10 nodos de datos de 360 ​​para cerrar completamente el clúster.

Se parecía a esto:

Clúster de Elasticsearch de 200 TB+

Después de la versión 6.4.0, donde se solucionó este terrible error, los nodos de datos dejaron de matar al maestro. Pero eso no lo hizo "más inteligente". Es decir: cuando generamos 2, 3 o 10 (cualquier número distinto de uno) nodos de datos, el maestro recibe un primer mensaje que dice que el nodo A se ha ido e intenta informar al nodo B, al nodo C sobre esto y al nodo D.

Y por el momento, esto solo se puede solucionar estableciendo un tiempo de espera para los intentos de contarle algo a alguien, equivalente a unos 20-30 segundos, y así controlar la velocidad del centro de datos que sale del clúster.

En principio, esto se ajusta a los requisitos que se presentaron inicialmente al producto final como parte del proyecto, pero desde el punto de vista de la "ciencia pura" esto es un error. Lo cual, por cierto, los desarrolladores solucionaron con éxito en la versión 7.2.

Además, cuando un determinado nodo de datos se apagó, resultó que difundir información sobre su salida era más importante que decirle a todo el clúster que había tal o cual fragmento primario en él (para promover un fragmento de réplica en otro nodo de datos). centro en la primaria, y en la información se podría escribir en ellos).

Por lo tanto, cuando todo ya se ha calmado, los nodos de datos liberados no se marcan inmediatamente como obsoletos. En consecuencia, nos vemos obligados a esperar hasta que se agote el tiempo de todos los pings a los nodos de datos liberados, y solo después de eso nuestro clúster comienza a decirnos que allí, allí y allí debemos continuar registrando información. Puedes leer más sobre esto. aquí.

Como resultado, la operación de retirar un centro de datos hoy nos lleva unos 5 minutos en hora punta. Para un coloso tan grande y torpe, este es un resultado bastante bueno.

Como resultado, llegamos a la siguiente decisión:

  • Contamos con 360 nodos de datos con discos de 700 gigabytes.
  • 60 coordinadores para enrutar el tráfico a través de estos mismos nodos de datos.
  • 40 maestros que hemos dejado como una especie de legado desde versiones anteriores a la 6.4.0; para sobrevivir a la retirada del centro de datos, estábamos mentalmente preparados para perder varias máquinas para tener la garantía de tener un quórum de maestros incluso en el peor de los casos
  • Cualquier intento de combinar roles en un contenedor se topó con el hecho de que tarde o temprano el nodo se rompería bajo carga.
  • Todo el clúster utiliza un tamaño de montón de 31 gigabytes: todos los intentos de reducir el tamaño resultaron en la eliminación de algunos nodos en consultas de búsqueda pesadas con el comodín principal o en la activación del disyuntor en el propio Elasticsearch.
  • Además, para garantizar el rendimiento de la búsqueda, intentamos mantener la cantidad de objetos en el clúster lo más pequeña posible para procesar la menor cantidad posible de eventos en el cuello de botella que obtuvimos en el maestro.

Finalmente sobre el monitoreo

Para garantizar que todo esto funcione según lo previsto, supervisamos lo siguiente:

  • Cada nodo de datos informa a nuestra nube que existe y que hay tales o cuales fragmentos en él. Cuando extinguimos algo en algún lugar, el clúster informa después de 2-3 segundos que en el centro A extinguimos los nodos 2, 3 y 4; esto significa que en otros centros de datos bajo ninguna circunstancia podemos extinguir aquellos nodos en los que solo hay un fragmento. izquierda.
  • Conociendo la naturaleza del comportamiento del maestro, observamos con mucha atención el número de tareas pendientes. Porque incluso una tarea estancada, si no se agota a tiempo, teóricamente en alguna situación de emergencia puede convertirse en la razón por la cual, por ejemplo, la promoción de un fragmento de réplica en el primario no funciona, razón por la cual la indexación dejará de funcionar.
  • También observamos muy de cerca los retrasos en el recolector de basura, porque ya hemos tenido grandes dificultades con esto durante la optimización.
  • Rechazos por hilo para comprender de antemano dónde está el cuello de botella.
  • Bueno, métricas estándar como montón, RAM y E/S.

Al crear monitoreo, debe tener en cuenta las características de Thread Pool en Elasticsearch. Documentación de búsqueda elástica describe las opciones de configuración y los valores predeterminados para la búsqueda y la indexación, pero no dice nada sobre thread_pool.management. Estos subprocesos procesan, en particular, consultas como _cat/shards y otras similares, que son convenientes de usar al escribir monitoreo. Cuanto más grande es el clúster, más solicitudes de este tipo se ejecutan por unidad de tiempo, y el thread_pool.management mencionado anteriormente no solo no se presenta en la documentación oficial, sino que también está limitado de forma predeterminada a 5 subprocesos, lo que se elimina muy rápidamente, después cual la monitorización deja de funcionar correctamente.

Lo que quiero decir en conclusión: ¡lo logramos! Pudimos brindarles a nuestros programadores y desarrolladores una herramienta que, en casi cualquier situación, puede brindar información de manera rápida y confiable sobre lo que sucede en producción.

Sí, resultó bastante complicado, pero aun así logramos adaptar nuestros deseos a los productos existentes, que no tuvimos que parchar y reescribir nosotros mismos.

Clúster de Elasticsearch de 200 TB+

Fuente: habr.com

Añadir un comentario