Clúster Elasticsearch 200 TB+

Clúster Elasticsearch 200 TB+

Moita xente loita con Elasticsearch. Pero que ocorre cando queres usalo para almacenar rexistros "nun volume especialmente grande"? E tamén é indoloro experimentar a falla de algún dos varios centros de datos? Que tipo de arquitectura deberías facer e con que trampas te tropezarás?

En Odnoklassniki decidimos usar elasticsearch para resolver o problema da xestión de rexistros, e agora compartimos a nosa experiencia con Habr: tanto sobre arquitectura como sobre trampas.

Son Pyotr Zaitsev, traballo como administrador de sistemas en Odnoklassniki. Antes diso, tamén era administrador, traballaba con Manticore Search, Sphinx search, Elasticsearch. Quizais, se aparece outra... busca, probablemente eu tamén traballe con ela. Tamén participo nunha serie de proxectos de código aberto de forma voluntaria.

Cando cheguei a Odnoklassniki, dixen temerariamente na entrevista que podía traballar con Elasticsearch. Despois de entender e completar algunhas tarefas sinxelas, encargáronme a gran tarefa de reformar o sistema de xestión de rexistros que existía nese momento.

Requisitos

Os requisitos do sistema formuláronse do seguinte xeito:

  • Graylog debía usarse como frontend. Dado que a empresa xa tiña experiencia no uso deste produto, os programadores e os probadores coñecíano, era familiar e cómodo para eles.
  • Volume de datos: de media 50-80 mil mensaxes por segundo, pero se algo rompe, entón o tráfico non está limitado por nada, pode ser de 2-3 millóns de liñas por segundo
  • Despois de discutir cos clientes os requisitos para a velocidade de procesamento das consultas de busca, decatámonos de que o patrón típico de usar un sistema deste tipo é o seguinte: a xente está a buscar rexistros da súa aplicación durante os últimos dous días e non quere esperar máis dun segundo para o resultado dunha consulta formulada.
  • Os administradores insistiron en que o sistema sexa facilmente escalable se é necesario, sen esixir que afonden no seu funcionamento.
  • De xeito que a única tarefa de mantemento que requiren estes sistemas periodicamente é cambiar algún hardware.
  • Ademais, Odnoklassniki ten unha excelente tradición técnica: calquera servizo que lancemos debe sobrevivir a un fallo do centro de datos (súpeto, non planificado e absolutamente en calquera momento).

O último requisito na posta en marcha deste proxecto foi o que máis nos custou, do que falarei con máis detalle.

Mércores

Traballamos en catro centros de datos, mentres que os nodos de datos de Elasticsearch só se poden localizar en tres (por varias razóns non técnicas).

Estes catro centros de datos conteñen aproximadamente 18 mil fontes de rexistro diferentes: hardware, contedores, máquinas virtuais.

Característica importante: o clúster comeza en contedores podman non en máquinas físicas, senón en propio produto en nube one-cloud. Os contedores teñen 2 núcleos garantidos, semellante ao 2.0Ghz v4, con posibilidade de reciclar os núcleos restantes se están inactivos.

Noutras palabras:

Clúster Elasticsearch 200 TB+

Topoloxía

Inicialmente vin a forma xeral da solución do seguinte xeito:

  • 3-4 VIP están detrás do rexistro A do dominio Graylog, este é o enderezo ao que se envían os rexistros.
  • cada VIP é un equilibrador LVS.
  • Despois diso, os rexistros van á batería Graylog, algúns dos datos están en formato GELF, outros en formato syslog.
  • Despois todo isto escríbese en grandes lotes a unha batería de coordinadores de Elasticsearch.
  • E eles, á súa vez, envían solicitudes de lectura e escritura aos nodos de datos relevantes.

Clúster Elasticsearch 200 TB+

Terminoloxía

Quizais non todos entendan a terminoloxía en detalle, polo que gustaríame determe un pouco.

Elasticsearch ten varios tipos de nodos: mestre, coordinador, nodo de datos. Hai outros dous tipos para diferentes transformacións de rexistro e comunicación entre diferentes clústeres, pero só usamos os que se indican.

Mestre
Fai ping a todos os nós presentes no clúster, mantén un mapa de clúster actualizado e distribúeo entre nós, procesa a lóxica de eventos e realiza varios tipos de mantemento do clúster.

