Ako sme v CIAN skrotili terabajty logov

Ako sme v CIAN skrotili terabajty logov

Ahojte všetci, volám sa Alexander, pracujem v CIAN ako inžinier a zaoberám sa správou systému a automatizáciou procesov infraštruktúry. V komentároch k jednému z predchádzajúcich článkov sme boli požiadaní, aby sme povedali, odkiaľ získavame 4 TB protokolov za deň a čo s nimi robíme. Áno, máme veľa logov a na ich spracovanie bol vytvorený samostatný klaster infraštruktúry, čo nám umožňuje rýchlo riešiť problémy. V tomto článku budem hovoriť o tom, ako sme ho v priebehu roka prispôsobili, aby fungoval so stále rastúcim tokom údajov.

Kde sme začali?

Ako sme v CIAN skrotili terabajty logov

Za posledných niekoľko rokov sa zaťaženie na stránke cian.ru veľmi rýchlo zvýšilo a do tretieho štvrťroka 2018 návštevnosť zdrojov dosiahla 11.2 milióna jedinečných používateľov mesačne. Vtedy sme v kritických momentoch stratili až 40% denníkov, preto sme sa nevedeli rýchlo vysporiadať s incidentmi a vynaložili sme veľa času a úsilia na ich riešenie. Často sme tiež nevedeli nájsť príčinu problému a po nejakom čase sa to opakovalo. Bolo to peklo a bolo treba s tým niečo robiť.

Na ukladanie protokolov sme vtedy používali klaster 10 dátových uzlov s ElasticSearch verzie 5.5.2 so štandardným nastavením indexu. Bolo predstavené pred viac ako rokom ako obľúbené a cenovo dostupné riešenie: vtedy tok guľatiny nebol taký veľký, nemalo zmysel vymýšľať neštandardné konfigurácie. 

Spracovanie prichádzajúcich protokolov zabezpečoval Logstash na rôznych portoch na piatich koordinátoroch ElasticSearch. Jeden index bez ohľadu na veľkosť pozostával z piatich črepov. Bola organizovaná hodinová a denná rotácia, v dôsledku čoho sa v zhluku každú hodinu objavilo asi 100 nových črepov. Aj keď nebolo veľa protokolov, klaster sa vyrovnal dobre a nikto nevenoval pozornosť jeho nastaveniam. 

Výzvy rýchleho rastu

Objem generovaných protokolov veľmi rýchlo rástol, keďže sa dva procesy navzájom prekrývali. Na jednej strane rástol počet používateľov služby. Na druhej strane sme začali aktívne prechádzať na architektúru mikroslužieb a pílili sme naše staré monolity v C# a Pythone. Niekoľko desiatok nových mikroslužieb, ktoré nahradili časti monolitu, vygenerovalo výrazne viac protokolov pre klaster infraštruktúry. 

Bolo to škálovanie, ktoré nás priviedlo do bodu, keď sa zhluk stal prakticky neovládateľný. Keď začali protokoly prichádzať rýchlosťou 20 tisíc správ za sekundu, časté zbytočné otáčanie zvýšilo počet zlomkov na 6 tisíc a na jeden uzol bolo viac ako 600 zlomkov. 

To viedlo k problémom s alokáciou pamäte RAM a keď došlo k zlyhaniu uzla, všetky úlomky sa začali pohybovať súčasne, čím sa znásobila návštevnosť a načítali sa ďalšie uzly, čo takmer znemožňovalo zapisovanie údajov do klastra. A v tomto období sme zostali bez polená. A ak sa vyskytol problém so serverom, v podstate sme stratili 1/10 klastra. Veľký počet malých indexov pridal na zložitosti.

Bez protokolov sme nechápali dôvody incidentu a mohli sme skôr či neskôr opäť stúpiť na tie isté hrable, čo bolo v ideológii nášho tímu neprijateľné, keďže všetky naše pracovné mechanizmy sú navrhnuté tak, aby robili pravý opak – nikdy sa neopakovali rovnaké problémy. Na to sme potrebovali celý objem protokolov a ich doručenie takmer v reálnom čase, keďže tím technikov v službe monitoroval upozornenia nielen z metrík, ale aj z protokolov. Aby sme pochopili rozsah problému, v tom čase bol celkový objem protokolov asi 2 TB za deň. 

