Kako smo mi u CIAN-u ukrotili terabajte dnevnika

Kako smo mi u CIAN-u ukrotili terabajte dnevnika

Pozdrav svima, zovem se Alexander, radim u CIAN-u kao inženjer i bavim se sistemskom administracijom i automatizacijom infrastrukturnih procesa. U komentarima na jedan od prethodnih članaka, zamoljeni smo da kažemo odakle dobijamo 4 TB dnevnika dnevno i šta radimo sa njima. Da, imamo puno logova, a za njihovu obradu kreiran je poseban infrastrukturni klaster, što nam omogućava brzo rješavanje problema. U ovom članku ću govoriti o tome kako smo ga prilagodili tokom godine dana za rad sa sve većim protokom podataka.

Gdje smo počeli?

Kako smo mi u CIAN-u ukrotili terabajte dnevnika

U proteklih nekoliko godina, opterećenje na cian.ru je vrlo brzo poraslo, a do trećeg kvartala 2018. promet resursa dostigao je 11.2 miliona jedinstvenih korisnika mjesečno. Tada smo u kritičnim trenucima gubili i do 40% dnevnika, zbog čega nismo mogli brzo da se nosimo sa incidentima i trošili smo mnogo vremena i truda na njihovo rešavanje. Također često nismo mogli pronaći uzrok problema, a on bi se ponovio nakon nekog vremena. Bio je to pakao i nešto se moralo učiniti povodom toga.

U to vrijeme smo koristili klaster od 10 čvorova podataka sa ElasticSearch verzijom 5.5.2 sa standardnim postavkama indeksa za pohranjivanje dnevnika. Predstavljen je prije više od godinu dana kao popularno i pristupačno rješenje: tada protok trupaca nije bio tako velik, nije bilo smisla smišljati nestandardne konfiguracije. 

Obradu dolaznih dnevnika omogućio je Logstash na različitim portovima na pet ElasticSearch koordinatora. Jedan indeks, bez obzira na veličinu, sastojao se od pet krhotina. Organizirana je satna i dnevna rotacija, tako da se svakog sata u klasteru pojavilo oko 100 novih krhotina. Iako nije bilo mnogo dnevnika, klaster se snašao i niko nije obraćao pažnju na njegove postavke. 

Izazovi brzog rasta

Obim generiranih dnevnika je rastao vrlo brzo, jer su se dva procesa preklapala. S jedne strane, broj korisnika usluge je rastao. S druge strane, počeli smo aktivno da prelazimo na mikroservisnu arhitekturu, razrezujući naše stare monolite u C# i Python-u. Nekoliko desetina novih mikroservisa koji su zamijenili dijelove monolita generirali su znatno više dnevnika za infrastrukturni klaster. 

Skaliranje nas je dovelo do tačke u kojoj je klaster postao praktično neupravljiv. Kada su logovi počeli da pristižu brzinom od 20 hiljada poruka u sekundi, česta beskorisna rotacija povećala je broj fragmenata na 6 hiljada, a bilo je više od 600 fragmenata po čvoru. 

To je dovelo do problema s alokacijom RAM-a, a kada se čvor sruši, svi dijelovi su počeli da se kreću istovremeno, množeći promet i učitavajući druge čvorove, što je učinilo gotovo nemogućim upisivanje podataka u klaster. I u tom periodu ostali smo bez balvana. A ako je bilo problema sa serverom, u osnovi smo izgubili 1/10 klastera. Veliki broj malih indeksa je dodao složenost.

Bez logova nismo razumjeli razloge incidenta i mogli bismo prije ili kasnije ponovo stati na iste grablje, a u ideologiji našeg tima to je bilo neprihvatljivo, jer su svi naši mehanizmi rada osmišljeni da rade upravo suprotno - nikada se ne ponavljaju isti problemi. Da bismo to učinili, bila nam je potrebna puna količina dnevnika i njihova isporuka gotovo u realnom vremenu, budući da je tim dežurnih inženjera pratio upozorenja ne samo iz metrike, već i iz dnevnika. Da bismo razumjeli razmjere problema, u to vrijeme ukupna količina dnevnika bila je oko 2 TB dnevno. 

Postavili smo cilj da u potpunosti eliminišemo gubitak dnevnika i smanjimo vrijeme njihove isporuke u ELK klaster na maksimalno 15 minuta tokom više sile (kasnije smo se oslanjali na ovu cifru kao interni KPI).

