SRE: veiktspējas analÄ«ze. Konfigurācijas metode, izmantojot vienkārÅ”u tÄ«mekļa serveri Go

Veiktspējas analÄ«ze un regulÄ“Å”ana ir spēcÄ«gs rÄ«ks, lai pārbaudÄ«tu klientu veiktspējas atbilstÄ«bu.

Veiktspējas analÄ«zi var izmantot, lai pārbaudÄ«tu programmas vājās vietas, pielietojot zinātnisku pieeju regulÄ“Å”anas eksperimentu testÄ“Å”anai. Å ajā rakstā ir definēta vispārÄ«ga pieeja veiktspējas analÄ«zei un regulÄ“Å”anai, kā piemēru izmantojot Go tÄ«mekļa serveri.

Go ir Ä«paÅ”i labs Å”eit, jo tam ir profilÄ“Å”anas rÄ«ki pprof standarta bibliotēkā.

SRE: veiktspējas analÄ«ze. Konfigurācijas metode, izmantojot vienkārÅ”u tÄ«mekļa serveri Go

stratēģija

Izveidosim kopsavilkuma sarakstu mÅ«su strukturālajai analÄ«zei. Mēs mēģināsim izmantot dažus datus, lai pieņemtu lēmumus, nevis veiktu izmaiņas, pamatojoties uz intuÄ«ciju vai minējumiem. Lai to izdarÄ«tu, mēs darÄ«sim Ŕādi:

  • Nosakām optimizācijas robežas (prasÄ«bas);
  • Mēs aprēķinām transakciju slodzi sistēmai;
  • Veicam testu (veidojam datus);
  • Mēs novērojam;
  • Mēs analizējam ā€“ vai visas prasÄ«bas ir izpildÄ«tas?
  • Mēs to uzstādām zinātniski, izvirzām hipotēzi;
  • Mēs veicam eksperimentu, lai pārbaudÄ«tu Å”o hipotēzi.

SRE: veiktspējas analÄ«ze. Konfigurācijas metode, izmantojot vienkārÅ”u tÄ«mekļa serveri Go

VienkārŔa HTTP servera arhitektūra

Å im rakstam mēs izmantosim nelielu HTTP serveri Golangā. Visu Ŕī raksta kodu var atrast Å”eit.

Analizējamā lietojumprogramma ir HTTP serveris, kas aptauj Postgresql katram pieprasÄ«jumam. Turklāt ir Prometheus, node_exporter un Grafana lietojumprogrammu un sistēmas metrikas apkopoÅ”anai un parādÄ«Å”anai.

SRE: veiktspējas analÄ«ze. Konfigurācijas metode, izmantojot vienkārÅ”u tÄ«mekļa serveri Go

VienkārÅ”oÅ”anas labad mēs uzskatām, ka horizontālajai mērogoÅ”anai (un aprēķinu vienkārÅ”oÅ”anai) katrs pakalpojums un datubāze tiek izvietoti kopā:

SRE: veiktspējas analÄ«ze. Konfigurācijas metode, izmantojot vienkārÅ”u tÄ«mekļa serveri Go

MērÄ·u definÄ“Å”ana

Å ajā posmā mēs izlemjam par mērÄ·i. Ko mēs cenÅ”amies analizēt? Kā mēs zinām, kad ir pienācis laiks beigt? Å ajā rakstā mēs iedomāsimies, ka mums ir klienti un mÅ«su pakalpojums apstrādās 10 000 pieprasÄ«jumu sekundē.

Š’ Google SRE grāmata Atlases un modelÄ“Å”anas metodes ir detalizēti apskatÄ«tas. DarÄ«sim to paÅ”u un veidosim modeļus:

  • Latentums: 99% pieprasÄ«jumu jāpabeidz mazāk nekā 60 ms;
  • Izmaksas: pakalpojumam ir jāpatērē minimālā naudas summa, kas, mÅ«suprāt, ir saprātÄ«gi iespējama. Lai to izdarÄ«tu, mēs palielinām caurlaidspēju;
  • Jaudas plānoÅ”ana: ir jāsaprot un jādokumentē, cik lietojumprogrammas gadÄ«jumu bÅ«s jāpalaiž, ieskaitot vispārējo mērogoÅ”anas funkcionalitāti un cik gadÄ«jumu bÅ«s nepiecieÅ”ams, lai izpildÄ«tu sākotnējās slodzes un nodroÅ”ināŔanas prasÄ«bas. atlaiÅ”ana n+1.

