Kako smo preživjeli povećanje opterećenja x10 na daljinu i koje smo zaključke izvukli

Zdravo, Habr! Posljednjih nekoliko mjeseci živimo u vrlo zanimljivoj situaciji i želio bih podijeliti našu priču o skaliranju infrastrukture. Za to vrijeme, SberMarket je povećao narudžbe 4 puta i pokrenuo uslugu u 17 novih gradova. Eksplozivni rast potražnje za dostavom namirnica zahtijevao je od nas da povećamo svoju infrastrukturu. O najzanimljivijim i najkorisnijim zaključcima pročitajte ispod.

Kako smo preživjeli povećanje opterećenja x10 na daljinu i koje smo zaključke izvukli

Moje ime je Dima Bobylev, ja sam tehnički direktor SberMarketa. Pošto je ovo prvi post na našem blogu, reći ću nekoliko riječi o sebi i kompaniji. Prošle jeseni sam učestvovao na takmičenju mladih lidera Runeta. Za takmičenje I napisao kratku priču o tome kako mi u SberMarketu vidimo internu kulturu i pristup razvoju usluga. I iako nisam uspeo da pobedim na takmičenju, formulisao sam za sebe osnovne principe razvoja IT ekosistema.

Prilikom upravljanja timom, važno je razumjeti i pronaći ravnotežu između onoga što je potrebno poslovanju i potreba svakog pojedinačnog developera. Sada SberMarket raste 13 puta godišnje, a to utiče na proizvod, zahtijevajući od njega stalno povećanje obima i tempa razvoja. Unatoč tome, programerima izdvajamo dovoljno vremena za preliminarnu analizu i kvalitetno kodiranje. Formirani pristup pomaže ne samo u stvaranju radnog proizvoda, već iu njegovom daljnjem skaliranju i razvoju. Kao rezultat ovog rasta, SberMarket je već postao lider među uslugama dostave namirnica: svakodnevno isporučujemo oko 18 hiljada narudžbi dnevno, iako ih je početkom februara bilo oko 3500.

Kako smo preživjeli povećanje opterećenja x10 na daljinu i koje smo zaključke izvukli
Jednog dana, klijent je zamolio kurira SberMarketa da mu isporuči namirnice beskontaktno - pravo na balkon

Ali pređimo na pojedinosti. U proteklih nekoliko mjeseci, aktivno smo skalirali infrastrukturu naše kompanije. Ova potreba je objašnjena vanjskim i unutrašnjim faktorima. Uz širenje baze kupaca, broj povezanih trgovina porastao je sa 90 na početku godine na više od 200 do sredine svibnja. Mi smo, naravno, bili pripremljeni, rezervisali smo glavnu infrastrukturu, plus računali smo na mogućnost vertikalnog i horizontalnog skaliranja svih virtuelnih mašina smeštenih u Yandex oblaku. Međutim, praksa je pokazala: „Sve što može poći naopako, poći će po zlu“. I danas želim podijeliti najzanimljivije situacije koje su se desile ovih sedmica. Nadam se da će vam naše iskustvo biti od koristi.

Slave je u punoj borbenoj gotovosti

I prije početka pandemije bili smo suočeni s povećanjem broja zahtjeva prema našim backend serverima. Trend naručivanja namirnica za kućnu dostavu počeo je da se zahuktava, a uvođenjem prvih mjera samoizolacije zbog COVID-19, opterećenje je drastično poraslo tokom dana. Postojala je potreba da se brzo isprazne glavni serveri glavne baze podataka i prenesu neki od zahteva za čitanje na repliku servera (slave).

Za ovaj korak smo se pripremili unaprijed, a 2 slave servera su već pokrenuta za takav manevar. Uglavnom su korišteni za paketne zadatke generiranja feedova informacija za razmjenu podataka sa partnerima. Ovi procesi su stvarali dodatno opterećenje i sasvim opravdano su izbačeni iz jednačine nekoliko mjeseci ranije. 

