SRE: Uchambuzi wa Utendaji. Mbinu ya usanidi kwa kutumia seva rahisi ya wavuti katika Go

Uchambuzi wa utendakazi na urekebishaji ni zana yenye nguvu ya kuthibitisha utiifu wa utendakazi kwa wateja.

Uchambuzi wa utendakazi unaweza kutumika kuangalia vikwazo katika mpango kwa kutumia mbinu ya kisayansi ya kujaribu majaribio ya kurekebisha. Makala haya yanafafanua mbinu ya jumla ya uchanganuzi wa utendakazi na urekebishaji, kwa kutumia Go webserver kama mfano.

Go ni nzuri sana hapa kwa sababu ina zana za kuorodhesha pprof katika maktaba ya kawaida.

SRE: Uchambuzi wa Utendaji. Mbinu ya usanidi kwa kutumia seva rahisi ya wavuti katika Go

Mkakati

Wacha tutengeneze orodha ya muhtasari wa uchambuzi wetu wa muundo. Tutajaribu kutumia baadhi ya data kufanya maamuzi badala ya kufanya mabadiliko kulingana na angavu au kubahatisha. Ili kufanya hivyo, tutafanya hivi:

  • Tunaamua mipaka ya uboreshaji (mahitaji);
  • Tunahesabu mzigo wa shughuli kwa mfumo;
  • Tunafanya mtihani (kuunda data);
  • Tunazingatia;
  • Tunachambua - je, mahitaji yote yamefikiwa?
  • Tunaiweka kisayansi, fanya hypothesis;
  • Tunafanya jaribio ili kujaribu dhana hii.

SRE: Uchambuzi wa Utendaji. Mbinu ya usanidi kwa kutumia seva rahisi ya wavuti katika Go

Usanifu Rahisi wa Seva ya HTTP

Kwa makala hii tutatumia seva ndogo ya HTTP huko Golang. Nambari zote kutoka kwa nakala hii zinaweza kupatikana hapa.

Programu inayochanganuliwa ni seva ya HTTP ambayo huchagua Postgresql kwa kila ombi. Zaidi ya hayo, kuna Prometheus, node_exporter na Grafana kwa ajili ya kukusanya na kuonyesha vipimo vya programu na mfumo.

SRE: Uchambuzi wa Utendaji. Mbinu ya usanidi kwa kutumia seva rahisi ya wavuti katika Go

Ili kurahisisha, tunazingatia kwamba kwa kuongeza mlalo (na kurahisisha mahesabu) kila huduma na hifadhidata huwekwa pamoja:

SRE: Uchambuzi wa Utendaji. Mbinu ya usanidi kwa kutumia seva rahisi ya wavuti katika Go

Kufafanua malengo

Katika hatua hii, tunaamua juu ya lengo. Tunajaribu kuchambua nini? Je, tunajuaje wakati wa kumaliza umefika? Katika makala haya, tutafikiria kuwa tuna wateja na kwamba huduma yetu itashughulikia maombi 10 kwa sekunde.

Π’ Kitabu cha Google SRE Mbinu za uteuzi na modeli zinajadiliwa kwa undani. Wacha tufanye vivyo hivyo na tujenge mifano:

  • Muda wa kusubiri: 99% ya maombi yanapaswa kukamilika kwa chini ya 60ms;
  • Gharama: Huduma inapaswa kutumia kiwango cha chini zaidi cha pesa ambacho tunafikiri kinawezekana. Kwa kufanya hivyo, sisi kuongeza throughput;
  • Upangaji wa uwezo: Inahitaji kuelewa na kuweka kumbukumbu ni matukio ngapi ya maombi yatahitaji kuendeshwa, ikiwa ni pamoja na utendaji wa jumla wa kuongeza ukubwa, na ni matukio ngapi yatahitajika ili kukidhi mahitaji ya awali ya upakiaji na utoaji. redundancy n+1.

Ucheleweshaji unaweza kuhitaji uboreshaji pamoja na uchanganuzi, lakini matokeo yanahitaji kuchanganuliwa. Unapotumia mchakato wa SRE SLO, ombi la kucheleweshwa hutoka kwa mteja au biashara, inayowakilishwa na mmiliki wa bidhaa. Na huduma yetu itatimiza wajibu huu tangu mwanzo bila mipangilio yoyote!

Kuweka mazingira ya mtihani

