Como nós en CIAN domesticamos terabytes de rexistros

Como nós en CIAN domesticamos terabytes de rexistros

Ola a todos, chámome Alexander, traballo en CIAN como enxeñeiro e estou implicado na administración de sistemas e na automatización de procesos de infraestrutura. Nos comentarios dun dos artigos anteriores, pedíronnos que dixeramos de onde conseguimos 4 TB de rexistros por día e que facemos con eles. Si, temos moitos rexistros e creouse un clúster de infraestrutura separado para procesalos, o que nos permite resolver problemas rapidamente. Neste artigo falarei de como o adaptamos ao longo dun ano para traballar cun fluxo de datos cada vez maior.

Por onde empezamos?

Como nós en CIAN domesticamos terabytes de rexistros

Nos últimos anos, a carga en cian.ru creceu moi rapidamente e, no terceiro trimestre de 2018, o tráfico de recursos alcanzou os 11.2 millóns de usuarios únicos ao mes. Nese momento, nos momentos críticos perdíamos ata o 40% dos rexistros, polo que non podíamos facer fronte ás incidencias rapidamente e dedicamos moito tempo e esforzo a resolvelos. Tamén moitas veces non puidemos atopar a causa do problema e volveríase repetir despois dun tempo. Era un inferno e había que facer algo ao respecto.

Nese momento, utilizabamos un clúster de 10 nodos de datos con ElasticSearch versión 5.5.2 con configuración de índice estándar para almacenar rexistros. Introduciuse hai máis dun ano como unha solución popular e accesible: entón o fluxo de rexistros non era tan grande, non tiña sentido crear configuracións non estándar. 

Logstash proporcionou o procesamento dos rexistros de entrada en diferentes portos en cinco coordinadores de ElasticSearch. Un índice, independentemente do tamaño, constaba de cinco fragmentos. Organizouse unha rotación horaria e diaria, como resultado, uns 100 novos fragmentos apareceron no clúster cada hora. Aínda que non había moitos rexistros, o clúster funcionou ben e ninguén prestou atención á súa configuración. 

Os retos do rápido crecemento

O volume de rexistros xerados creceu moi rapidamente, xa que dous procesos se solapaban. Por unha banda, medrou o número de usuarios do servizo. Por outra banda, comezamos a cambiar activamente a unha arquitectura de microservizos, cortando os nosos antigos monolitos en C# e Python. Varias ducias de novos microservizos que substituíron partes do monolito xeraron significativamente máis rexistros para o clúster de infraestruturas. 

Foi o escalado o que nos levou ata o punto no que o clúster se volveu practicamente inmanexable. Cando os rexistros comezaron a chegar a un ritmo de 20 mil mensaxes por segundo, a rotación inútil frecuente aumentou o número de fragmentos a 6 mil, e había máis de 600 fragmentos por nodo. 

Isto provocou problemas coa asignación de RAM, e cando un nodo fallaba, todos os fragmentos comezaban a moverse simultaneamente, multiplicando o tráfico e cargando outros nodos, o que facía case imposible escribir datos no clúster. E durante este período quedamos sen troncos. E se houbo un problema co servidor, basicamente perdemos 1/10 do clúster. Un gran número de pequenos índices engadiu complexidade.

Sen rexistros, non entendiamos as razóns do incidente e tarde ou cedo poderiamos volver a pisar o mesmo anciño, e na ideoloxía do noso equipo isto era inaceptable, xa que todos os nosos mecanismos de traballo están deseñados para facer exactamente o contrario - nunca repetir. os mesmos problemas. Para iso, necesitábamos todo o volume de rexistros e a súa entrega case en tempo real, xa que un equipo de enxeñeiros de servizo supervisaba as alertas non só das métricas, senón tamén dos rexistros. Para comprender a escala do problema, nese momento o volume total de rexistros era duns 2 TB por día. 

Fixemos o obxectivo de eliminar completamente a perda de rexistros e reducir o tempo da súa entrega ao clúster ELK a un máximo de 15 minutos durante casos de forza maior (máis tarde confiamos nesta cifra como un KPI interno).