Pošto se replikacija dogodila na Slave-u, pridržavali smo se koncepta da aplikacije mogu raditi s njima samo u načinu samo za čitanje. Plan oporavka od katastrofe pretpostavljao je da u slučaju katastrofe možemo jednostavno montirati Slave umjesto glavnog i prebaciti sve zahtjeve za pisanje i čitanje na Slave. Međutim, željeli smo koristiti i replike za potrebe odjela za analitiku, tako da serveri nisu u potpunosti prebačeni na status samo za čitanje, već je svaki host imao svoj skup korisnika, a neki su imali i prava pisanja za spremanje međurezultata proračuna.

Do određenog nivoa opterećenja imali smo dovoljno mastera i za pisanje i za čitanje prilikom obrade http zahtjeva. Sredinom marta, baš kada je Sbermarket odlučio da u potpunosti pređe na daljinski rad, naš RPS je počeo eksponencijalno da raste. Sve je više naših klijenata odlazilo u samoizolaciju ili radilo od kuće, što je uticalo na naše pokazatelje opterećenja.

Performanse "mastera" više nisu bile dovoljne, pa smo počeli da prenosimo neke od najtežih zahteva za čitanje na repliku. Za transparentno usmjeravanje zahtjeva za pisanje do mastera i za čitanje zahtjeva za slave, koristili smo rubin dragulj "hobotnica" Napravili smo posebnog korisnika sa postfiksom _readonly bez prava pisanja. Ali zbog greške u konfiguraciji jednog od hostova, neki od zahtjeva za pisanje su otišli na slave server u ime korisnika koji je imao odgovarajuća prava.

Problem se nije odmah ispoljio, jer... povećano opterećenje povećalo je zaostajanje robova. Neusklađenost podataka otkrivena je u jutarnjim satima kada, nakon noćnog uvoza, robovi nisu "sustigli" gospodara. To smo pripisali velikom opterećenju same usluge i uvoza povezanim s pokretanjem novih trgovina. Ali slanje podataka sa višesatnim kašnjenjem bilo je neprihvatljivo, pa smo procese prebacili na drugi analitički slave, jer je imaoоveće resurse i nije bio opterećen zahtjevima za čitanje (na taj način smo sami sebi objasnili nedostatak kašnjenja replikacije).

Kada smo shvatili razloge „širenja“ glavnog roba, analitički je već propao iz istog razloga. Unatoč prisutnosti dva dodatna servera na koje smo planirali prebaciti opterećenje u slučaju kvara mastera, zbog nesretne greške ispostavilo se da u kritičnom trenutku nema dostupnih.

Ali pošto nismo samo izbacili bazu podataka (restorativni proces je u to vreme trajao oko 5 sati), već i snimak glavnog servera, uspeli smo da pokrenemo repliku u roku od 2 sata. Istina, nakon toga smo se dugo vremena suočavali sa prevrtanjem dnevnika replikacije (jer proces radi u single-threaded modu, ali to je sasvim druga priča).

Zaključak: Nakon ovakvog incidenta postalo je jasno da je potrebno napustiti praksu ograničavanja pisanja za korisnike i proglasiti cijeli server samo za čitanje. Uz ovaj pristup, nema sumnje da će replike biti dostupne u kritičnim trenucima.

Optimizacija čak i jednog teškog upita može vratiti bazu podataka u život

Iako konstantno ažuriramo katalog na stranici, zahtjevi koje smo slali Slave serverima dopuštali su neznatno zaostajanje u odnosu na Master. Vrijeme u kojem smo otkrili i eliminisali problem da robovi „iznenadno napuštaju distancu“ bilo je više od „psihološke barijere“ (za to vrijeme cijene su mogle biti ažurirane, a klijenti bi vidjeli zastarjele podatke), a mi smo bili primorani da prebaciti sve zahtjeve na glavni server baze podataka. Kao rezultat toga, stranica je bila spora... ali je barem funkcionirala. I dok se Slave oporavljao, nismo imali izbora osim optimizacije. 

