Kako smo pri CIAN ukrotili terabajte dnevnikov

Kako smo pri CIAN ukrotili terabajte dnevnikov

Pozdravljeni vsi, moje ime je Alexander, delam v CIAN kot inženir in se ukvarjam s sistemsko administracijo in avtomatizacijo infrastrukturnih procesov. V komentarjih na enega od prejšnjih člankov so nas prosili, da povemo, od kod dobimo 4 TB dnevnikov na dan in kaj z njimi počnemo. Da, imamo veliko dnevnikov in za njihovo obdelavo je bil ustvarjen ločen infrastrukturni grozd, ki nam omogoča hitro reševanje težav. V tem članku bom govoril o tem, kako smo ga tekom enega leta prilagodili za delo z vedno večjim tokom podatkov.

Kje smo začeli?

Kako smo pri CIAN ukrotili terabajte dnevnikov

V zadnjih nekaj letih je obremenitev na cian.ru zelo hitro rasla in do tretjega četrtletja 2018 je promet virov dosegel 11.2 milijona edinstvenih uporabnikov na mesec. Takrat smo v kritičnih trenutkih izgubili tudi do 40 % dnevnikov, zato nismo mogli hitro reševati incidentov in smo porabili veliko časa in truda za njihovo reševanje. Pogosto tudi vzroka težave nismo našli in se je čez nekaj časa ponovila. Bil je pekel in glede tega je bilo treba nekaj narediti.

Takrat smo za shranjevanje dnevnikov uporabili gručo 10 podatkovnih vozlišč z ElasticSearch različico 5.5.2 s standardnimi nastavitvami indeksa. Predstavljen je bil pred več kot letom dni kot priljubljena in cenovno dostopna rešitev: takrat pretok hlodov ni bil tako velik, ni bilo smisla ustvarjati nestandardnih konfiguracij. 

Obdelavo dohodnih dnevnikov je zagotovil Logstash na različnih vratih na petih koordinatorjih ElasticSearch. En indeks, ne glede na velikost, je bil sestavljen iz petih drobcev. Organizirana je bila urna in dnevna rotacija, posledično se je vsako uro v gruči pojavilo približno 100 novih drobcev. Čeprav ni bilo veliko dnevnikov, se je gruča dobro spopadla in nihče ni bil pozoren na njene nastavitve. 

Izzivi hitre rasti

Količina generiranih dnevnikov je zelo hitro rasla, saj sta se dva procesa prekrivala. Po eni strani se je povečalo število uporabnikov storitve. Po drugi strani pa smo začeli aktivno prehajati na mikrostoritveno arhitekturo in razrezati naše stare monolite v C# in Python. Več deset novih mikrostoritev, ki so nadomestile dele monolita, je ustvarilo bistveno več dnevnikov za infrastrukturni grozd. 

Skaliranje nas je pripeljalo do točke, ko je grozd postal praktično neobvladljiv. Ko so začeli dnevniki prihajati s hitrostjo 20 tisoč sporočil na sekundo, je pogosto neuporabno vrtenje povečalo število drobcev na 6 tisoč, na vozlišče pa je bilo več kot 600 drobcev. 

To je pripeljalo do težav z dodeljevanjem RAM-a in ko se je vozlišče zrušilo, so se vsi drobci začeli premikati hkrati, pomnožili promet in naložili druga vozlišča, zaradi česar je bilo skoraj nemogoče zapisovati podatke v gručo. In v tem obdobju smo ostali brez polen. In če je bila težava s strežnikom, smo v bistvu izgubili 1/10 gruče. Veliko število majhnih indeksov je dodalo kompleksnost.

Brez hlodov nismo razumeli razlogov za incident in bi lahko prej ali slej spet stopili na iste grablje, kar je bilo v ideologiji naše ekipe nesprejemljivo, saj so vsi naši mehanizmi dela zasnovani tako, da delujejo ravno nasprotno – nikoli več iste težave. Da bi to naredili, smo potrebovali celotno količino dnevnikov in njihovo dostavo skoraj v realnem času, saj je ekipa dežurnih inženirjev spremljala opozorila ne samo iz meritev, ampak tudi iz dnevnikov. Da bi razumeli obseg problema, je bila takrat skupna količina dnevnikov približno 2 TB na dan. 