Novi mehanizam rotacije i toplo-topli čvorovi

Kako smo mi u CIAN-u ukrotili terabajte dnevnika

Započeli smo konverziju klastera ažuriranjem ElasticSearch verzije sa 5.5.2 na 6.4.3. Još jednom je naš klaster verzije 5 umro, i odlučili smo ga isključiti i potpuno ažurirati - još uvijek nema dnevnika. Tako da smo ovu tranziciju napravili za samo nekoliko sati.

Najveća transformacija u ovoj fazi bila je implementacija Apache Kafke na tri čvora sa koordinatorom kao međubaferom. Posrednik poruka nas je spasio od gubitka evidencije tokom problema sa ElasticSearch-om. Istovremeno smo dodali 2 čvora u klaster i prešli na toplo-toplo arhitekturu sa tri “vruća” čvora smještena u različitim rekovima u podatkovnom centru. Preusmjerili smo im logove koristeći masku koja se ni pod kojim okolnostima ne smije izgubiti - nginx, kao i evidencije grešaka aplikacije. Manji logovi su poslani na preostale čvorove - otklanjanje grešaka, upozorenje itd., a nakon 24 sata prebačeni su "važni" zapisi sa "vrućih" čvorova.

Kako ne bismo povećali broj malih indeksa, prešli smo sa rotacije vremena na mehanizam prevrtanja. Na forumima je bilo dosta informacija da je rotacija po veličini indeksa vrlo nepouzdana, pa smo odlučili koristiti rotaciju prema broju dokumenata u indeksu. Analizirali smo svaki indeks i evidentirali broj dokumenata nakon kojih bi rotacija trebala funkcionirati. Tako smo dostigli optimalnu veličinu šarda - ne više od 50 GB. 

Optimizacija klastera

Kako smo mi u CIAN-u ukrotili terabajte dnevnika

Međutim, nismo se u potpunosti riješili problema. Nažalost, mali indeksi su se i dalje pojavljivali: nisu dostigli navedeni volumen, nisu rotirani i izbrisani su globalnim čišćenjem indeksa starijih od tri dana, jer smo uklonili rotaciju po datumu. To je dovelo do gubitka podataka zbog činjenice da je indeks iz klastera potpuno nestao, a pokušaj upisivanja u nepostojeći indeks slomio je logiku kustosa koji smo koristili za upravljanje. Alias ​​za pisanje je pretvoren u indeks i prekinuo je logiku rollover, uzrokujući nekontrolirani rast nekih indeksa do 600 GB. 

Na primjer, za konfiguraciju rotacije:

с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

Ako nije bilo pseudonima za prelazak, došlo je do greške:

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

Ostavili smo rješenje ovog problema za sljedeću iteraciju i pozabavili se drugim problemom: prešli smo na logiku povlačenja Logstash-a, koja obrađuje dolazne zapise (uklanja nepotrebne informacije i obogaćuje). Smjestili smo ga u docker, koji pokrećemo preko docker-compose, a tamo smo postavili i logstash-exporter, koji šalje metriku Prometheusu za operativni nadzor toka dnevnika. Na ovaj način dali smo sebi priliku da glatko mijenjamo broj logstash instanci odgovornih za obradu svake vrste dnevnika.

Dok smo poboljšavali klaster, promet cian.ru se povećao na 12,8 miliona jedinstvenih korisnika mjesečno. Kao rezultat toga, pokazalo se da su naše transformacije malo zaostajale za promjenama u proizvodnji, a mi smo se suočili s činjenicom da se „topli“ čvorovi nisu mogli nositi s opterećenjem i usporili su cjelokupnu isporuku trupaca. Dobili smo „vruće“ podatke bez grešaka, ali smo morali intervenirati u isporuci ostatka i napraviti ručni rollover kako bismo ravnomjerno rasporedili indekse. 

Istovremeno, skaliranje i mijenjanje postavki logstash instanci u klasteru bilo je komplicirano činjenicom da je to bio lokalni docker-compose, a sve radnje su se izvodile ručno (da biste dodali nove krajeve, bilo je potrebno ručno proći kroz sve servere i docker-compose up -d svuda).

Preraspodjela dnevnika