Dok su se Slave serveri oporavljali, minute su polako prolazile, Master je ostao preopterećen, a mi smo sve svoje napore uložili u optimizaciju aktivnih zadataka prema „Pareto pravilu“: odabrali smo TOP zahtjeve koji generiraju većinu opterećenja i počeli smo podešavanje . Ovo je urađeno u hodu.

Zanimljiv efekat je da je MySQL, napunjen do maksimuma, reagovao čak i na neznatno poboljšanje procesa. Optimizacija nekoliko upita koji su proizveli samo 5% ukupnog opterećenja je već pokazala primjetno opterećenje CPU-a. Kao rezultat toga, uspjeli smo obezbijediti prihvatljivu zalihu resursa za Mastera za rad sa bazom podataka i dobiti potrebno vrijeme za obnavljanje replika. 

Zaključak: Čak i mala optimizacija omogućava vam da "preživite" pod preopterećenjem nekoliko sati. Ovo nam je bilo dovoljno da vratimo servere sa replikama. Inače, o tehničkoj strani optimizacije upita ćemo raspravljati u jednom od sljedećih postova. Zato se pretplatite na naš blog ako smatrate da je koristan.

Organizirati praćenje rada partnerskih usluga

Obrađujemo narudžbe kupaca, te stoga naše usluge stalno komuniciraju s API-jima trećih strana - to su pristupnici za slanje SMS-a, platforme za plaćanje, sistemi za rutiranje, geokoder, Federalna porezna služba i mnogi drugi sistemi. A kada je opterećenje počelo naglo da raste, počeli smo da nailazimo na API ograničenja naših partnerskih usluga, o kojima ranije nismo ni razmišljali.

Neočekivano prekoračenje kvota partnerskih usluga može dovesti do vašeg zastoja. Mnogi API-ji blokiraju klijente koji prelaze ograničenja, au nekim slučajevima previše zahtjeva može preopteretiti partnerovu produkciju. 

Na primjer, kada je broj isporuka rastao, prateće službe nisu mogle da se nose sa zadacima njihove distribucije i utvrđivanja ruta. Kao rezultat toga, ispostavilo se da su narudžbe napravljene, ali usluga koja je kreirala rutu nije radila. Mora se reći da su naši logističari učinili gotovo nemoguće u ovakvim uslovima, a jasna interakcija tima pomogla je da se kompenziraju privremeni kvarovi u servisu. Ali nerealno je da se toliki obim naloga stalno obrađuje ručno, a nakon nekog vremena bili bismo suočeni s neprihvatljivim jazom između naloga i njihovog izvršenja. 

Poduzeto je niz organizacionih mjera, a dobro koordiniran rad tima pomogao je da dobijemo na vremenu dok smo dogovarali nove uslove i čekali modernizaciju usluga od nekih partnera. Postoje i drugi API-ji koji se mogu pohvaliti velikom izdržljivošću i nečuvenim stopama u slučaju velikog prometa. Na primjer, u početku smo koristili jedan dobro poznati API za mapiranje da bismo odredili adresu mjesta isporuke. Ali na kraju mjeseca dobili smo uredan račun od skoro 2 miliona rubalja. Nakon toga su odlučili da ga brzo zamene. Neću se baviti reklamom, ali reći ću da su nam troškovi značajno smanjeni.
Kako smo preživjeli povećanje opterećenja x10 na daljinu i koje smo zaključke izvukli

Zaključak: Neophodno je pratiti uslove rada svih partnerskih službi i imati ih na umu. Čak i ako se danas čini da su za vas „sa velikom marginom“, to ne znači da sutra neće postati prepreka rastu. I, naravno, bolje je unaprijed dogovoriti finansijske uslove povećanih zahtjeva za uslugu. 

Ponekad se ispostavi da "Treba mi još zlata"(c) ne pomaže

Navikli smo na “gegove” u glavnoj bazi podataka ili na aplikacijskim serverima, ali prilikom skaliranja mogu se pojaviti problemi tamo gdje nisu očekivani.Za pretraživanje po cijelom tekstu na stranici koristimo Apache Solr engine. Kako se opterećenje povećavalo, primijetili smo smanjenje vremena odgovora, a opterećenje serverskog procesora je već dostiglo 100%. Šta može biti jednostavnije - damo kontejneru sa Solrom više resursa.