Coordinador
Realiza unha única tarefa: acepta solicitudes de lectura ou escritura dos clientes e dirixe este tráfico. No caso de que haxa unha solicitude de escritura, o máis probable é que preguntará ao mestre en que fragmento do índice relevante debería colocalo e redirigirá a solicitude máis adiante.

Nodo de datos
Almacena datos, realiza consultas de busca que chegan desde fóra e realiza operacións sobre fragmentos situados nel.

greylog
Isto é algo así como unha fusión de Kibana con Logstash nunha pila ELK. Graylog combina unha interface de usuario e unha canalización de procesamento de rexistros. Baixo o capó, Graylog executa Kafka e Zookeeper, que proporcionan conectividade a Graylog como un clúster. Graylog pode almacenar en caché os rexistros (Kafka) no caso de que Elasticsearch non estea dispoñible e repita as solicitudes de lectura e escritura sen éxito, agrupa e marca os rexistros segundo as regras especificadas. Do mesmo xeito que Logstash, Graylog ten funcionalidade para modificar filas antes de escribilas en Elasticsearch.

Ademais, Graylog ten incorporado un servizo de descubrimento que permite, baseándose nun nodo Elasticsearch dispoñible, obter todo o mapa do clúster e filtralo por unha etiqueta específica, o que permite dirixir as solicitudes a contedores específicos.

Visualmente parece algo así:

Clúster Elasticsearch 200 TB+

Esta é unha captura de pantalla dunha instancia específica. Aquí construímos un histograma baseado na consulta de busca e mostramos as filas relevantes.

Índices

Volvendo á arquitectura do sistema, gustaríame determe máis en detalle sobre como construímos o modelo de índice para que todo funcionase correctamente.

No diagrama anterior, este é o nivel máis baixo: nodos de datos Elasticsearch.

Un índice é unha gran entidade virtual formada por fragmentos de Elasticsearch. En si mesmo, cada un dos fragmentos non é máis que un índice Lucene. E cada índice Lucene, á súa vez, consta dun ou máis segmentos.

Clúster Elasticsearch 200 TB+

Ao deseñar, pensamos que para cumprir o requisito de velocidade de lectura nunha gran cantidade de datos, necesitabamos "difundir" estes datos de forma uniforme entre os nodos de datos.

Isto deu lugar ao feito de que o número de fragmentos por índice (con réplicas) debería ser estrictamente igual ao número de nodos de datos. En primeiro lugar, para garantir un factor de replicación igual a dous (é dicir, podemos perder a metade do clúster). E, en segundo lugar, para procesar solicitudes de lectura e escritura en polo menos a metade do clúster.

Primeiro determinamos o tempo de almacenamento en 30 días.

A distribución dos fragmentos pódese representar graficamente do seguinte xeito:

Clúster Elasticsearch 200 TB+

Todo o rectángulo gris escuro é un índice. O cadrado vermello esquerdo é o fragmento principal, o primeiro do índice. E o cadrado azul é un fragmento de réplica. Están situados en diferentes centros de datos.

Cando engadimos outro fragmento, vai ao terceiro centro de datos. E, ao final, obtemos esta estrutura, que fai posible perder DC sen perder a consistencia dos datos:

Clúster Elasticsearch 200 TB+

Rotación de índices, é dicir. creando un novo índice e eliminando o máis antigo, igualámolo a 48 horas (segundo o patrón de uso do índice: as últimas 48 horas son as buscas máis frecuentes).

Este intervalo de rotación do índice débese aos seguintes motivos:

Cando unha solicitude de busca chega a un nodo de datos específico, entón, desde o punto de vista do rendemento, é máis rendible cando se consulta un fragmento, se o seu tamaño é comparable ao tamaño da cadeira do nodo. Isto permítelle manter a parte "quente" do índice nun montón e acceder a ela rapidamente. Cando hai moitas "partes quentes", a velocidade da busca do índice degrádase.

Cando un nodo comeza a executar unha consulta de busca nun fragmento, asigna un número de fíos igual ao número de núcleos de hiperfíos da máquina física. Se unha consulta de busca afecta a un gran número de fragmentos, entón o número de fíos crece proporcionalmente. Isto ten un impacto negativo na velocidade de busca e afecta negativamente á indexación de novos datos.

