Kako smo u CIAN-u ukrotili terabajte dnevnika

Kako smo u CIAN-u ukrotili terabajte dnevnika

Pozdrav svima, moje ime je Alexander, radim u CIAN-u kao inženjer i bavim se administracijom sustava i automatizacijom infrastrukturnih procesa. U komentarima na jedan od prethodnih članaka zamoljeni smo da kažemo odakle nam 4 TB logova dnevno i što radimo s njima. Da, imamo puno zapisa, a za njihovu obradu kreiran je zaseban infrastrukturni klaster, što nam omogućuje brzo rješavanje problema. U ovom ću članku govoriti o tome kako smo ga prilagodili tijekom godine dana za rad sa stalno rastućim protokom podataka.

Gdje smo počeli?

Kako smo u CIAN-u ukrotili terabajte dnevnika

Tijekom proteklih nekoliko godina opterećenje na cian.ru raslo je vrlo brzo, a do trećeg kvartala 2018. promet resursa dosegnuo je 11.2 milijuna jedinstvenih korisnika mjesečno. Tada smo u kritičnim trenucima gubili i do 40% logova, zbog čega nismo mogli brzo rješavati incidente i trošili smo puno vremena i truda na njihovo rješavanje. Također često nismo mogli pronaći uzrok problema, a on bi se nakon nekog vremena ponovio. Bio je to pakao i s tim se nešto moralo učiniti.

U to smo vrijeme koristili klaster od 10 podatkovnih čvorova s ​​ElasticSearch verzijom 5.5.2 sa standardnim postavkama indeksa za pohranu zapisa. 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 zapisa osigurao je Logstash na različitim portovima na pet ElasticSearch koordinatora. Jedan indeks, bez obzira na veličinu, sastojao se od pet fragmenata. Organizirana je satnica i dnevna rotacija, kao rezultat toga, oko 100 novih fragmenata pojavilo se u klasteru svakog sata. Iako nije bilo mnogo zapisa, klaster se dobro nosio i nitko nije obraćao pozornost na njegove postavke. 

Izazovi brzog rasta

Količina generiranih zapisa rasla je vrlo brzo, jer su se dva procesa preklapala. S jedne strane, rastao je broj korisnika usluge. S druge strane, počeli smo aktivno prelaziti na mikroservisnu arhitekturu, piljenjem naših starih monolita u C# i Pythonu. Nekoliko desetaka novih mikroservisa koji su zamijenili dijelove monolita generiralo je znatno više zapisa za infrastrukturni klaster. 

Upravo nas je skaliranje dovelo do točke u kojoj je klaster postao praktički neupravljiv. Kada su dnevnici počeli pristizati brzinom od 20 tisuća poruka u sekundi, česta beskorisna rotacija povećala je broj shardova na 6 tisuća, a bilo je više od 600 shardova po čvoru. 

To je dovelo do problema s dodjelom RAM-a, a kada bi se čvor srušio, svi shardovi su se počeli kretati istovremeno, umnožavajući promet i učitavajući druge čvorove, što je učinilo gotovo nemogućim pisanje podataka u klaster. I u tom periodu ostali smo bez balvana. A ako je bilo problema s poslužiteljem, u biti smo izgubili 1/10 klastera. Velik broj malih indeksa dodao je složenost.

Bez balvana nismo razumjeli razloge incidenta i mogli bismo prije ili kasnije ponovno stati na iste grablje, au ideologiji našeg tima to je bilo nedopustivo, budući da su svi naši mehanizmi rada osmišljeni da čine upravo suprotno - nikad se ne ponavlja isti problemi. Da bismo to učinili, bila nam je potrebna puna količina zapisa i njihova isporuka gotovo u stvarnom vremenu, budući da je tim dežurnih inženjera pratio upozorenja ne samo iz metrike, već i iz zapisa. Da bismo razumjeli razmjere problema, u to je vrijeme ukupna količina zapisa iznosila oko 2 TB dnevno. 

Postavili smo cilj potpuno eliminirati gubitak logova i smanjiti vrijeme njihove dostave ELK klasteru na najviše 15 minuta tijekom više sile (kasnije smo se oslanjali na ovu brojku kao interni KPI).

Novi mehanizam rotacije i vruće-tople čvorove

Kako smo u CIAN-u ukrotili terabajte dnevnika

Započeli smo konverziju klastera ažuriranjem verzije ElasticSearch s 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 zapisa. Tako smo ovaj prijelaz napravili u samo nekoliko sati.

Najveća transformacija u ovoj fazi bila je implementacija Apache Kafke na tri čvora s koordinatorom kao međuspremnikom. Broker poruka spasio nas je od gubitka zapisa tijekom problema s ElasticSearchom. U isto vrijeme, dodali smo 2 čvora u klaster i prebacili se na toplo-toplu arhitekturu s tri "vruća" čvora smještena u različitim policama u podatkovnom centru. Logove smo preusmjeravali njima pomoću maske koja se ni pod kojim uvjetima ne smije izgubiti - nginx, kao i logove grešaka aplikacije. Preostalim čvorovima slani su manji zapisi - otklanjanje pogrešaka, upozorenje itd., a nakon 24 sata prebačeni su "važni" zapisi s "vrućih" čvorova.

