Hur vi på CIAN tämjde terabyte av stockar

Hur vi på CIAN tämjde terabyte av stockar

Hej alla, jag heter Alexander, jag jobbar på CIAN som ingenjör och är involverad i systemadministration och automatisering av infrastrukturprocesser. I kommentarerna till en av de tidigare artiklarna ombads vi berätta var vi får 4 TB loggar per dag och vad vi gör med dem. Ja, vi har många loggar och ett separat infrastrukturkluster har skapats för att bearbeta dem, vilket gör att vi snabbt kan lösa problem. I den här artikeln kommer jag att prata om hur vi anpassade det under loppet av ett år för att arbeta med ett ständigt växande dataflöde.

Var började vi?

Hur vi på CIAN tämjde terabyte av stockar

Under de senaste åren har belastningen på cian.ru vuxit mycket snabbt, och under tredje kvartalet 2018 nådde resurstrafiken 11.2 miljoner unika användare per månad. Vid den tiden förlorade vi vid kritiska ögonblick upp till 40 % av loggarna, vilket är anledningen till att vi inte snabbt kunde hantera incidenter och spenderade mycket tid och kraft på att lösa dem. Vi kunde ofta inte heller hitta orsaken till problemet, och det återkom efter en tid. Det var ett helvete och något måste göras åt det.

Vid den tiden använde vi ett kluster med 10 datanoder med ElasticSearch version 5.5.2 med standardindexinställningar för att lagra loggar. Det introducerades för mer än ett år sedan som en populär och prisvärd lösning: då var flödet av stockar inte så stort, det var ingen idé att komma med icke-standardiserade konfigurationer. 

Bearbetning av inkommande loggar tillhandahölls av Logstash på olika portar på fem ElasticSearch-koordinatorer. Ett index, oavsett storlek, bestod av fem skärvor. En tim- och daglig rotation organiserades, vilket resulterade i att cirka 100 nya skärvor dök upp i klustret varje timme. Även om det inte fanns särskilt många loggar, klarade klustret det bra och ingen uppmärksammade dess inställningar. 

Utmaningarna med snabb tillväxt

Volymen genererade loggar växte mycket snabbt, eftersom två processer överlappade varandra. Å ena sidan växte antalet användare av tjänsten. Å andra sidan började vi aktivt byta till en mikrotjänstarkitektur och sågade upp våra gamla monoliter i C# och Python. Flera dussin nya mikrotjänster som ersatte delar av monoliten genererade betydligt fler loggar för infrastrukturklustret. 

Det var skalningen som ledde oss till den punkt där klustret blev praktiskt taget ohanterligt. När loggarna började komma med en hastighet av 20 tusen meddelanden per sekund ökade frekvent värdelös rotation antalet skärvor till 6 tusen, och det fanns mer än 600 skärvor per nod. 

Detta ledde till problem med allokeringen av RAM, och när en nod kraschade började alla skärvor röra sig samtidigt, vilket multiplicerade trafiken och laddade andra noder, vilket gjorde det nästan omöjligt att skriva data till klustret. Och under denna period stod vi utan stockar. Och om det fanns ett problem med servern förlorade vi i princip 1/10 av klustret. Ett stort antal små index ökade komplexiteten.

Utan loggar förstod vi inte orsakerna till incidenten och kunde förr eller senare trampa på samma rake igen, och i vårt teams ideologi var detta oacceptabelt, eftersom alla våra arbetsmekanismer är utformade för att göra precis tvärtom - aldrig upprepa samma problem. För att göra detta behövde vi hela volymen loggar och deras leverans nästan i realtid, eftersom ett team av tjänstgörande ingenjörer övervakade varningar inte bara från mätvärden utan också från loggar. För att förstå problemets omfattning var den totala volymen stockar vid den tiden cirka 2 TB per dag. 

Vi satte ett mål att helt eliminera förlusten av stockar och minska leveranstiden till ELK-klustret till maximalt 15 minuter under force majeure (vi förlitade oss senare på denna siffra som en intern KPI).