Novo mecanismo de rotación e nós quente-quente

Como nós en CIAN domesticamos terabytes de rexistros

Comezamos a conversión do clúster actualizando a versión de ElasticSearch da 5.5.2 á 6.4.3. Unha vez máis o noso clúster da versión 5 morreu e decidimos desactivalo e actualizalo completamente; aínda non hai rexistros. Así que fixemos esta transición en só un par de horas.

A transformación máis a gran escala nesta fase foi a implementación de Apache Kafka en tres nodos cun coordinador como búfer intermedio. O corredor de mensaxes salvounos de perder rexistros durante problemas con ElasticSearch. Ao mesmo tempo, engadimos 2 nodos ao clúster e cambiamos a unha arquitectura quente con tres nodos "quentes" situados en diferentes racks no centro de datos. Rediriximos os rexistros a eles usando unha máscara que non debería perderse baixo ningún concepto: nginx, así como os rexistros de erros da aplicación. Enviáronse rexistros menores aos nodos restantes: depuración, aviso, etc., e despois de 24 horas transfiríronse rexistros "importantes" dos nodos "quentes".

Para non aumentar o número de pequenos índices, cambiamos da rotación temporal ao mecanismo de rollover. Había moita información nos foros de que a rotación por tamaño do índice é moi pouco fiable, polo que decidimos usar a rotación polo número de documentos do índice. Analizamos cada índice e rexistramos o número de documentos despois do cal debería funcionar a rotación. Así, alcanzamos o tamaño óptimo de fragmentos: non máis de 50 GB. 

Optimización de clústeres

Como nós en CIAN domesticamos terabytes de rexistros

Non obstante, non nos libramos completamente dos problemas. Desafortunadamente, aínda apareceron pequenos índices: non alcanzaron o volume especificado, non se rotaron e elimináronse mediante a limpeza global de índices anteriores a tres días, xa que eliminamos a rotación por data. Isto provocou a perda de datos debido ao feito de que o índice do clúster desapareceu por completo e un intento de escribir nun índice inexistente rompeu a lóxica do comisario que utilizamos para a xestión. O alias para escribir converteuse nun índice e rompeu a lóxica de rollover, provocando un crecemento incontrolado dalgúns índices ata 600 GB. 

Por exemplo, para a configuración de rotación:

сurator-elk-rollover.yaml

---
actions:
  1:
    action: rollover
    options:
      name: "nginx_write"
      conditions:
        max_docs: 100000000
  2:
    action: rollover
    options:
      name: "python_error_write"
      conditions:
        max_docs: 10000000

Se non había un alias de transferencia, ocorreu un erro:

ERROR     alias "nginx_write" not found.
ERROR     Failed to complete action: rollover.  <type 'exceptions.ValueError'>: Unable to perform index rollover with alias "nginx_write".

Deixamos a solución a este problema para a seguinte iteración e abordamos outro problema: cambiamos á lóxica de extracción de Logstash, que procesa os rexistros entrantes (eliminando información innecesaria e enriquecendo). Colocámolo en docker, que lanzamos a través de docker-compose, e tamén colocamos alí logstash-exporter, que envía métricas a Prometheus para o seguimento operativo do fluxo de rexistros. Deste xeito, démonos a oportunidade de cambiar sen problemas o número de instancias de logstash responsables de procesar cada tipo de rexistro.

Mentres mellorabamos o clúster, o tráfico de cian.ru aumentou ata os 12,8 millóns de usuarios únicos ao mes. Como resultado, resultou que as nosas transformacións estaban un pouco por detrás dos cambios na produción e enfrontámonos ao feito de que os nodos "cálidos" non podían soportar a carga e retardaron toda a entrega de rexistros. Recibimos datos "quentes" sen fallos, pero tivemos que intervir na entrega do resto e facer un rollover manual para distribuír uniformemente os índices. 

Ao mesmo tempo, a escala e o cambio da configuración das instancias de logstash no clúster foi complicado polo feito de que se trataba dunha composición docker local e todas as accións realizáronse manualmente (para engadir novos extremos, era necesario pasar manualmente por todas os servidores e faga docker-compose -d en todas partes).