Kako se ne bi povećavao broj malih indeksa, prešli smo s 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 po broju dokumenata u indeksu. Analizirali smo svaki indeks i zabilježili broj dokumenata nakon kojih bi rotacija trebala funkcionirati. Tako smo dosegli optimalnu veličinu sharda - ne više od 50 GB. 

Optimizacija klastera

Kako smo 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 dosegli navedeni volumen, nisu se rotirali i brisali su se globalnim čišćenjem indeksa starijih od tri dana, jer smo uklonili rotaciju po datumu. To je dovelo do gubitka podataka jer je indeks iz klastera u potpunosti nestao, a pokušaj upisivanja u nepostojeći indeks razbio je logiku kustosa koji smo koristili za upravljanje. Alias ​​za pisanje pretvoren je u indeks i razbio je logiku prevrtanja, 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 prelamanje, dogodila se pogreška:

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 prihvatili smo se drugog problema: prebacili smo se na logiku povlačenja Logstasha, koja obrađuje dolazne zapise (uklanja nepotrebne informacije i obogaćuje). Smjestili smo ga u docker koji pokrećemo preko docker-composea, a tamo smo smjestili i logstash-exporter koji šalje metriku Prometheusu za operativno praćenje toka zapisa. Na ovaj način dali smo si mogućnost glatke promjene broja instanci logstash-a odgovornih za obradu svake vrste dnevnika.

Dok smo poboljšavali klaster, promet cian.ru porastao je na 12,8 milijuna jedinstvenih korisnika mjesečno. Kao rezultat toga, pokazalo se da naše transformacije malo zaostaju za promjenama u proizvodnji, a mi smo se suočili s činjenicom da se "topli" čvorovi ne mogu nositi s opterećenjem i usporavaju cjelokupnu isporuku trupaca. “Vruće” podatke smo primili bez kvarova, ali smo morali intervenirati u isporuku ostalih i napraviti ručni rollover kako bismo ravnomjerno raspodijelili indekse. 

Istodobno, skaliranje i mijenjanje postavki instanci logstash u klasteru bilo je komplicirano činjenicom da je to bio lokalni docker-compose, a sve su se radnje izvodile ručno (za dodavanje novih krajeva bilo je potrebno ručno proći kroz sve poslužitelje i docker-compose up -d posvuda).

Preraspodjela dnevnika

U rujnu ove godine još smo rezali monolit, opterećenje klastera se povećavalo, a protok logova približavao se 30 tisuća poruka u sekundi. 

Kako smo u CIAN-u ukrotili terabajte dnevnika

Sljedeću smo iteraciju započeli ažuriranjem hardvera. Prešli smo s pet koordinatora na tri, zamijenili podatkovne čvorove i pobijedili što se tiče novca i skladišnog prostora. Za čvorove koristimo dvije konfiguracije: 

  • Za “vruće” čvorove: E3-1270 v6 / 960 Gb 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 smo iteraciji premjestili indeks s pristupnim zapisnicima mikroservisa, koji zauzima isti prostor kao i frontalni nginx zapisnici, u drugu grupu od tri "vruća" čvora. Sada pohranjujemo podatke na "vruće" čvorove 20 sati, a zatim ih prenosimo na "tople" čvorove u ostale zapise. 

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

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

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

Kako smo u CIAN-u ukrotili terabajte dnevnika

Planovi za budućnost

Implementirana konfiguracija se savršeno skalira i sada pohranjujemo 13,3 TB podataka - sve zapise za 4 dana, što je potrebno za hitnu analizu upozorenja. Neke zapisnike pretvaramo u metričke podatke koje dodajemo u Graphite. Kako bismo olakšali posao inženjerima, imamo metriku za infrastrukturni klaster i skripte za poluautomatsko popravljanje uobičajenih problema. Nakon povećanja broja podatkovnih čvorova, koje je planirano za iduću godinu, prelazimo na pohranu podataka s 4 na 7 dana. To će biti dovoljno za operativni rad, jer uvijek nastojimo incidente istražiti što je prije moguće, a za dugotrajne istrage postoje telemetrijski podaci. 

U listopadu 2019. promet na cian.ru već je narastao na 15,3 milijuna jedinstvenih korisnika mjesečno. Ovo je postao ozbiljan test arhitektonskog rješenja za isporuku trupaca. 

Sada se pripremamo ažurirati ElasticSearch na verziju 7. Međutim, za ovo ćemo morati ažurirati mapiranje mnogih indeksa u ElasticSearchu, jer su prešli iz verzije 5.5 i proglašeni su zastarjelim u verziji 6 (jednostavno ne postoje u verziji 7). To znači da će tijekom procesa ažuriranja sigurno doći do neke vrste više sile, koja će nas ostaviti bez zapisa dok se problem riješi. Od verzije 7 najviše se veselimo Kibani s poboljšanim sučeljem i novim filterima. 

Postigli smo naš glavni cilj: zaustavili smo gubitak zapisa i smanjili vrijeme zastoja infrastrukturnog klastera s 2-3 pada tjedno na nekoliko sati rada na održavanju mjesečno. Sav taj rad u proizvodnji je gotovo nevidljiv. Međutim, sada možemo točno odrediti što se događa s našom uslugom, možemo to brzo učiniti u tihom načinu rada i ne brinuti se 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