Ny rotationsmekanism och varmvarma noder

Hur vi på CIAN tämjde terabyte av stockar

Vi startade klusterkonverteringen genom att uppdatera ElasticSearch-versionen från 5.5.2 till 6.4.3. Än en gång dog vårt version 5-kluster, och vi bestämde oss för att stänga av det och uppdatera det helt - det finns fortfarande inga loggar. Så vi gjorde den här övergången på bara ett par timmar.

Den mest storskaliga transformationen i detta skede var implementeringen av Apache Kafka på tre noder med en koordinator som en mellanliggande buffert. Meddelandemäklaren räddade oss från att förlora loggar under problem med ElasticSearch. Samtidigt lade vi till 2 noder i klustret och bytte till en varm-varm-arkitektur med tre "heta" noder placerade i olika rack i datacentret. Vi omdirigerade loggar till dem med en mask som inte bör gå förlorad under några omständigheter - nginx, såväl som applikationsfelloggar. Mindre loggar skickades till de återstående noderna - felsökning, varning etc., och efter 24 timmar överfördes "viktiga" loggar från "heta" noder.

För att inte öka antalet små index bytte vi från tidsrotation till rollover-mekanismen. Det fanns mycket information på forumen om att rotation efter indexstorlek är väldigt opålitlig, så vi bestämde oss för att använda rotation efter antalet dokument i indexet. Vi analyserade varje index och registrerade antalet dokument efter vilket rotationen skulle fungera. Därmed har vi nått den optimala skärvstorleken - inte mer än 50 GB. 

Klusteroptimering

Hur vi på CIAN tämjde terabyte av stockar

Vi har dock inte helt blivit av med problemen. Tyvärr dök det fortfarande upp små index: de nådde inte den angivna volymen, roterades inte och raderades genom global rengöring av index äldre än tre dagar, eftersom vi tog bort rotation efter datum. Detta ledde till dataförlust på grund av att indexet från klustret försvann helt, och ett försök att skriva till ett obefintligt index bröt logiken hos kuratorn som vi använde för hanteringen. Alias ​​för skrivning omvandlades till ett index och bröt rollover-logiken, vilket orsakade okontrollerad tillväxt av vissa index upp till 600 GB. 

Till exempel, för rotationskonfigurationen:

с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

Om det inte fanns något rollover-alias uppstod ett fel:

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

Vi lämnade lösningen på det här problemet för nästa iteration och tog upp ett annat problem: vi bytte till pull-logiken i Logstash, som bearbetar inkommande loggar (tar bort onödig information och berikar). Vi placerade den i docker, som vi lanserar via docker-compose, och vi placerade även logstash-exporter där, som skickar mätvärden till Prometheus för operativ övervakning av loggströmmen. På så sätt gav vi oss själva möjligheten att smidigt ändra antalet logstash-instanser som är ansvariga för att bearbeta varje typ av logg.

Medan vi förbättrade klustret ökade cian.rus trafik till 12,8 miljoner unika användare per månad. Som ett resultat visade det sig att våra omvandlingar låg lite bakom förändringarna i produktionen, och vi stod inför det faktum att de "varma" noderna inte kunde klara av belastningen och saktade ner hela leveransen av stockar. Vi fick "heta" data utan misslyckanden, men vi var tvungna att ingripa i leveransen av resten och göra en manuell rollover för att fördela indexen jämnt. 

Samtidigt komplicerades skalning och ändring av inställningarna för logstash-instanser i klustret av det faktum att det var en lokal docker-compose, och alla åtgärder utfördes manuellt (för att lägga till nya ändar var det nödvändigt att manuellt gå igenom alla servrarna och gör docker-compose up -d överallt).

Omfördelning av loggar

I september i år skar vi fortfarande upp monoliten, belastningen på klustret ökade och flödet av loggar närmade sig 30 tusen meddelanden per sekund. 