Para proporcionar a latencia de busca necesaria, decidimos usar un SSD. Para procesar rapidamente as solicitudes, as máquinas que albergaban estes contedores tiñan que ter polo menos 56 núcleos. Elixiuse a cifra de 56 como un valor condicionalmente suficiente que determina o número de fíos que Elasticsearch xerará durante a operación. En Elasitcsearch, moitos parámetros do grupo de fíos dependen directamente do número de núcleos dispoñibles, o que á súa vez afecta directamente ao número necesario de nodos do clúster segundo o principio "menos núcleos - máis nodos".

Como resultado, descubrimos que, de media, un fragmento pesa uns 20 gigabytes e hai 1 fragmentos por índice. En consecuencia, se os rotamos unha vez cada 360 horas, temos 48 deles. Cada índice contén datos de 15 días.

Circuítos de lectura e escritura de datos

Imos descubrir como se rexistran os datos neste sistema.

Digamos que chega algunha solicitude de Graylog ao coordinador. Por exemplo, queremos indexar 2-3 mil filas.

O coordinador, recibindo unha solicitude de Graylog, pregunta ao mestre: "Na solicitude de indexación especificamos especificamente un índice, pero non se especificou en que fragmento escribir".

O mestre responde: "Escribe esta información no fragmento número 71", despois de que envíase directamente ao nodo de datos relevante, onde se atopa o fragmento principal número 71.

Despois diso, o rexistro de transaccións replícase nun fragmento de réplica, que se atopa noutro centro de datos.

Clúster Elasticsearch 200 TB+

Chega unha solicitude de busca de Graylog ao coordinador. O coordinador redirixeo segundo o índice, mentres que Elasticsearch distribúe as solicitudes entre o fragmento principal e o fragmento de réplica mediante o principio de round-robin.

Clúster Elasticsearch 200 TB+

Os 180 nodos responden de forma desigual e, mentres responden, o coordinador acumula información que xa foi "escupida" por nodos de datos máis rápidos. Despois diso, cando chegou toda a información ou a solicitude chegou a un tempo de espera, entrégao todo directamente ao cliente.

Este sistema enteiro procesa de media as consultas de busca das últimas 48 horas en 300-400 ms, excluíndo aquelas consultas cun comodín inicial.

Flores con Elasticsearch: configuración de Java

Clúster Elasticsearch 200 TB+

Para que todo funcione como queriamos orixinalmente, pasamos moito tempo depurando unha gran variedade de cousas no clúster.

A primeira parte dos problemas descubertos estivo relacionada coa forma en que Java está preconfigurado por defecto en Elasticsearch.

Problema un
Vimos un gran número de informes de que a nivel de Lucene, cando se executan traballos en segundo plano, as fusións de segmentos de Lucene fallan con un erro. Ao mesmo tempo, quedou claro nos rexistros que se trataba dun erro OutOfMemoryError. Vimos por telemetría que a cadeira estaba libre e non estaba claro por que fallaba esta operación.

Descubriuse que as fusións do índice Lucene ocorren fóra da cadeira. E os contedores están bastante limitados en canto aos recursos consumidos. Só o montón podía caber nestes recursos (o valor de heap.size era aproximadamente igual á memoria RAM) e algunhas operacións fóra do montón colapsaban cun erro de asignación de memoria se por algún motivo non encaixaban nos ~500 MB que quedaban antes do límite.

A corrección foi bastante trivial: aumentou a cantidade de RAM dispoñible para o contedor, despois de que esquecemos que ata tiñamos tales problemas.

Problema dous
4-5 días despois do lanzamento do clúster, observamos que os nodos de datos comezaban a caer periódicamente do clúster e ingresalos despois de 10-20 segundos.

Cando comezamos a descubrilo, resultou que esta memoria fóra do montón en Elasticsearch non está controlada de ningún xeito. Cando lle demos máis memoria ao contedor, puidemos encher os conxuntos de búfer directo con varias informacións, e só se eliminou despois de que se lanzou o GC explícito desde Elasticsearch.

Nalgúns casos, esta operación levou bastante tempo e durante este tempo o clúster conseguiu marcar este nodo como xa saído. Este problema está ben descrito aquí.

A solución foi a seguinte: limitamos a capacidade de Java para usar a maior parte da memoria fóra do montón para estas operacións. Limitámolo a 16 gigabytes (-XX:MaxDirectMemorySize=16g), garantindo que se chamase GC explícito con moita máis frecuencia e procesase moito máis rápido, polo que xa non se desestabilizaba o clúster.

Problema tres
Se pensas que os problemas cos "nodos que saen do clúster no momento máis inesperado" remataron, estás equivocado.