Stanovili sme si cieľ úplne eliminovať stratu protokolov a skrátiť čas ich doručenia do klastra ELK na maximálne 15 minút počas vyššej moci (na tento údaj sme sa neskôr spoliehali ako na interný KPI).

Nový rotačný mechanizmus a horúce-teplé uzly

Ako sme v CIAN skrotili terabajty logov

Konverziu klastra sme začali aktualizáciou verzie ElasticSearch z 5.5.2 na 6.4.3. Náš klaster verzie 5 opäť zomrel a rozhodli sme sa ho vypnúť a úplne aktualizovať - ​​stále neexistujú žiadne protokoly. Takže tento prechod sme urobili len za pár hodín.

Najrozsiahlejšou transformáciou v tejto fáze bola implementácia Apache Kafka na troch uzloch s koordinátorom ako medziľahlou vyrovnávacou pamäťou. Sprostredkovateľ správ nás zachránil pred stratou protokolov počas problémov s ElasticSearch. Zároveň sme do klastra pridali 2 uzly a prešli na hot-warm architektúru s tromi „horúcimi“ uzlami umiestnenými v rôznych stojanoch v dátovom centre. Logy sme na ne presmerovali pomocou masky, ktorá by sa za žiadnych okolností nemala stratiť – nginx, ako aj protokoly chýb aplikácií. Do zostávajúcich uzlov boli odoslané vedľajšie protokoly - ladenie, varovanie atď., A po 24 hodinách boli prenesené „dôležité“ protokoly z „horúcich“ uzlov.

Aby sa nezvyšoval počet malých indexov, prešli sme z rotácie času na mechanizmus rollover. Na fórach bolo veľa informácií, že rotácia podľa veľkosti indexu je veľmi nespoľahlivá, preto sme sa rozhodli použiť rotáciu podľa počtu dokumentov v indexe. Analyzovali sme každý index a zaznamenali sme počet dokumentov, po ktorých by rotácia mala fungovať. Dosiahli sme teda optimálnu veľkosť fragmentu – nie viac ako 50 GB. 

Optimalizácia klastra

Ako sme v CIAN skrotili terabajty logov

Problémov sme sa však úplne nezbavili. Bohužiaľ, stále sa objavovali malé indexy: nedosiahli zadaný objem, neboli rotované a boli vymazané globálnym čistením indexov starších ako tri dni, keďže sme odstránili rotáciu podľa dátumu. To viedlo k strate údajov v dôsledku toho, že index z klastra úplne zmizol a pokus o zápis do neexistujúceho indexu narušil logiku kurátora, ktorý sme použili na správu. Alias ​​pre zápis bol prevedený na index a prelomil logiku prevrátenia, čo spôsobilo nekontrolovaný nárast niektorých indexov až na 600 GB. 

Napríklad pre konfiguráciu rotácie:

с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

Ak neexistoval žiadny alias prevrátenia, vyskytla sa chyba:

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

Riešenie tohto problému sme nechali na ďalšiu iteráciu a venovali sme sa ďalšiemu problému: prešli sme na logiku ťahania Logstash, ktorá spracováva prichádzajúce protokoly (odstraňovanie nepotrebných informácií a obohacovanie). Umiestnili sme ho do dockeru, ktorý spúšťame cez docker-compose a umiestnili sme tam aj logstash-exporter, ktorý posiela metriky do Prometheusu na operatívne sledovanie streamu logov. Takto sme si dali možnosť plynule zmeniť počet inštancií logstash zodpovedných za spracovanie každého typu denníka.

Počas zlepšovania klastra sa návštevnosť stránky cian.ru zvýšila na 12,8 milióna jedinečných používateľov mesačne. Vo výsledku sa ukázalo, že naše premeny trochu zaostali za zmenami vo výrobe a stretli sme sa s tým, že „teplé“ uzly nezvládli záťaž a spomalili celú dodávku guľatiny. „Horúce“ dáta sme dostali bez zlyhaní, ale museli sme zasiahnuť do doručenia zvyšku a urobiť manuálny rollover, aby sme indexy rovnomerne rozdelili. 

Zároveň škálovanie a zmena nastavení inštancií logstash v klastri komplikovala skutočnosť, že išlo o lokálny docker-compose a všetky akcie sa vykonávali ručne (pre pridávanie nových koncov bolo potrebné manuálne prejsť všetky servery a všade urobte docker-compose up -d).

Prerozdelenie denníkov