Kwa msaada wa mazingira ya mtihani, tutaweza kuweka mzigo uliopimwa kwenye mfumo wetu. Kwa uchambuzi, data juu ya utendaji wa huduma ya wavuti itatolewa.

Mzigo wa shughuli

Mazingira haya hutumia Mboga kuunda kiwango maalum cha ombi la HTTP hadi kusimamishwa:

$ 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

Uangalizi

Mzigo wa muamala utatumika wakati wa utekelezaji. Kando na vipimo vya maombi (idadi ya maombi, muda wa kusubiri majibu) na mfumo wa uendeshaji (kumbukumbu, CPU, IOPS), uwekaji wasifu wa programu utaendeshwa ili kuelewa ni wapi kuna matatizo na jinsi muda wa CPU unavyotumika.

Uwekaji wasifu

Uwekaji wasifu ni aina ya kipimo inayokuruhusu kuona wakati wa CPU unapoenda wakati programu inaendeshwa. Inakuruhusu kuamua ni wapi na muda gani wa processor unatumika:

SRE: Uchambuzi wa Utendaji. Mbinu ya usanidi kwa kutumia seva rahisi ya wavuti katika Go

Data hii inaweza kutumika wakati wa uchanganuzi kupata maarifa kuhusu muda wa CPU uliopotea na kazi isiyo ya lazima inayofanywa. Go (pprof) inaweza kutoa wasifu na kuwaona kama grafu za moto kwa kutumia seti ya kawaida ya zana. Nitazungumza juu ya utumiaji wao na mwongozo wa usanidi baadaye katika kifungu hicho.

Utekelezaji, uchunguzi, uchambuzi.

Hebu tufanye jaribio. Tutafanya, tutazingatia na kuchambua hadi tutakaporidhika na utendaji. Wacha tuchague thamani ya chini ya mzigo ili kuitumia ili kupata matokeo ya uchunguzi wa kwanza. Katika kila hatua inayofuata tutaongeza mzigo kwa sababu fulani ya kuongeza, iliyochaguliwa na tofauti fulani. Kila jaribio la upakiaji hufanywa na idadi ya maombi yaliyorekebishwa: make load-test LOAD_TEST_RATE=X.

Maombi 50 kwa sekunde

SRE: Uchambuzi wa Utendaji. Mbinu ya usanidi kwa kutumia seva rahisi ya wavuti katika Go

Makini na grafu mbili za juu. Sehemu ya juu kushoto inaonyesha kuwa programu yetu huchakata maombi 50 kwa sekunde (inafikiriwa) na sehemu ya juu kulia inaonyesha muda wa kila ombi. Vigezo vyote viwili hutusaidia kuangalia na kuchanganua ikiwa tuko ndani ya mipaka yetu ya utendakazi au la. Mstari mwekundu kwenye grafu Kuchelewa kwa Ombi la HTTP inaonyesha SLO kwa 60ms. Mstari unaonyesha kuwa tuko chini ya muda wetu wa juu zaidi wa kujibu.

Wacha tuangalie upande wa gharama:

Maombi 10000 kwa sekunde / kwa maombi 50 kwa seva = seva 200 + 1

Bado tunaweza kuboresha takwimu hii.

Maombi 500 kwa sekunde

Mambo ya kufurahisha zaidi huanza kutokea wakati mzigo unafikia maombi 500 kwa sekunde:

SRE: Uchambuzi wa Utendaji. Mbinu ya usanidi kwa kutumia seva rahisi ya wavuti katika Go

Tena, kwenye grafu ya juu kushoto unaweza kuona kwamba programu inarekodi mzigo wa kawaida. Ikiwa sivyo, kuna tatizo kwenye seva ambayo programu inaendesha. Grafu ya latency ya majibu iko upande wa juu kulia, ikionyesha kuwa maombi 500 kwa sekunde yalisababisha kucheleweshwa kwa majibu kwa 25-40ms. Asilimia ya 99 bado inafaa katika SLO ya milisekunde 60 iliyochaguliwa hapo juu.

Kwa upande wa gharama:

Maombi 10000 kwa sekunde / kwa maombi 500 kwa seva = seva 20 + 1

Kila kitu bado kinaweza kuboreshwa.

Maombi 1000 kwa sekunde

SRE: Uchambuzi wa Utendaji. Mbinu ya usanidi kwa kutumia seva rahisi ya wavuti katika Go