Cando configuramos o traballo con índices, escollemos mmapfs para reducir o tempo de busca en fragmentos frescos con gran segmentación. Foi un erro, porque ao usar mmapfs o ficheiro está asignado á memoria RAM, e despois traballamos co ficheiro mapeado. Debido a isto, resulta que cando o GC intenta deter fíos na aplicación, imos ao punto seguro durante moito tempo e, de camiño a el, a aplicación deixa de responder ás solicitudes do mestre sobre se está activa. . En consecuencia, o mestre cre que o nodo xa non está presente no clúster. Despois diso, despois de 5-10 segundos, o colector de lixo funciona, o nodo cobra vida, entra de novo no clúster e comeza a inicializar fragmentos. Todo semellaba "a produción que merecíamos" e non era apto para nada serio.

Para desfacernos deste comportamento, primeiro cambiamos aos niofs estándar e despois, cando migramos da quinta versión de Elastic á sexta, probamos os híbridos, onde este problema non se reproducía. Podes ler máis sobre os tipos de almacenamento aquí.

Problema catro
Despois houbo outro problema moi interesante que tratamos durante un tempo récord. Collémolo durante 2-3 meses porque o seu patrón era absolutamente incomprensible.

Ás veces, os nosos coordinadores ían ao GC completo, normalmente nalgún momento despois do xantar, e nunca regresaban de alí. Ao mesmo tempo, ao rexistrar o atraso do GC, parecía o seguinte: todo vai ben, ben, ben, e despois unha vez, e de súpeto todo está mal.

Ao principio pensamos que tiñamos un usuario malvado que estaba lanzando algún tipo de solicitude que saía ao coordinador do modo de traballo. Rexistramos solicitudes durante moito tempo, tentando descubrir o que estaba a suceder.

Como resultado, resultou que no momento en que un usuario lanza unha solicitude enorme e chega a un coordinador específico de Elasticsearch, algúns nodos responden máis tempo que outros.

E mentres o coordinador agarda unha resposta de todos os nodos, acumula os resultados enviados desde os nodos que xa responderon. Para GC, isto significa que os nosos patróns de uso do montón cambian moi rapidamente. E o GC que utilizamos non puido facer fronte a esta tarefa.

A única solución que atopamos para cambiar o comportamento do clúster nesta situación é a migración a JDK13 e o uso do colector de lixo de Shenandoah. Isto resolveu o problema, os nosos coordinadores deixaron de caer.

Aquí é onde remataron os problemas con Java e comezaron os problemas de ancho de banda.

"Bagas" con Elasticsearch: rendemento

Clúster Elasticsearch 200 TB+

Os problemas co rendemento significan que o noso clúster funciona de forma estable, pero nos picos do número de documentos indexados e durante as manobras, o rendemento é insuficiente.

O primeiro síntoma atopado: durante algunhas "explosións" na produción, cando de súpeto se xera un gran número de rexistros, o erro de indexación es_rejected_execution comeza a parpadear con frecuencia en Graylog.

Isto debeuse ao feito de que thread_pool.write.queue nun nodo de datos, ata o momento en que Elasticsearch é capaz de procesar a solicitude de indexación e cargar a información no fragmento do disco, só pode almacenar na caché 200 solicitudes por defecto. E en Documentación de Elasticsearch Fálase moi pouco deste parámetro. Só se indica o número máximo de fíos e o tamaño predeterminado.

Por suposto, fomos torcer este valor e descubrimos o seguinte: concretamente, na nosa configuración, ata 300 solicitudes están bastante ben en caché, e un valor máis alto está cheo de que volvemos a voar a Full GC.

Ademais, dado que se trata de lotes de mensaxes que chegan dentro dunha solicitude, foi necesario axustar Graylog para que non escriba con frecuencia e en lotes pequenos, senón en lotes enormes ou unha vez cada 3 segundos se o lote aínda non está completo. Neste caso, resulta que a información que escribimos en Elasticsearch está dispoñible non en dous segundos, senón en cinco (o que nos convén bastante), senón o número de retransmisións que hai que facer para avanzar nun gran redúcese a pila de información.

Isto é especialmente importante naqueles momentos nos que algo se estrelou nalgún lugar e informa con furia sobre iso, para non obter un Elastic completamente spam, e despois dun tempo - nodos de Graylog que non funcionan debido aos búfers obstruídos.