Latentam var bÅ«t nepiecieÅ”ama optimizācija papildus analÄ«zei, taču nepārprotami ir jāanalizē caurlaidspēja. Izmantojot SRE SLO procesu, aizkaves pieprasÄ«jums nāk no klienta vai uzņēmuma, ko pārstāv produkta Ä«paÅ”nieks. Un mÅ«su serviss Å”o pienākumu izpildÄ«s jau no paÅ”a sākuma bez jebkādiem iestatÄ«jumiem!

Testa vides iestatīŔana

Ar testa vides palīdzību mēs varēsim novietot izmērītu slodzi uz mūsu sistēmu. Analīzei tiks ģenerēti dati par tīmekļa pakalpojuma veiktspēju.

Darījumu slodze

Å Ä« vide izmanto veÄ£etēt lai izveidotu pielāgotu HTTP pieprasÄ«juma ātrumu lÄ«dz apturÄ“Å”anai:

$ make load-test LOAD_TEST_RATE=50
echo "POST http://localhost:8080" | vegeta attack -body tests/fixtures/age_no_match.json -rate=50 -duration=0 | tee results.bin | vegeta report

NovēroÅ”ana

DarÄ«juma slodze tiks piemērota izpildlaikā. Papildus lietojumprogrammu (pieprasÄ«jumu skaits, atbildes latentums) un operētājsistēmas (atmiņa, centrālais procesors, IOPS) metrikai tiks veikta lietojumprogrammu profilÄ“Å”ana, lai saprastu, kur tai ir problēmas un kā tiek patērēts CPU laiks.

ProfilēŔana

ProfilÄ“Å”ana ir mērÄ«jumu veids, kas ļauj redzēt, kur paiet CPU laiks, kad lietojumprogramma darbojas. Tas ļauj precÄ«zi noteikt, kur un cik daudz procesora laika tiek tērēts:

SRE: veiktspējas analÄ«ze. Konfigurācijas metode, izmantojot vienkārÅ”u tÄ«mekļa serveri Go

Å os datus var izmantot analÄ«zes laikā, lai gÅ«tu ieskatu par izŔķērdēto CPU laiku un nevajadzÄ«go darbu. Go (pprof) var Ä£enerēt profilus un vizualizēt tos kā liesmu diagrammas, izmantojot standarta rÄ«ku komplektu. Par to lietoÅ”anu un iestatÄ«Å”anas rokasgrāmatu es runāŔu vēlāk rakstā.

Izpilde, novēroÅ”ana, analÄ«ze.

Veiksim eksperimentu. Uzstāsim, vērosim un analizēsim, lÄ«dz bÅ«sim apmierināti ar sniegumu. Izvēlēsimies patvaļīgi zemu slodzes vērtÄ«bu, lai to lietotu, lai iegÅ«tu pirmo novērojumu rezultātus. Katrā nākamajā solÄ« mēs palielināsim slodzi ar noteiktu mērogoÅ”anas koeficientu, kas izvēlēts ar dažām izmaiņām. Katra slodzes pārbaudes darbÄ«ba tiek veikta ar pielāgotu pieprasÄ«jumu skaitu: make load-test LOAD_TEST_RATE=X.

50 pieprasījumi sekundē

SRE: veiktspējas analÄ«ze. Konfigurācijas metode, izmantojot vienkārÅ”u tÄ«mekļa serveri Go