Uzinduzi mzuri! Maombi yanaonyesha kuwa ilishughulikia maombi 1000 kwa sekunde, lakini kikomo cha kusubiri kilikiukwa na SLO. Hii inaweza kuonekana kwenye mstari p99 kwenye grafu ya juu kulia. Licha ya ukweli kwamba mstari wa p100 ni wa juu zaidi, ucheleweshaji halisi ni wa juu kuliko upeo wa 60ms. Wacha tuzame kwenye uwekaji wasifu ili kujua programu hufanya nini haswa.

Uwekaji wasifu

Kwa wasifu, tunaweka mzigo kwa maombi 1000 kwa sekunde, kisha utumie pprof kunasa data ili kujua ni wapi programu inatumia wakati wa CPU. Hii inaweza kufanywa kwa kuwezesha mwisho wa HTTP pprof, na kisha, chini ya mzigo, hifadhi matokeo kwa kutumia curl:

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

Matokeo yanaweza kuonyeshwa kama hii:

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

SRE: Uchambuzi wa Utendaji. Mbinu ya usanidi kwa kutumia seva rahisi ya wavuti katika Go

Grafu inaonyesha wapi na ni kiasi gani programu hutumia wakati wa CPU. Kutoka kwa maelezo kutoka Brendan Gregg:

Mhimili wa X ni idadi ya wasifu wa rafu, iliyopangwa kwa alfabeti (huu si wakati), mhimili wa Y unaonyesha kina cha rafu, ikihesabu kutoka sifuri hadi [juu]. Kila mstatili ni sura ya rafu. Kadiri sura inavyokuwa pana, ndivyo inavyokuwa mara nyingi zaidi kwenye safu. Kilicho juu huendesha CPU, na kile kilicho chini ni vipengele vya mtoto. Rangi kawaida haimaanishi chochote, lakini huchaguliwa kwa nasibu ili kutofautisha fremu.

Uchambuzi - hypothesis

Kwa kurekebisha, tutazingatia kujaribu kutafuta wakati wa CPU uliopotea. Tutatafuta vyanzo vikubwa vya matumizi yasiyo na maana na kuviondoa. Kweli, kwa kuzingatia kwamba uwekaji wasifu unaonyesha kwa usahihi sana ambapo programu hutumia wakati wake wa kichakataji, unaweza kulazimika kuifanya mara kadhaa, na utahitaji pia kubadilisha msimbo wa chanzo cha programu, fanya majaribio tena na uone kuwa utendaji unakaribia lengo.

Kufuatia mapendekezo ya Brendan Gregg, tutasoma chati kutoka juu hadi chini. Kila mstari unaonyesha fremu ya rafu (simu ya kazi). Mstari wa kwanza ni sehemu ya kuingia kwenye programu, mzazi wa simu nyingine zote (kwa maneno mengine, simu nyingine zote zitakuwa nazo kwenye stack zao). Mstari unaofuata tayari ni tofauti:

SRE: Uchambuzi wa Utendaji. Mbinu ya usanidi kwa kutumia seva rahisi ya wavuti katika Go

Ukipeperusha kishale juu ya jina la chaguo za kukokotoa kwenye grafu, jumla ya muda uliokuwa kwenye rafu wakati wa utatuzi utaonyeshwa. Chaguo za kukokotoa za HTTPServe zilikuwepo 65% ya wakati huo, vitendaji vingine vya wakati wa utekelezaji runtime.mcall, mstart ΠΈ gc, ilichukua muda uliobaki. Ukweli wa kufurahisha: 5% ya muda wote hutumika kwa hoja za DNS:

SRE: Uchambuzi wa Utendaji. Mbinu ya usanidi kwa kutumia seva rahisi ya wavuti katika Go

Anwani ambazo programu inatafuta ni za Postgresql. Bonyeza FindByAge:

SRE: Uchambuzi wa Utendaji. Mbinu ya usanidi kwa kutumia seva rahisi ya wavuti katika Go

Inashangaza, mpango unaonyesha kwamba, kimsingi, kuna vyanzo vitatu vinavyoongeza ucheleweshaji: kufungua na kufunga miunganisho, kuomba data, na kuunganisha kwenye hifadhidata. Grafu inaonyesha kwamba maombi ya DNS, kufungua na kufunga miunganisho huchukua takriban 13% ya muda wote wa utekelezaji.

Nadharia: Kutumia tena miunganisho kwa kutumia kuunganisha kunapaswa kupunguza muda wa ombi moja la HTTP, kuruhusu upitishaji wa juu zaidi na ucheleweshaji mdogo..

Kuanzisha programu - jaribio