Ademais, cando tivemos estas mesmas explosións en produción, recibimos queixas de programadores e probadores: no momento en que realmente necesitaban estes rexistros, déronselles moi lentamente.

Comezaron a descifralo. Por unha banda, estaba claro que tanto as consultas de busca como as de indexación procesábanse, fundamentalmente, nas mesmas máquinas físicas, e dun xeito ou doutro habería certas baixadas.

Pero isto podería evitarse parcialmente debido ao feito de que nas sextas versións de Elasticsearch apareceu un algoritmo que permite distribuír consultas entre nodos de datos relevantes non segundo o principio de round-robin aleatorio (o contedor que fai a indexación e contén o shard pode estar moi ocupado, non haberá forma de responder rapidamente), senón reenviar esta solicitude a un contedor menos cargado cunha réplica-shard, que responderá moito máis rápido. Noutras palabras, chegamos a use_adaptive_replica_selection: true.

A imaxe da lectura comeza a verse así:

Clúster Elasticsearch 200 TB+

A transición a este algoritmo permitiu mellorar significativamente o tempo de consulta naqueles momentos nos que tiñamos un gran fluxo de rexistros que escribir.

Finalmente, o principal problema foi a eliminación indolora do centro de datos.

O que queriamos do clúster inmediatamente despois de perder a conexión cun DC:

  • Se temos un mestre actual no centro de datos fallido, volverase seleccionar e moverse como rol a outro nodo doutro DC.
  • O mestre eliminará rapidamente todos os nós inaccesibles do clúster.
  • En función dos restantes, entenderá: no centro de datos perdido que tiñamos tales ou tales fragmentos primarios, promoverá rapidamente fragmentos de réplicas complementarios nos restantes centros de datos e seguiremos indexando os datos.
  • Como resultado diso, o rendemento de escritura e lectura do clúster irá degradando gradualmente, pero en xeral todo funcionará, aínda que sexa lentamente, pero de forma estable.

Como resultou, queriamos algo así:

Clúster Elasticsearch 200 TB+

E obtivemos o seguinte:

Clúster Elasticsearch 200 TB+

Como pasou isto?

Cando o centro de datos caeu, o noso mestre converteuse no pescozo de botella.

Por que?

O caso é que o mestre ten un TaskBatcher, que se encarga de distribuír determinadas tarefas e eventos no clúster. Calquera saída de nodo, calquera promoción dun fragmento de réplica a principal, calquera tarefa para crear un fragmento nalgún lugar - todo isto vai primeiro a TaskBatcher, onde se procesa secuencialmente e nun fío.

No momento da retirada dun centro de datos, resultou que todos os nodos de datos dos centros de datos supervivientes consideraban o seu deber informar ao mestre "perdemos tales fragmentos e tales nodos de datos".

Ao mesmo tempo, os nodos de datos superviventes enviaron toda esta información ao actual mestre e tentaron esperar a confirmación de que a aceptase. Non agardaron por iso, xa que o mestre recibía tarefas máis rápido do que podía responder. Os nodos esgotaron o tempo de repetición das solicitudes, e o mestre neste momento nin sequera intentou respondelas, pero estaba completamente absorto na tarefa de ordenar as solicitudes por prioridade.

En forma de terminal, resultou que os nodos de datos enviaron spam ao mestre ata o punto de que entrou en GC completo. Despois diso, o noso papel mestre trasladouse a algún nodo seguinte, pasoulle o mesmo e, como resultado, o clúster colapsou por completo.

Fixemos medicións e, antes da versión 6.4.0, na que se solucionou isto, abondaba con emitir simultáneamente só 10 nodos de datos de 360 ​​para apagar completamente o clúster.

Parecía algo así:

Clúster Elasticsearch 200 TB+

Despois da versión 6.4.0, onde se solucionou este terrible erro, os nodos de datos deixaron de matar ao mestre. Pero iso non o fixo "máis intelixente". É dicir: cando saímos 2, 3 ou 10 (calquera número que non sexa un) nodos de datos, o mestre recibe unha primeira mensaxe que di que o nodo A saíu e tenta dicirlle ao nodo B, ao nodo C, ao nodo D.

E polo momento, isto só se pode resolver establecendo un tempo de espera para os intentos de dicirlle algo a alguén, igual a uns 20-30 segundos, e controlar así a velocidade do centro de datos que sae do clúster.