Pievērsiet uzmanÄ«bu diviem augŔējiem grafikiem. AugŔējā kreisajā pusē ir redzams, ka mÅ«su lietojumprogramma apstrādā 50 pieprasÄ«jumus sekundē (tā domā), un augŔējā labajā stÅ«rÄ« ir redzams katra pieprasÄ«juma ilgums. Abi parametri palÄ«dz mums apskatÄ«t un analizēt, vai esam mÅ«su veiktspējas robežās vai nē. Sarkanā lÄ«nija diagrammā HTTP pieprasÄ«juma latentums parāda SLO pie 60 ms. LÄ«nija parāda, ka esam krietni zem maksimālā atbildes laika.

Apskatīsim izmaksu pusi:

10000 50 pieprasījumu sekundē / 200 pieprasījumi uz serveri = 1 serveri + XNUMX

Mēs vēl varam uzlabot Å”o rādÄ«tāju.

500 pieprasījumi sekundē

Interesantākas lietas sāk notikt, kad slodze sasniedz 500 pieprasījumus sekundē:

SRE: veiktspējas analÄ«ze. Konfigurācijas metode, izmantojot vienkārÅ”u tÄ«mekļa serveri Go

Atkal augŔējā kreisajā diagrammā var redzēt, ka lietojumprogramma reÄ£istrē normālu slodzi. Ja tas tā nav, serverÄ«, kurā darbojas lietojumprogramma, ir problēma. Atbildes latentuma diagramma atrodas augŔējā labajā stÅ«rÄ«, un tas parāda, ka 500 pieprasÄ«jumi sekundē izraisÄ«ja atbildes aizkavi 25ā€“40 ms. 99. procentile joprojām lieliski iekļaujas iepriekÅ” izvēlētajā 60 ms SLO.

Izmaksu ziņā:

10000 500 pieprasījumu sekundē / 20 pieprasījumi uz serveri = 1 serveri + XNUMX

Visu vēl var uzlabot.

1000 pieprasījumi sekundē

SRE: veiktspējas analÄ«ze. Konfigurācijas metode, izmantojot vienkārÅ”u tÄ«mekļa serveri Go

Lieliska palaiÅ”ana! Lietojumprogramma rāda, ka tā apstrādāja 1000 pieprasÄ«jumus sekundē, taču latentuma limits tika pārkāpts ar SLO. To var redzēt p99 rindā augŔējā labajā diagrammā. Neskatoties uz to, ka p100 lÄ«nija ir daudz augstāka, faktiskā aizkave ir lielāka par maksimālo 60 ms. Iedziļināsimies profilÄ“Å”anā, lai uzzinātu, ko lietojumprogramma faktiski dara.

ProfilēŔana

ProfilÄ“Å”anai mēs iestatām slodzi uz 1000 pieprasÄ«jumiem sekundē, pēc tam izmantojiet pprof lai iegÅ«tu datus, lai uzzinātu, kur lietojumprogramma pavada CPU laiku. To var izdarÄ«t, aktivizējot HTTP galapunktu pprof, un pēc tam zem slodzes saglabājiet rezultātus, izmantojot curl:

$ curl http://localhost:8080/debug/pprof/profile?seconds=29 > cpu.1000_reqs_sec_no_optimizations.prof

Rezultātus var parādīt Ŕādi:

$ go tool pprof -http=:12345 cpu.1000_reqs_sec_no_optimizations.prof

SRE: veiktspējas analÄ«ze. Konfigurācijas metode, izmantojot vienkārÅ”u tÄ«mekļa serveri Go

Diagramma parāda, kur un cik daudz lietojumprogramma tērē CPU laiku. No apraksta no Brendans Gregs:

X ass ir kaudzes profila populācija, kas sakārtota alfabētiskā secÄ«bā (tas nav laiks), Y ass parāda kaudzes dziļumu, skaitot no nulles [augŔā]. Katrs taisnstÅ«ris ir kaudzes rāmis. Jo platāks rāmis, jo biežāk tas atrodas skursteņos. Tas, kas atrodas augÅ”pusē, darbojas ar centrālo procesoru, un tas, kas atrodas zemāk, ir pakārtotie elementi. Krāsas parasti neko nenozÄ«mē, bet vienkārÅ”i tiek izvēlētas nejauÅ”i, lai atŔķirtu rāmjus.

Analīze - hipotēze