V septembri tohto roku sme monolit ešte strihali, zaťaženie klastra sa zvyšovalo a tok logov sa blížil k 30 tisícom správ za sekundu. 

Ako sme v CIAN skrotili terabajty logov

Ďalšiu iteráciu sme začali aktualizáciou hardvéru. Prešli sme z piatich koordinátorov na troch, vymenili sme dátové uzly a vyhrali sme v peniazoch a úložnom priestore. Pre uzly používame dve konfigurácie: 

  • Pre „horúce“ uzly: E3-1270 v6 / 960 Gb SSD / 32 Gb x 3 x 2 (3 pre Hot1 a 3 pre Hot2).
  • Pre „teplé“ uzly: E3-1230 v6 / 4Tb SSD / 32 Gb x 4.

V tejto iterácii sme index s prístupovými protokolmi mikroslužieb, ktoré zaberajú rovnaký priestor ako protokoly nginx v prvej línii, presunuli do druhej skupiny troch „horúcich“ uzlov. Teraz ukladáme údaje na „horúcich“ uzloch na 20 hodín a potom ich prenesieme do „teplých“ uzlov do zvyšku protokolov. 

Problém miznutia malých indexov sme vyriešili prekonfigurovaním ich rotácie. Teraz sa indexy v každom prípade otáčajú každých 23 hodín, aj keď je tam málo údajov. To mierne zvýšilo počet črepov (bolo ich asi 800), ale z hľadiska výkonnosti klastra je to únosné. 

Výsledkom bolo, že v klastri bolo šesť „horúcich“ a iba štyri „teplé“ uzly. To spôsobuje mierne oneskorenie žiadostí v dlhých časových intervaloch, ale zvýšenie počtu uzlov v budúcnosti tento problém vyrieši.

Táto iterácia tiež vyriešila problém nedostatku poloautomatického škálovania. Na tento účel sme nasadili infraštruktúrny klaster Nomad – podobný tomu, ktorý sme už nasadili do produkcie. Zatiaľ sa množstvo Logstashe automaticky nemení v závislosti od zaťaženia, ale k tomu sa dostaneme.

Ako sme v CIAN skrotili terabajty logov

Plány do budúcnosti

Implementovaná konfigurácia je perfektne škálovateľná a teraz ukladáme 13,3 TB dát – všetky protokoly na 4 dni, čo je potrebné na núdzovú analýzu výstrah. Niektoré záznamy prevedieme na metriky, ktoré pridáme do grafu. Na uľahčenie práce inžinierov máme metriky pre klaster infraštruktúry a skripty na poloautomatickú opravu bežných problémov. Po navýšení počtu dátových uzlov, ktoré je plánované na budúci rok, prejdeme na ukladanie dát zo 4 na 7 dní. Na operatívnu prácu to bude stačiť, keďže sa vždy snažíme čo najskôr vyšetriť incidenty a na dlhodobé vyšetrovanie sú tu telemetrické údaje. 

V októbri 2019 už návštevnosť na stránke cian.ru vzrástla na 15,3 milióna jedinečných používateľov mesačne. To sa stalo vážnym testom architektonického riešenia dodávky guľatiny. 

Teraz pripravujeme aktualizáciu ElasticSearch na verziu 7. Na to však budeme musieť aktualizovať mapovanie mnohých indexov v ElasticSearch, keďže prešli z verzie 5.5 a vo verzii 6 boli deklarované ako zastarané (vo verzii jednoducho neexistujú 7). To znamená, že počas procesu aktualizácie určite dôjde k nejakej vyššej moci, ktorá nás zanechá bez protokolov, kým sa problém vyrieši. Z verzie 7 sa najviac tešíme na Kibanu s vylepšeným rozhraním a novými filtrami. 

Dosiahli sme náš hlavný cieľ: prestali sme strácať protokoly a znížili sme prestoje klastra infraštruktúry z 2 – 3 zlyhaní za týždeň na niekoľko hodín údržby mesačne. Všetka táto práca vo výrobe je takmer neviditeľná. Teraz však vieme presne určiť, čo sa deje s našou službou, môžeme to urobiť rýchlo v tichom režime a nemusíme sa báť, že sa protokoly stratia. Vo všeobecnosti sme spokojní, šťastní a pripravujeme sa na nové exploity, o ktorých budeme hovoriť neskôr.

Zdroj: hab.com

Pridať komentár