U septembru ove godine i dalje smo sekli monolit, opterećenje na klasteru se povećavalo, a protok logova se približavao 30 hiljada poruka u sekundi. 

Kako smo mi u CIAN-u ukrotili terabajte dnevnika

Sljedeću iteraciju započeli smo ažuriranjem hardvera. Prešli smo sa pet koordinatora na tri, zamenili čvorove podataka i pobedili u novcu i prostoru za skladištenje. Za čvorove koristimo dvije konfiguracije: 

  • Za "vruće" čvorove: E3-1270 v6 / 960Gb SSD / 32 Gb x 3 x 2 (3 za Hot1 i 3 za Hot2).
  • Za "tople" čvorove: E3-1230 v6 / 4Tb SSD / 32 Gb x 4.

U ovoj iteraciji smo indeks sa pristupnim evidencijama mikroservisa, koji zauzimaju isti prostor kao i prvi nginx logovi, premjestili u drugu grupu od tri „vruća“ čvora. Sada pohranjujemo podatke na "vrućim" čvorovima 20 sati, a zatim ih prenosimo na "tople" čvorove u ostatak dnevnika. 

Problem nestajanja malih indeksa riješili smo rekonfiguracijom njihove rotacije. Sada se indeksi u svakom slučaju rotiraju svaka 23 sata, čak i ako ima malo podataka. Ovo je neznatno povećalo broj šardova (bilo ih je oko 800), ali sa stanovišta performansi klastera to je podnošljivo. 

Kao rezultat toga, bilo je šest „vrućih“ i samo četiri „topla“ čvora u klasteru. Ovo uzrokuje blago kašnjenje zahtjeva u dugim vremenskim intervalima, ali povećanje broja čvorova u budućnosti će riješiti ovaj problem.

Ova iteracija je također riješila problem nedostatka poluautomatskog skaliranja. Da bismo to učinili, postavili smo infrastrukturni Nomad klaster – sličan onome što smo već implementirali u proizvodnji. Za sada se količina Logstasha ne mijenja automatski ovisno o opterećenju, ali ćemo doći do toga.

Kako smo mi u CIAN-u ukrotili terabajte dnevnika

Planovi za budućnost

Implementirana konfiguracija se savršeno skalira, a sada pohranjujemo 13,3 TB podataka - sve evidencije za 4 dana, što je neophodno za hitnu analizu upozorenja. Neke od dnevnika pretvaramo u metriku, koju dodajemo u Graphite. Da bismo olakšali posao inženjerima, imamo metriku za infrastrukturni klaster i skripte za poluautomatsko popravljanje uobičajenih problema. Nakon povećanja broja čvorova podataka, što je planirano za narednu godinu, prelazimo na skladištenje podataka sa 4 na 7 dana. To će biti dovoljno za operativni rad, jer se uvijek trudimo da incidente istražimo što je prije moguće, a za dugoročne istrage postoje telemetrijski podaci. 

U oktobru 2019. promet na cian.ru je već porastao na 15,3 miliona jedinstvenih korisnika mjesečno. Ovo je postalo ozbiljan test arhitektonskog rješenja za isporuku trupaca. 

Sada se spremamo da ažuriramo ElasticSearch na verziju 7. Međutim, za to ćemo morati ažurirati mapiranje mnogih indeksa u ElasticSearch-u, budući da su prešli iz verzije 5.5 i deklarirani su kao zastarjeli u verziji 6 (jednostavno ne postoje u verziji 7). To znači da će tokom procesa ažuriranja sigurno doći do neke vrste više sile, koja će nas ostaviti bez evidencije dok se problem riješi. Od verzije 7, najviše se radujemo Kibani sa poboljšanim interfejsom i novim filterima. 

Ostvarili smo naš glavni cilj: prestali smo gubiti evidenciju i smanjili vrijeme zastoja infrastrukturnog klastera sa 2-3 pada tjedno na nekoliko sati rada na održavanju mjesečno. Sav ovaj rad u proizvodnji gotovo je nevidljiv. Međutim, sada možemo tačno utvrditi šta se dešava sa našom uslugom, možemo to brzo da uradimo u tihom režimu i ne brinemo da će se zapisnici izgubiti. Generalno, zadovoljni smo, sretni i spremamo se za nove podvige, o kojima ćemo kasnije.

izvor: www.habr.com

Dodajte komentar