NoregulÄ“Å”anai mēs koncentrēsimies uz mēģinājumu atrast izŔķērdētu CPU laiku. Mēs meklēsim lielākos bezjēdzÄ«go tēriņu avotus un noņemsim tos. Tā kā profilÄ“Å”ana ļoti precÄ«zi atklāj, kur tieÅ”i lietojumprogramma tērē savu procesora laiku, iespējams, tas bÅ«s jādara vairākas reizes, kā arÄ« bÅ«s jāmaina lietojumprogrammas pirmkods, atkārtoti jāveic testi un jāpārliecinās, ka veiktspēja tuvojas mērÄ·im.

Sekojot Brendana Grega ieteikumiem, mēs lasÄ«sim diagrammu no augÅ”as uz leju. Katrā rindā tiek parādÄ«ts kaudzes rāmis (funkcijas izsaukums). Pirmā rinda ir ieejas punkts programmā, visu pārējo zvanu vecāks (citiem vārdiem sakot, visiem pārējiem zvaniem tas bÅ«s savā kaudzē). Nākamā rinda jau ir atŔķirÄ«ga:

SRE: veiktspējas analÄ«ze. Konfigurācijas metode, izmantojot vienkārÅ”u tÄ«mekļa serveri Go

Ja grafikā novietojat kursoru virs funkcijas nosaukuma, tiks parādÄ«ts kopējais laiks, kad tā atradās kaudzē atkļūdoÅ”anas laikā. HTTPServe funkcija bija tur 65% laika, citas izpildlaika funkcijas runtime.mcall, mstart Šø gc, aizņēma atlikuÅ”o laiku. Jautrs fakts: 5% no kopējā laika tiek tērēti DNS vaicājumiem:

SRE: veiktspējas analÄ«ze. Konfigurācijas metode, izmantojot vienkārÅ”u tÄ«mekļa serveri Go

Programmas meklētās adreses pieder Postgresql. KlikŔķiniet uz FindByAge:

SRE: veiktspējas analÄ«ze. Konfigurācijas metode, izmantojot vienkārÅ”u tÄ«mekļa serveri Go

Interesanti, ka programma parāda, ka principā ir trÄ«s galvenie avoti, kas pievieno aizkavÄ“Å”anos: savienojumu atvērÅ”ana un aizvērÅ”ana, datu pieprasÄ«Å”ana un pieslēgÅ”ana datubāzei. Grafikā redzams, ka DNS pieprasÄ«jumi, savienojumu atvērÅ”ana un aizvērÅ”ana aizņem aptuveni 13% no kopējā izpildes laika.

Hipotēze: Atkārtoti izmantojot savienojumus, izmantojot pÅ«lÄ“Å”anu, jāsamazina viena HTTP pieprasÄ«juma laiks, nodroÅ”inot lielāku caurlaidspēju un mazāku latentumu.

Lietojumprogrammas iestatīŔana - eksperiments

Mēs atjauninām avota kodu, cenÅ”amies noņemt savienojumu ar Postgresql katram pieprasÄ«jumam. Pirmā iespēja ir izmantot savienojuma baseins lietojumprogrammas lÄ«menÄ«. Å ajā eksperimentā mēs iestatÄ«sim to savienojumu apvienoÅ”ana, izmantojot SQL draiveri for go:

db, err := sql.Open("postgres", dbConnectionString)
db.SetMaxOpenConns(8)

if err != nil {
   return nil, err
}

Izpilde, novēroÅ”ana, analÄ«ze

Pēc testa restartÄ“Å”anas ar 1000 pieprasÄ«jumiem sekundē ir skaidrs, ka p99 latentuma lÄ«menis ir atgriezies normālā stāvoklÄ« ar SLO 60 ms!

Kādas ir izmaksas?

10000 1000 pieprasījumu sekundē / 10 pieprasījumi uz serveri = 1 serveri + XNUMX

Darīsim to vēl labāk!

2000 pieprasījumi sekundē

SRE: veiktspējas analÄ«ze. Konfigurācijas metode, izmantojot vienkārÅ”u tÄ«mekļa serveri Go