Umjesto očekivanog povećanja performansi, server je jednostavno "umro". Odmah se učitao na 100% i reagirao još sporije. U početku smo imali 2 jezgra i 2 GB RAM-a. Odlučili smo da uradimo ono što obično pomaže - dali smo serveru 8 jezgara i 32 GB. Sve je postalo mnogo gore (tačno kako i zašto ćemo vam reći u posebnom postu). 

Tokom nekoliko dana shvatili smo zamršenost ovog problema i postigli optimalne performanse sa 8 jezgara i 32 GB. Ovakva konfiguracija nam omogućava da nastavimo da povećavamo opterećenje danas, što je veoma važno, jer rast nije samo kod klijenata, već i broja povezanih prodavnica - za 2 meseca njihov broj se udvostručio. 

Zaključak: Standardne metode poput „dodavanja više gvožđa“ ne rade uvijek. Dakle, kada skalirate bilo koju uslugu, morate dobro razumjeti kako ona koristi resurse i unaprijed testirati njen rad u novim uvjetima. 

Bez državnosti je ključ za lako horizontalno skaliranje

Generalno, naš tim slijedi dobro poznati pristup: servisi ne bi trebali imati interno stanje (bez stanja) i trebali bi biti nezavisni od okruženja izvršavanja. To nam je omogućilo da se nosimo s rastom opterećenja jednostavnim horizontalnim skaliranjem. Ali imali smo jedan izuzetak servis - rukovalac za duge pozadinske zadatke. Bio je uključen u slanje e-pošte i sms poruka, obradu događaja, generiranje feedova, uvoz cijena i dionica i obradu slika. Dogodilo se da ovisi o lokalnoj pohrani datoteka i da je u jednoj kopiji. 

Kada se broj zadataka u redu čekanja procesora povećao (a to se prirodno dogodilo s povećanjem broja naloga), performanse hosta na kojem su se nalazili procesor i skladište datoteka postali su ograničavajući faktor. Kao rezultat toga, zaustavljeno je ažuriranje asortimana i cijena, slanje obavještenja korisnicima i mnoge druge kritične funkcije koje su bile zaglavljene u redu čekanja. Ops tim je brzo migrirao pohranu datoteka u mrežnu pohranu nalik S3, a to nam je omogućilo da podignemo nekoliko moćnih strojeva za skaliranje pozadinskog procesora zadataka.

Zaključak: Pravilo bez državljanstva mora se poštovati za sve komponente bez izuzetka, čak i ako se čini da „ovde definitivno nećemo moći da odolimo“. Bolje je potrošiti malo vremena na pravilno organiziranje rada svih sistema nego na brzinu prepisivati ​​kod i popravljati preopterećenu uslugu.

7 principa za intenzivan rast