Zadali smo si cilj, da v primeru višje sile popolnoma odpravimo izgubo dnevnikov in skrajšamo čas njihove dostave v gručo ELK na največ 15 minut (na to številko smo se kasneje oprli kot interni KPI).

Nov rotacijski mehanizem in vroče-tople vozlišča

Kako smo pri CIAN ukrotili terabajte dnevnikov

Pretvorbo gruče smo začeli s posodobitvijo različice ElasticSearch s 5.5.2 na 6.4.3. Ponovno je naša gruča različice 5 umrla in odločili smo se, da jo izklopimo in popolnoma posodobimo - še vedno ni dnevnikov. Tako smo ta prehod opravili v samo nekaj urah.

Najbolj obsežna transformacija na tej stopnji je bila implementacija Apache Kafka na treh vozliščih s koordinatorjem kot vmesnim medpomnilnikom. Posrednik sporočil nas je rešil pred izgubo dnevnikov med težavami z ElasticSearch. Istočasno smo v gručo dodali 2 vozlišči in prešli na toplo-toplo arhitekturo s tremi "vročimi" vozlišči, ki se nahajajo v različnih stojalih v podatkovnem centru. Nanje smo preusmerjali dnevnike z uporabo maske, ki se v nobenem primeru ne sme izgubiti - nginx, kot tudi dnevnike napak aplikacij. Manjši dnevniki so bili poslani preostalim vozliščem - odpravljanje napak, opozorilo itd., Po 24 urah pa so bili preneseni "pomembni" dnevniki iz "vročih" vozlišč.

Da ne bi povečali števila majhnih indeksov, smo prešli s časovne rotacije na mehanizem prevračanja. Na forumih je bilo veliko informacij, da je rotacija po velikosti indeksa zelo nezanesljiva, zato smo se odločili za rotacijo po številu dokumentov v indeksu. Analizirali smo vsak indeks in zabeležili število dokumentov, po katerih naj bi rotacija delovala. Tako smo dosegli optimalno velikost sharda - ne več kot 50 GB. 

Optimizacija grozdov

Kako smo pri CIAN ukrotili terabajte dnevnikov

Težav pa se nismo povsem znebili. Na žalost so se majhni indeksi še vedno pojavljali: niso dosegli določenega obsega, niso bili rotirani in so bili izbrisani z globalnim čiščenjem indeksov, starejših od treh dni, saj smo odstranili rotacijo po datumu. To je povzročilo izgubo podatkov zaradi dejstva, da je indeks iz gruče popolnoma izginil, poskus pisanja v neobstoječi indeks pa je zlomil logiko kuratorja, ki smo ga uporabljali za upravljanje. Vzdevek za pisanje je bil pretvorjen v indeks in je prekinil logiko prevračanja, kar je povzročilo nenadzorovano rast nekaterih indeksov do 600 GB. 

Na primer za konfiguracijo vrtenja:

с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

Če ni bilo vzdevka za prevračanje, je prišlo do napake:

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

Rešitev tega problema smo pustili za naslednjo iteracijo in se lotili drugega: preklopili smo na logiko vleke Logstash, ki obdeluje dohodne dnevnike (odstranjevanje nepotrebnih informacij in obogatitev). Postavili smo ga v docker, ki ga zaženemo prek docker-compose, in tja smo postavili tudi logstash-exporter, ki pošilja metrike Prometheusu za operativno spremljanje toka dnevnika. Na ta način smo si dali možnost gladkega spreminjanja števila instanc logstash, odgovornih za obdelavo vsake vrste dnevnika.

Medtem ko smo izboljševali gručo, se je promet cian.ru povečal na 12,8 milijona edinstvenih uporabnikov na mesec. Posledično se je izkazalo, da so naše transformacije nekoliko zaostajale za spremembami v proizvodnji in soočili smo se z dejstvom, da »topla« vozlišča niso kos obremenitvi in ​​so upočasnila celotno dostavo hlodovine. “Vroče” podatke smo prejeli brez napak, vendar smo morali poseči v dostavo preostalih in narediti ročni rollover, da smo indekse enakomerno porazdelili. 

Hkrati je bilo skaliranje in spreminjanje nastavitev primerkov logstash v gruči zapleteno zaradi dejstva, da je šlo za lokalno docker-compose in so bila vsa dejanja izvedena ročno (za dodajanje novih koncev je bilo treba ročno iti skozi vse strežnike in naredite docker-compose up -d povsod).

Prerazporeditev dnevnika