En principio, isto encaixa nos requisitos que se presentaron inicialmente ao produto final como parte do proxecto, pero desde o punto de vista da "ciencia pura" trátase dun erro. Que, por certo, foi solucionado con éxito polos desenvolvedores na versión 7.2.

Ademais, cando un determinado nodo de datos se apagaba, resultou que difundir información sobre a súa saída era máis importante que dicirlle a todo o clúster que había tales ou tales fragmentos primarios nel (para promover un fragmento de réplica noutros datos). centro en primaria, e en información poderíase escribir neles).

Polo tanto, cando todo xa morreu, os nodos de datos liberados non se marcan inmediatamente como obsoletos. En consecuencia, vémonos obrigados a esperar ata que todos os pings se esgoten nos nodos de datos liberados, e só despois diso o noso clúster comeza a indicarnos que nalgún lugar, alí e alí temos que seguir gravando información. Podes ler máis sobre isto aquí.

Como resultado, a operación de retirar un centro de datos hoxe lévanos uns 5 minutos durante a hora punta. Para un coloso tan grande e torpe, este é un resultado bastante bo.

Como resultado, chegamos á seguinte decisión:

  • Temos 360 nodos de datos con discos de 700 gigabytes.
  • 60 coordinadores para enrutar o tráfico a través destes mesmos nodos de datos.
  • 40 mestres que deixamos como unha especie de legado desde as versións anteriores á 6.4.0: para sobrevivir á retirada do centro de datos, estabamos preparados mentalmente para perder varias máquinas para poder garantir un quórum de mestres incluso en o peor dos casos
  • Calquera intento de combinar roles nun contedor atopouse co feito de que tarde ou cedo o nodo rompería baixo a carga.
  • Todo o clúster usa un heap.size de 31 gigabytes: todos os intentos de reducir o tamaño resultaron en matar algúns nodos en consultas de busca pesadas co comodín principal ou conseguir o interruptor de circuito no propio Elasticsearch.
  • Ademais, para garantir o rendemento da busca, tentamos manter o número de obxectos do clúster o menor posible, para procesar o menor número posible de eventos no pescozo de botella que obtivemos no mestre.

Por último sobre o seguimento

Para garantir que todo isto funciona como se pretende, vixiamos o seguinte:

  • Cada nodo de datos informa á nosa nube de que existe, e hai tales ou tales fragmentos nel. Cando apagamos algo nalgún lugar, o clúster informa despois de 2-3 segundos que no centro A apagamos os nós 2, 3 e 4; isto significa que noutros centros de datos non podemos extinguir en ningún caso aqueles nodos nos que só hai un fragmento. esquerda.
  • Coñecendo a natureza do comportamento do mestre, observamos con moito coidado o número de tarefas pendentes. Porque mesmo unha tarefa atascada, se non chega a tempo, teoricamente nalgunha situación de emerxencia pode converterse no motivo polo que, por exemplo, a promoción dun fragmento de réplica no principal non funciona, polo que a indexación deixará de funcionar.
  • Tamén observamos moi detidamente os atrasos dos colectores de lixo, porque xa tivemos grandes dificultades con isto durante a optimización.
  • Rexeita por fío para entender con antelación onde está o pescozo de botella.
  • Ben, métricas estándar como heap, RAM e E/S.

Ao monitorizar a construción, debes ter en conta as funcións de Thread Pool en Elasticsearch. Documentación de Elasticsearch describe opcións de configuración e valores predeterminados para a busca e a indexación, pero non se refire a thread_pool.management. Estes fíos procesan, en particular, consultas como _cat/shards e outras similares, que son convenientes para usar cando se escribe monitorización. Canto maior sexa o clúster, máis solicitudes deste tipo se executan por unidade de tempo, e o mencionado thread_pool.management non só non se presenta na documentación oficial, senón que tamén está limitado por defecto a 5 fíos, que se eliminan moi rapidamente despois de que seguimento deixa de funcionar correctamente.

O que quero dicir en conclusión: fixémolo! Puidemos ofrecer aos nosos programadores e desenvolvedores unha ferramenta que, en case calquera situación, pode proporcionar información rápida e fiable sobre o que está a suceder na produción.

Si, resultou ser bastante complicado, pero, con todo, conseguimos encaixar os nosos desexos nos produtos existentes, que non tivemos que parchear e reescribir por nós mesmos.

Clúster Elasticsearch 200 TB+

Fonte: www.habr.com

Engadir un comentario