Hur vi på CIAN tämjde terabyte av stockar

Vi startade nästa iteration med en hårdvaruuppdatering. Vi bytte från fem koordinatorer till tre, bytte ut datanoder och vann när det gällde pengar och lagringsutrymme. För noder använder vi två konfigurationer: 

  • För "heta" noder: E3-1270 v6 / 960 Gb SSD / 32 Gb x 3 x 2 (3 för Hot1 och 3 för Hot2).
  • För "varma" noder: E3-1230 v6 / 4Tb SSD / 32 Gb x 4.

Vid denna iteration flyttade vi indexet med åtkomstloggar för mikrotjänster, som tar upp samma utrymme som frontlinjens nginx-loggar, till den andra gruppen av tre "heta" noder. Vi lagrar nu data på "heta" noder i 20 timmar och överför dem sedan till "varma" noder till resten av loggarna. 

Vi löste problemet med att små index försvann genom att konfigurera om deras rotation. Nu roteras indexen var 23:e timme i alla fall, även om det finns lite data där. Detta ökade antalet skärvor något (det fanns cirka 800 av dem), men ur klusterprestandasynpunkt är det acceptabelt. 

Som ett resultat fanns det sex "heta" och bara fyra "varma" noder i klustret. Detta orsakar en liten fördröjning av förfrågningar under långa tidsintervall, men att öka antalet noder i framtiden kommer att lösa detta problem.

Denna iteration löste också problemet med avsaknaden av halvautomatisk skalning. För att göra detta distribuerade vi ett infrastruktur Nomad-kluster - liknande det vi redan har distribuerat i produktionen. För närvarande ändras inte mängden Logstash automatiskt beroende på belastningen, men vi kommer fram till detta.

Hur vi på CIAN tämjde terabyte av stockar

Planer för framtiden

Den implementerade konfigurationen skalar perfekt, och nu lagrar vi 13,3 TB data - alla loggar i 4 dagar, vilket är nödvändigt för nödanalys av varningar. Vi omvandlar några av loggarna till mätvärden, som vi lägger till i Graphite. För att underlätta arbetet för ingenjörer har vi mätvärden för infrastrukturklustret och skript för halvautomatisk reparation av vanliga problem. Efter att ha utökat antalet datanoder, vilket är planerat till nästa år, kommer vi att gå över till datalagring från 4 till 7 dagar. Detta kommer att räcka för operativt arbete, eftersom vi alltid försöker utreda incidenter så snart som möjligt och för långtidsutredningar finns telemetridata. 

I oktober 2019 hade trafiken till cian.ru redan vuxit till 15,3 miljoner unika användare per månad. Detta blev ett seriöst test av den arkitektoniska lösningen för att leverera stockar. 

Nu förbereder vi att uppdatera ElasticSearch till version 7. Men för detta måste vi uppdatera kartläggningen av många index i ElasticSearch, eftersom de flyttade från version 5.5 och förklarades som föråldrade i version 6 (de existerar helt enkelt inte i version 7) 7). Detta innebär att det under uppdateringsprocessen definitivt kommer att uppstå någon form av force majeure, som kommer att lämna oss utan loggar medan problemet lösts. Av version XNUMX ser vi mest fram emot Kibana med ett förbättrat gränssnitt och nya filter. 

Vi uppnådde vårt huvudmål: vi slutade tappa loggar och minskade stilleståndstiden för infrastrukturklustret från 2-3 krascher per vecka till ett par timmars underhållsarbete per månad. Allt detta arbete i produktionen är nästan osynligt. Men nu kan vi avgöra exakt vad som händer med vår tjänst, vi kan snabbt göra det i ett tyst läge och inte oroa oss för att loggarna kommer att gå förlorade. I allmänhet är vi nöjda, glada och förbereder oss för nya bedrifter, som vi kommer att prata om senare.

Källa: will.com

Lägg en kommentar