Redistribución de rexistros

En setembro deste ano, aínda estabamos cortando o monolito, a carga do clúster aumentaba e o fluxo de rexistros achegábase ás 30 mil mensaxes por segundo. 

Como nós en CIAN domesticamos terabytes de rexistros

Comezamos a seguinte iteración cunha actualización de hardware. Cambiamos de cinco coordinadores a tres, substituímos os nodos de datos e gañamos en termos de diñeiro e espazo de almacenamento. Para os nodos usamos dúas configuracións: 

  • Para nós "quentes": E3-1270 v6 / 960 Gb SSD / 32 Gb x 3 x 2 (3 para Hot1 e 3 para Hot2).
  • Para nós "cálidos": E3-1230 v6 / 4Tb SSD / 32 Gb x 4.

Nesta iteración, movemos o índice con rexistros de acceso de microservizos, que ocupa o mesmo espazo que os rexistros nginx de primeira liña, ao segundo grupo de tres nodos "quentes". Agora almacenamos os datos en nodos "quentes" durante 20 horas, e despois transferímolos a nodos "quentes" ao resto dos rexistros. 

Resolvemos o problema da desaparición de pequenos índices reconfigurando a súa rotación. Agora os índices rótanse cada 23 horas en calquera caso, aínda que hai poucos datos alí. Isto aumentou lixeiramente o número de fragmentos (había uns 800 deles), pero desde o punto de vista do rendemento do clúster é tolerable. 

Como resultado, había seis nodos "quentes" e só catro nodos "quentes". Isto provoca un lixeiro atraso nas solicitudes durante longos intervalos de tempo, pero aumentar o número de nós no futuro resolverá este problema.

Esta iteración tamén solucionou o problema da falta de escalado semiautomático. Para iso, implantamos un clúster de infraestrutura Nomad, similar ao que xa implantamos en produción. Polo momento, a cantidade de Logstash non cambia automaticamente dependendo da carga, pero chegaremos a isto.

Como nós en CIAN domesticamos terabytes de rexistros

Planos para o futuro

A configuración implementada escala perfectamente e agora almacenamos 13,3 TB de datos, todos os rexistros durante 4 días, o que é necesario para a análise de alertas de emerxencia. Convertemos algúns dos rexistros en métricas, que engadimos a Graphite. Para facilitar o traballo dos enxeñeiros, temos métricas para o clúster de infraestruturas e scripts para a reparación semiautomática de problemas comúns. Despois de aumentar o número de nodos de datos, que está previsto para o próximo ano, cambiaremos ao almacenamento de datos de 4 a 7 días. Isto será suficiente para o traballo operativo, xa que sempre intentamos investigar os incidentes canto antes, e para investigacións a longo prazo hai datos de telemetría. 

En outubro de 2019, o tráfico a cian.ru xa crecera ata os 15,3 millóns de usuarios únicos ao mes. Isto converteuse nunha proba seria da solución arquitectónica para entregar rexistros. 

Agora preparámonos para actualizar ElasticSearch á versión 7. Non obstante, para iso teremos que actualizar a asignación de moitos índices en ElasticSearch, xa que pasaron da versión 5.5 e foron declarados como obsoletos na versión 6 (simplemente non existen na versión). 7). Isto significa que durante o proceso de actualización definitivamente haberá algún tipo de forza maior, que nos deixará sen rexistros mentres se resolva o problema. Da versión 7, temos máis ganas de Kibana cunha interface mellorada e novos filtros. 

Conseguimos o noso obxectivo principal: deixamos de perder rexistros e reducimos o tempo de inactividade do clúster de infraestruturas de 2-3 fallos por semana a un par de horas de traballo de mantemento ao mes. Todo este traballo na produción é case invisible. Non obstante, agora podemos determinar exactamente o que está a suceder co noso servizo, podemos facelo rapidamente nun modo silencioso e non preocuparnos de que se perdan os rexistros. En xeral, estamos satisfeitos, contentos e preparándonos para novas fazañas, das que falaremos máis adiante.

Fonte: www.habr.com

Engadir un comentario