Slodzes dubultoÅ”ana parāda to paÅ”u, augŔējā kreisajā grafikā redzams, ka aplikācijai izdodas apstrādāt 2000 pieprasÄ«jumu sekundē, p100 ir zemāks par 60ms, p99 apmierina SLO.

Izmaksu ziņā:

10000 2000 pieprasījumu sekundē / 5 pieprasījumi uz serveri = 1 serveri + XNUMX

3000 pieprasījumi sekundē

SRE: veiktspējas analÄ«ze. Konfigurācijas metode, izmantojot vienkārÅ”u tÄ«mekļa serveri Go

Å eit lietojumprogramma var apstrādāt 3000 pieprasÄ«jumus ar p99 latentumu, kas mazāks par 60 ms. SLO netiek pārkāpts, un izmaksas tiek pieņemtas Ŕādi:

10000 3000 pieprasījumu sekundē / uz 4 1 pieprasījumiem uz serveri = XNUMX serveri + XNUMX (autors ir noapaļojis, apm. tulkotājs)

Mēģināsim veikt citu analīzes kārtu.

Analīze - hipotēze

Mēs apkopojam un parādām lietojumprogrammas atkļūdoÅ”anas rezultātus ar 3000 pieprasÄ«jumiem sekundē:

SRE: veiktspējas analÄ«ze. Konfigurācijas metode, izmantojot vienkārÅ”u tÄ«mekļa serveri Go

Joprojām 6% laika tiek veltÄ«ti savienojumu izveidei. PÅ«la iestatÄ«Å”ana ir uzlabojusi veiktspēju, taču joprojām varat redzēt, ka lietojumprogramma turpina darbu, lai izveidotu jaunus savienojumus ar datu bāzi.

Hipotēze: Savienojumi, neskatoties uz baseina klātbÅ«tni, joprojām tiek pārtraukti un iztÄ«rÄ«ti, tāpēc lietojumprogrammai tie ir jāatiestata. Neapstiprināto savienojumu skaita iestatÄ«Å”ana uz pÅ«la lielumu palÄ«dzēs samazināt latentumu, samazinot laiku, ko lietojumprogramma pavada savienojuma izveidei..

Lietojumprogrammas iestatīŔana - eksperiments

Mēģina instalēt MaxIdleConns vienāds ar baseina izmēru (arÄ« aprakstÄ«ts Å”eit):

db, err := sql.Open("postgres", dbConnectionString)
db.SetMaxOpenConns(8)
db.SetMaxIdleConns(8)
if err != nil {
   return nil, err
}

Izpilde, novēroÅ”ana, analÄ«ze

3000 pieprasījumi sekundē

SRE: veiktspējas analÄ«ze. Konfigurācijas metode, izmantojot vienkārÅ”u tÄ«mekļa serveri Go

p99 ir mazāks par 60 ms ar ievērojami mazāku p100!

SRE: veiktspējas analÄ«ze. Konfigurācijas metode, izmantojot vienkārÅ”u tÄ«mekļa serveri Go

Pārbaudot liesmas grafiku, redzams, ka savienojums vairs nav manāms! PārbaudÄ«sim sÄ«kāk pg(*conn).query ā€” mēs arÄ« nepamanām, ka Å”eit tiek izveidots savienojums.

SRE: veiktspējas analÄ«ze. Konfigurācijas metode, izmantojot vienkārÅ”u tÄ«mekļa serveri Go

Secinājums

Veiktspējas analÄ«ze ir ļoti svarÄ«ga, lai saprastu, ka tiek izpildÄ«tas klientu vēlmes un nefunkcionālās prasÄ«bas. AnalÄ«ze, salÄ«dzinot novērojumus ar klientu vēlmēm, var palÄ«dzēt noteikt, kas ir pieņemams un kas nav. Go nodroÅ”ina jaudÄ«gus standarta bibliotēkā iebÅ«vētus rÄ«kus, kas padara analÄ«zi vienkārÅ”u un pieejamu.

Avots: www.habr.com

Pievieno komentāru