Unatoč dostupnosti dodatnih kapaciteta, nagazili smo na nekoliko grešaka u procesu rasta. Za to vrijeme broj narudžbi se povećao više od 4 puta. Sada već isporučujemo više od 17 narudžbi dnevno u 000 grada i planiramo još više proširiti geografiju - u prvoj polovini 62. godine očekuje se da usluga bude pokrenuta širom Rusije. Kako bismo se izborili sa rastućim opterećenjem, uzimajući u obzir naše već pune čunjeve, razvili smo 2020 osnovnih principa za rad u uslovima stalnog rasta:

  1. Upravljanje incidentima. Napravili smo tablu u Jira, gde se svaki incident reflektuje u obliku karte. Ovo će pomoći u stvarnom određivanju prioriteta i izvršavanju zadataka povezanih s incidentom. Uostalom, u suštini, nije strašno pogriješiti, ali je strašno pogriješiti dva puta u istoj prilici. Za one slučajeve kada se incidenti ponavljaju prije nego što se uzrok otkloni, upute za akciju trebale bi biti spremne, jer je u vrijeme velikog opterećenja važno reagirati munjevitom brzinom.
  2. Monitoring potrebno za sve elemente infrastrukture bez izuzetka. Zahvaljujući njemu, uspjeli smo predvidjeti rast opterećenja i pravilno odabrati „uska grla“ za eliminaciju prioriteta. Najvjerovatnije će se pod velikim opterećenjem sve ono o čemu niste razmišljali pokvariti ili početi usporavati. Stoga je najbolje kreirati nova upozorenja odmah nakon pojave prvih incidenata kako biste ih pratili i predvidjeli.
  3. Ispravna upozorenja jednostavno neophodno kada se opterećenje naglo poveća. Prvo, moraju prijaviti šta je tačno pokvareno. Drugo, ne bi trebalo biti mnogo upozorenja, jer obilje nekritičnih upozorenja dovodi do potpunog ignorisanja svih upozorenja.
  4. Prijave moraju biti bez državljanstva. Uvjereni smo da ne bi trebalo biti izuzetaka od ovog pravila. Potrebna nam je potpuna nezavisnost od runtime okruženja. Da biste to učinili, možete pohraniti zajedničke podatke u bazu podataka ili, na primjer, direktno u S3. Još bolje, pridržavajte se pravila. https://12factor.net. Tokom naglog povećanja vremena, jednostavno ne postoji način za optimizaciju koda i moraćete da se nosite sa opterećenjem direktnim povećanjem računarskih resursa i horizontalnim skaliranjem.
  5. Kvote i performanse eksternih usluga. Uz brzi rast, problem može nastati ne samo u vašoj infrastrukturi, već iu eksternoj usluzi. Najneugodnije je kada se to ne dogodi zbog neuspjeha, već zbog dostizanja kvota ili ograničenja. Dakle, eksterne usluge bi trebale biti skalirane jednako dobro kao i vi. 
  6. Odvojeni procesi i redovi. Ovo mnogo pomaže kada postoji blokada na jednom od gateway-a. Ne bismo nailazili na kašnjenja u prijenosu podataka da puni redovi slanja SMS-a ne ometaju razmjenu obavještenja između informacionih sistema. I bilo bi lakše povećati broj radnika kada bi radili odvojeno.
  7. Finansijska stvarnost. Kada dođe do eksplozivnog rasta tokova podataka, nema vremena za razmišljanje o tarifama i pretplatama. Ali morate ih zapamtiti, posebno ako ste mala kompanija. Vlasnik bilo kojeg API-ja, kao i vaš hosting provajder, može snositi veliki račun. Dakle, morate pažljivo pročitati ugovore.

zaključak

Ne bez gubitaka, ali ovu fazu smo preživjeli i danas se trudimo da se pridržavamo svih zatečenih principa, a svaka mašina ima mogućnost lakog povećanja x4 performansi kako bi se izborila sa nekim neočekivanim događajima. 

U sljedećim objavama podijelit ćemo naše iskustvo u istraživanju degradacije performansi u Apache Solr-u, a također ćemo govoriti o optimizaciji upita i kako interakcija sa Federalnom poreskom službom pomaže kompaniji da uštedi novac. Pretplatite se na naš blog kako ništa ne biste propustili, a u komentarima nam recite jeste li imali sličnih problema tokom rasta prometa.

Kako smo preživjeli povećanje opterećenja x10 na daljinu i koje smo zaključke izvukli

Samo registrovani korisnici mogu učestvovati u anketi. Prijavite semolim.

Da li ste ikada doživjeli usporavanje/smanjenje usluge zbog naglog povećanja opterećenja zbog:

  • 55,6%Nemogućnost brzog dodavanja računarskih resursa10

  • 16,7%Infrastrukturna ograničenja hosting provajdera3

  • 33,3%Ograničenja API-ja trećih strana6

  • 27,8%Povrede principa apatrida njihove prijave5

  • 88,9%Neoptimalni kod vlastitih usluga16

Glasalo je 18 korisnika. Uzdržano je bilo 6 korisnika.

izvor: www.habr.com

Dodajte komentar