Septembra letos smo še razrezali monolit, obremenitev grozda je naraščala, pretok dnevnikov pa se je bližal 30 tisoč sporočil na sekundo. 

Kako smo pri CIAN ukrotili terabajte dnevnikov

Naslednjo ponovitev smo začeli s posodobitvijo strojne opreme. S petih koordinatorjev smo prešli na tri, zamenjali podatkovna vozlišča in zmagali pri denarju in prostoru za shranjevanje. Za vozlišča uporabljamo dve konfiguraciji: 

  • Za “vroča” vozlišča: E3-1270 v6 / 960 Gb SSD / 32 Gb x 3 x 2 (3 za Hot1 in 3 za Hot2).
  • Za "topla" vozlišča: E3-1230 v6 / 4Tb SSD / 32 Gb x 4.

Pri tej ponovitvi smo premaknili indeks z dostopnimi dnevniki mikrostoritev, ki zavzemajo enak prostor kot sprednji dnevniki nginx, v drugo skupino treh "vročih" vozlišč. Podatke zdaj hranimo na "vročih" vozliščih 20 ur, nato pa jih prenesemo na "topla" vozlišča v preostale dnevnike. 

Težavo izginotja majhnih indeksov smo rešili s preoblikovanjem njihovega vrtenja. Zdaj se indeksi v vsakem primeru menjajo vsakih 23 ur, tudi če je tam malo podatkov. S tem se je nekoliko povečalo število shardov (bilo jih je približno 800), vendar je z vidika zmogljivosti gruče znosno. 

Posledično je bilo v gruči šest "vročih" in samo štiri "topla" vozlišča. To povzroči rahlo zamudo pri zahtevah v dolgih časovnih intervalih, vendar bo povečanje števila vozlišč v prihodnosti rešilo ta problem.

Ta ponovitev je odpravila tudi problem pomanjkanja polavtomatskega skaliranja. Da bi to naredili, smo uvedli infrastrukturno gručo Nomad – podobno tistemu, ki smo ga že uvedli v proizvodnji. Za zdaj se količina Logstasha ne spreminja samodejno glede na obremenitev, vendar bomo do tega prišli.

Kako smo pri CIAN ukrotili terabajte dnevnikov

Načrti za prihodnost

Implementirana konfiguracija se odlično skalira in zdaj hranimo 13,3 TB podatkov - vse dnevnike za 4 dni, kar je potrebno za nujno analizo opozoril. Nekatere dnevnike pretvorimo v meritve, ki jih dodamo v Graphite. Za lažje delo inženirjev imamo metrike za infrastrukturni grozd in skripte za polavtomatsko popravilo pogostih težav. Po povečanju števila podatkovnih vozlišč, ki je načrtovano v prihodnjem letu, bomo prešli na hrambo podatkov s 4 na 7 dni. Za operativno delo bo to dovolj, saj se vedno trudimo čim prej preiskati dogodke, za dolgoročne preiskave pa so na voljo telemetrijski podatki. 

Oktobra 2019 je promet na cian.ru že narasel na 15,3 milijona edinstvenih uporabnikov na mesec. To je postal resen preizkus arhitekturne rešitve za dostavo hlodov. 

Zdaj se pripravljamo na posodobitev ElasticSearch na različico 7. Vendar bomo za to morali posodobiti preslikavo številnih indeksov v ElasticSearch, saj so prešli iz različice 5.5 in so bili v različici 6 razglašeni za zastarele (preprosto ne obstajajo v različici 7). To pomeni, da bo med postopkom posodobitve zagotovo prišlo do neke vrste višje sile, zaradi katere bomo ostali brez dnevnikov, medtem ko bo težava rešena. Od različice 7 se najbolj veselimo Kibane z izboljšanim vmesnikom in novimi filtri. 

Dosegli smo glavni cilj: prenehali smo izgubljati dnevnike in zmanjšali čas izpada infrastrukturnega grozda z 2-3 zrušitev na teden na nekaj ur vzdrževalnih del na mesec. Vse to delo v proizvodnji je skoraj nevidno. Zdaj pa lahko natančno ugotovimo, kaj se dogaja z našo storitvijo, lahko to storimo hitro v tihem načinu in ne skrbimo, da se bodo dnevniki izgubili. Na splošno smo zadovoljni, srečni in se pripravljamo na nove podvige, o katerih bomo kasneje.

Vir: www.habr.com

Dodaj komentar