Tunasasisha msimbo wa chanzo, jaribu kuondoa muunganisho kwa Postgresql kwa kila ombi. Chaguo la kwanza ni kutumia bwawa la uunganisho katika ngazi ya maombi. Katika jaribio hili sisi tuiweke uunganisho wa uunganisho kwa kutumia dereva wa sql kwenda:

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

if err != nil {
   return nil, err
}

Utekelezaji, uchunguzi, uchambuzi

Baada ya kuanzisha upya jaribio kwa maombi 1000 kwa sekunde, ni wazi kwamba viwango vya latency vya p99 vimerejea kawaida na SLO ya 60ms!

Ni gharama gani?

Maombi 10000 kwa sekunde / kwa maombi 1000 kwa seva = seva 10 + 1

Hebu tuifanye vizuri zaidi!

Maombi 2000 kwa sekunde

SRE: Uchambuzi wa Utendaji. Mbinu ya usanidi kwa kutumia seva rahisi ya wavuti katika Go

Kuongeza mzigo mara mbili kunaonyesha kitu kimoja, grafu ya juu kushoto inaonyesha kuwa programu inaweza kushughulikia maombi 2000 kwa sekunde, p100 ni ya chini kuliko 60ms, p99 inakidhi SLO.

Kwa upande wa gharama:

Maombi 10000 kwa sekunde / kwa maombi 2000 kwa seva = seva 5 + 1

Maombi 3000 kwa sekunde

SRE: Uchambuzi wa Utendaji. Mbinu ya usanidi kwa kutumia seva rahisi ya wavuti katika Go

Hapa programu inaweza kuchakata maombi 3000 kwa muda wa kusubiri wa p99 wa chini ya 60ms. SLO haijakiukwa, na gharama inakubaliwa kama ifuatavyo:

Maombi 10000 kwa sekunde / kwa maombi 3000 kwa kila seva = seva 4 + 1 (mwandishi amekusanya, takriban. mfasiri)

Hebu tujaribu awamu nyingine ya uchambuzi.

Uchambuzi - hypothesis

Tunakusanya na kuonyesha matokeo ya utatuzi wa programu kwa maombi 3000 kwa sekunde:

SRE: Uchambuzi wa Utendaji. Mbinu ya usanidi kwa kutumia seva rahisi ya wavuti katika Go

Bado 6% ya muda hutumika kuanzisha miunganisho. Kusanidi bwawa kumeboresha utendakazi, lakini bado unaweza kuona kwamba programu inaendelea kufanya kazi katika kuunda miunganisho mipya kwenye hifadhidata.

Nadharia: Viunganisho, licha ya kuwepo kwa bwawa, bado imeshuka na kusafishwa, hivyo programu inahitaji kuweka upya. Kuweka idadi ya miunganisho inayosubiri kwenye saizi ya bwawa kunafaa kusaidia kwa muda wa kusubiri kwa kupunguza muda ambao programu hutumia kuunda muunganisho..

Kuanzisha programu - jaribio

Inajaribu kusakinisha MaxIdleConns sawa na saizi ya bwawa (pia imeelezewa hapa):

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

Utekelezaji, uchunguzi, uchambuzi

Maombi 3000 kwa sekunde

SRE: Uchambuzi wa Utendaji. Mbinu ya usanidi kwa kutumia seva rahisi ya wavuti katika Go

p99 ni chini ya 60ms na p100 chini sana!

SRE: Uchambuzi wa Utendaji. Mbinu ya usanidi kwa kutumia seva rahisi ya wavuti katika Go

Kuangalia grafu ya mwali kunaonyesha kuwa muunganisho hauonekani tena! Hebu tuangalie kwa undani zaidi pg(*conn).query - pia hatuoni muunganisho unaoanzishwa hapa.

SRE: Uchambuzi wa Utendaji. Mbinu ya usanidi kwa kutumia seva rahisi ya wavuti katika Go

Hitimisho

Uchambuzi wa utendakazi ni muhimu ili kuelewa kwamba matarajio ya wateja na mahitaji yasiyo ya utendaji yanatimizwa. Uchambuzi kwa kulinganisha uchunguzi na matarajio ya mteja unaweza kusaidia kubainisha ni nini kinachokubalika na kisichokubalika. Go hutoa zana madhubuti zilizojumuishwa katika maktaba ya kawaida ambayo hufanya uchanganuzi kuwa rahisi na kufikiwa.

Chanzo: mapenzi.com

Kuongeza maoni