SRE: Nānā Hana Hana. Ke ala hoʻonohonoho hoʻohana ʻana i kahi kikowaena pūnaewele maʻalahi ma Go

ʻO ka nānā ʻana a me ke kani ʻana he mea hana ikaika no ka hōʻoia ʻana i ka hoʻokō ʻana i ka hana no nā mea kūʻai aku.

Hiki ke hoʻohana ʻia ka loiloi hana no ka nānā ʻana i nā bottlenecks i kahi papahana ma o ka hoʻohana ʻana i kahi ala ʻepekema i ka hoʻāʻo ʻana i nā hoʻokolohua hoʻolohe. Hōʻike kēia ʻatikala i kahi ala maʻamau i ka nānā ʻana i ka hana a me ke kani ʻana, me ka hoʻohana ʻana i kahi kikowaena pūnaewele Go ma ke ʻano he laʻana.

Maikaʻi loa ʻo Go ma ʻaneʻi no ka mea he mau mea hana profiling pprof i ka waihona maʻamau.

SRE: Nānā Hana Hana. Ke ala hoʻonohonoho hoʻohana ʻana i kahi kikowaena pūnaewele maʻalahi ma Go

Kūlana

E hana mākou i kahi papa inoa hōʻuluʻulu no kā mākou hoʻolālā hoʻolālā. E ho'āʻo mākou e hoʻohana i kekahi ʻikepili no ka hoʻoholo ʻana ma mua o ka hoʻololi ʻana ma muli o ka intuition a i ʻole guesswork. No ka hana ʻana i kēia, e hana mākou i kēia:

  • Hoʻoholo mākou i nā palena optimization (koi);
  • E helu mākou i ka ukana kālepa no ka ʻōnaehana;
  • Hana mākou i ka ho'āʻo (hana i ka ʻikepili);
  • Nānā mākou;
  • Nānā mākou - ua hoʻokō ʻia nā koi āpau?
  • Hoʻokumu mākou i ka ʻepekema, hana i kahi kuhiakau;
  • Hana mākou i kahi hoʻokolohua e hoʻāʻo ai i kēia kuhiakau.

SRE: Nānā Hana Hana. Ke ala hoʻonohonoho hoʻohana ʻana i kahi kikowaena pūnaewele maʻalahi ma Go

Hoʻolālā Kūkaʻikaʻi HTTP maʻalahi

No kēia ʻatikala e hoʻohana mākou i kahi kikowaena HTTP liʻiliʻi ma Golang. Hiki ke loaʻa nā code a pau mai kēia ʻatikala maanei.

ʻO ka noi e nānā ʻia nei he kikowaena HTTP e koho ana iā Postgresql no kēlā me kēia noi. Eia kekahi, aia ʻo Prometheus, node_exporter a me Grafana no ka hōʻiliʻili ʻana a me ka hōʻike ʻana i ka noi a me nā metric ʻōnaehana.

SRE: Nānā Hana Hana. Ke ala hoʻonohonoho hoʻohana ʻana i kahi kikowaena pūnaewele maʻalahi ma Go

No ka maʻalahi, manaʻo mākou no ka hoʻonui ʻia ʻana (a me ka hoʻomaʻamaʻa ʻana i ka helu ʻana) ua hoʻonohonoho pū ʻia kēlā me kēia lawelawe a me ka waihona.

SRE: Nānā Hana Hana. Ke ala hoʻonohonoho hoʻohana ʻana i kahi kikowaena pūnaewele maʻalahi ma Go

Ka wehewehe ʻana i nā pahuhopu

Ma kēia ʻanuʻu, hoʻoholo mākou i ka pahuhopu. He aha kā mākou e hoʻāʻo nei e kālailai? Pehea mākou e ʻike ai i ka wā e pau ai? Ma kēia ʻatikala, e noʻonoʻo mākou he mau mea kūʻai aku mākou a e hana kā mākou lawelawe i nā noi 10 i kēlā me kēia kekona.

В Buke SRE Google Kūkākūkā ʻia nā ʻano o ke koho ʻana a me ke ʻano hoʻohālike. E hana like kāua a kūkulu i nā hiʻohiʻona:

  • Latency: 99% o nā noi e hoʻopau ʻia ma lalo o 60ms;
  • Kumukūʻai: Pono ka lawelawe e hoʻopau i ka liʻiliʻi o ke kālā a mākou e manaʻo ai he hiki ke kūpono. No ka hana ʻana i kēia, hoʻonui mākou i ka throughput;
  • Ka hoʻolālā ʻana i ka mana: Pono ka ʻike a me ka palapala ʻana i ka nui o nā manawa o ka noi e pono e holo, me ka hana hoʻonui holoʻokoʻa, a me ka nui o nā manawa e pono ai e hoʻokō i nā koi mua a me ka hoʻolako ʻana. hoʻonui n+1.

Pono paha ka Latency i ka hoʻonui ʻana i ka nānā ʻana, akā pono e nānā pono ʻia ka throughput. I ka hoʻohana ʻana i ke kaʻina hana SRE SLO, hiki mai ka noi lohi mai ka mea kūʻai aku a ʻoihana paha, i hōʻike ʻia e ka mea nona ka huahana. A e hoʻokō kā mākou lawelawe i kēia kuleana mai ka hoʻomaka ʻana me ka ʻole o nā hoʻonohonoho!

Hoʻonohonoho i kahi hoʻāʻo

Me ke kōkua o kahi hoʻāʻo ʻana, hiki iā mākou ke kau i kahi haʻahaʻa ana ma kā mākou ʻōnaehana. No ka nānā ʻana, e hana ʻia nā ʻikepili i ka hana o ka lawelawe pūnaewele.

Ka ukana ukana

Ke hoʻohana nei kēia kaiapuni Vegeta e hana i ka helu noi HTTP maʻamau a pau:

$ 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

Nānā

E hoʻohana ʻia ka ukana hana i ka wā holo. Ma waho aʻe o ka noi (ka helu o nā noi, ka latency pane) a me nā ʻōnaehana hana (memo, CPU, IOPS), e holo ʻia ka noiʻi noiʻi e hoʻomaopopo i kahi e pilikia ai a pehea e pau ai ka manawa CPU.

Ka hoʻopaʻa inoa

ʻO ka Profiling kahi ʻano ana e hiki ai iā ʻoe ke ʻike i kahi e hele ai ka manawa CPU i ka wā e holo ana kahi noi. Hāʻawi ia iā ʻoe e hoʻoholo pololei i kahi a me ka nui o ka manawa o ka processor:

SRE: Nānā Hana Hana. Ke ala hoʻonohonoho hoʻohana ʻana i kahi kikowaena pūnaewele maʻalahi ma Go

Hiki ke hoʻohana ʻia kēia ʻikepili i ka wā o ka nānā ʻana no ka loaʻa ʻana o ka ʻike i ka manawa CPU pau ʻole a me nā hana pono ʻole e hana ʻia. Hiki iā Go (pprof) ke hoʻopuka i nā kiʻi a nānā iā lākou e like me nā kiʻi lapalapa me ka hoʻohana ʻana i nā mea hana maʻamau. E kamaʻilio wau e pili ana i kā lākou hoʻohana a me ke alakaʻi hoʻonohonoho ma hope o ka ʻatikala.

Ka hoʻokō ʻana, ka nānā ʻana, ka nānā ʻana.

E hana kāua i hoʻokolohua. E hana mākou, nānā a hoʻopaʻa ʻia a māʻona mākou i ka hana. E koho mākou i kahi waiwai haʻahaʻa haʻahaʻa e hoʻohana ai i loaʻa nā hopena o nā ʻike mua. Ma kēlā me kēia kaʻina aʻe e hoʻonui mākou i ka ukana me kekahi kumu scaling, koho ʻia me kekahi ʻano hoʻololi. Hana ʻia kēlā me kēia hoʻāʻo hoʻouka me ka helu o nā noi i hoʻololi ʻia: make load-test LOAD_TEST_RATE=X.

50 noi i kekona

SRE: Nānā Hana Hana. Ke ala hoʻonohonoho hoʻohana ʻana i kahi kikowaena pūnaewele maʻalahi ma Go

E nānā pono i nā kiʻi ʻelua ma luna. Hōʻike ka ʻaoʻao hema i ke kaʻina hana o kā mākou noi noi 50 i kēlā me kēia kekona (manaʻo ia) a ʻo ka ʻaoʻao ʻākau i luna e hōʻike ana i ka lōʻihi o kēlā me kēia noi. Kōkua nā ʻāpana ʻelua iā mākou e nānā a nānā inā aia mākou i loko o kā mākou palena hana a ʻaʻole paha. Laina ʻulaʻula ma ka pakuhi HTTP Noi Latency hōʻike iā SLO ma 60ms. Hōʻike ka laina i lalo o kā mākou manawa pane kiʻekiʻe.

E nānā kākou i ka ʻaoʻao kumu kūʻai:

10000 noi no kekona / 50 noi no ke kikowaena = 200 mau kikowaena + 1

Hiki iā mākou ke hoʻomaikaʻi i kēia helu.

500 noi i kekona

Hoʻomaka nā mea hoihoi hou aʻe i ka loaʻa ʻana o ka ukana i 500 noi i kēlā me kēia kekona:

SRE: Nānā Hana Hana. Ke ala hoʻonohonoho hoʻohana ʻana i kahi kikowaena pūnaewele maʻalahi ma Go

Eia hou, ma ka ʻaoʻao hema hema hiki iā ʻoe ke ʻike e hoʻopaʻa ana ka noi i ka ukana maʻamau. Inā ʻaʻole kēia ka hihia, aia kahi pilikia ma ke kikowaena kahi e holo ai ka noi. Aia ka pakuhi latency pane ma ka ʻaoʻao ʻākau, e hōʻike ana he 500 noi i kēlā me kēia kekona i hopena i ka lohi pane o 25-40ms. Ua kūpono ka 99th percentile i ka 60ms SLO i koho ʻia ma luna.

E pili ana i ke kumukūʻai:

10000 noi no kekona / 500 noi no ke kikowaena = 20 mau kikowaena + 1

Hiki ke hoʻomaikaʻi ʻia nā mea a pau.

1000 noi i kekona

SRE: Nānā Hana Hana. Ke ala hoʻonohonoho hoʻohana ʻana i kahi kikowaena pūnaewele maʻalahi ma Go

Hoʻomaka maikaʻi! Hōʻike ka palapala noi ua hana ʻo ia i nā noi 1000 i kēlā me kēia kekona, akā ua uhaki ʻia ka palena latency e ka SLO. Hiki ke ʻike ʻia kēia ma ka laina p99 ma ka pakuhi ʻākau luna. ʻOiai ʻoi aku ka kiʻekiʻe o ka laina p100, ʻoi aku ka kiʻekiʻe o nā lohi maoli ma mua o ka nui o 60ms. E luʻu kākou i ka profiling e ʻike i ka hana maoli o ka noi.

Ka hoʻopaʻa inoa

No ka profiling, hoʻonoho mākou i ka ukana i 1000 noi i kēlā me kēia kekona, a laila hoʻohana pprof e hopu i ka ʻikepili e ʻike ai i kahi e hoʻohana ai ka noi i ka manawa CPU. Hiki ke hana i kēia ma ka ho'ā ʻana i ka hopena HTTP pprof, a laila, ma lalo o ka hoʻouka ʻana, mālama i nā hopena me ka curl:

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

Hiki ke hōʻike ʻia nā hopena e like me kēia:

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

SRE: Nānā Hana Hana. Ke ala hoʻonohonoho hoʻohana ʻana i kahi kikowaena pūnaewele maʻalahi ma Go

Hōʻike ka pakuhi i hea a me ka nui o ka noi e hoʻolilo i ka manawa CPU. Mai ka wehewehe mai Brendan Gregg:

ʻO ke koʻi X ka heluna kanaka hōʻike pūʻulu, i hoʻokaʻawale ʻia ma ke ʻano pīʻāpā (ʻaʻole kēia ka manawa), hōʻike ka axis Y i ka hohonu o ka waihona, e helu ana mai ka ʻole ma [luna]. ʻO kēlā me kēia ʻāpana ʻāpana he papa hoʻopaʻa. ʻOi aku ka laulā o ke kiʻi, ʻoi aku ka nui o ka loaʻa ʻana i nā pūʻulu. ʻO ka mea ma luna e holo ana ma ka CPU, a ʻo ka mea ma lalo nā mea keiki. ʻAʻohe manaʻo o nā kala, akā koho wale ʻia e hoʻokaʻawale i nā kiʻi.

Kānāwai - kuhiakau

No ke kani ʻana, e kālele mākou i ka hoʻāʻo ʻana e ʻimi i ka manawa CPU pau ʻole. E ʻimi mākou i nā kumu waiwai nui loa o ka hoʻolilo ʻole a hoʻopau iā lākou. ʻAe, ke hōʻike pololei nei ka profiling i kahi e hoʻohana ai ka noi i kāna manawa kaʻina hana, pono paha ʻoe e hana i nā manawa he nui, a pono ʻoe e hoʻololi i ke code kumu noi, hoʻihoʻi hou i nā hoʻokolohua a ʻike e pili ana ka hana i ka pahuhopu.

Ma hope o nā ʻōlelo aʻo a Brendan Gregg, e heluhelu mākou i ka pakuhi mai luna a lalo. Hōʻike kēlā me kēia laina i kahi kiʻi hoʻopaʻa (call function). ʻO ka laina mua ka helu komo i loko o ka papahana, ka makua o nā kelepona ʻē aʻe (ma nā huaʻōlelo ʻē aʻe, e loaʻa nā kelepona ʻē aʻe a pau ma kā lākou waihona). He ʻokoʻa ka laina aʻe:

SRE: Nānā Hana Hana. Ke ala hoʻonohonoho hoʻohana ʻana i kahi kikowaena pūnaewele maʻalahi ma Go

Inā hoʻolele ʻoe i ka cursor ma luna o ka inoa o kahi hana ma ka pakuhi, e hōʻike ʻia ka manawa holoʻokoʻa ma luna o ka hoʻopaʻa ʻana i ka wā debugging. Aia ka hana HTTPServe ma laila 65% o ka manawa, nā hana runtime ʻē aʻe runtime.mcall, mstart и gc, lawe i ke koena o ka manawa. ʻO ka ʻoiaʻiʻo leʻaleʻa: 5% o ka manawa holoʻokoʻa i hoʻopau ʻia ma nā nīnau DNS:

SRE: Nānā Hana Hana. Ke ala hoʻonohonoho hoʻohana ʻana i kahi kikowaena pūnaewele maʻalahi ma Go

ʻO nā ʻōlelo a ka papahana e ʻimi nei no Postgresql. Kaomi ma FindByAge:

SRE: Nānā Hana Hana. Ke ala hoʻonohonoho hoʻohana ʻana i kahi kikowaena pūnaewele maʻalahi ma Go

ʻO ka mea hoihoi, hōʻike ka papahana, ma ke kumu, ʻekolu mau kumu nui e hoʻohui i nā lohi: wehe a pani ʻana i nā pilina, noi ʻana i ka ʻikepili, a me ka hoʻopili ʻana i ka waihona. Hōʻike ka pakuhi i nā noi DNS, ka wehe ʻana a me ka pani ʻana i nā pilina ma kahi o 13% o ka manawa hoʻokō.

Kuhiakau: ʻO ka hoʻohana hou ʻana i nā pilina e hoʻohana ana i ka pooling pono e hōʻemi i ka manawa o kahi noi HTTP hoʻokahi, e ʻae ana i ka throughput kiʻekiʻe a me ka latency haʻahaʻa.

Hoʻonohonoho i ka noi - hoʻokolohua

Hoʻopau mākou i ke code kumu, e hoʻāʻo e wehe i ka pilina me Postgresql no kēlā me kēia noi. ʻO ka koho mua e hoʻohana loko pili ma ka pae noi. Ma kēia hoʻokolohua mākou e hoonoho kakou hui pū ʻana me ka hoʻohana ʻana i ka mea hoʻokele sql no ka hele:

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

if err != nil {
   return nil, err
}

Ka hoʻokō ʻana, ka nānā ʻana, ka nānā ʻana

Ma hope o ka hoʻomaka hou ʻana i ka hoʻāʻo me 1000 mau noi i kēlā me kēia kekona, ua maopopo ua hoʻi nā pae latency o p99 i ka maʻamau me kahi SLO o 60ms!

He aha ke kumukūʻai?

10000 noi no kekona / 1000 noi no ke kikowaena = 10 mau kikowaena + 1

E hana maikaʻi kākou!

2000 noi i kekona

SRE: Nānā Hana Hana. Ke ala hoʻonohonoho hoʻohana ʻana i kahi kikowaena pūnaewele maʻalahi ma Go

ʻO ka pāpālua i ka ukana e hōʻike ana i ka mea like, hōʻike ka pakuhi hema i ka hoʻoponopono ʻana i nā noi 2000 i kēlā me kēia kekona, p100 ka haʻahaʻa ma mua o 60ms, p99 e hoʻokō i ka SLO.

E pili ana i ke kumukūʻai:

10000 noi no kekona / 2000 noi no ke kikowaena = 5 mau kikowaena + 1

3000 noi i kekona

SRE: Nānā Hana Hana. Ke ala hoʻonohonoho hoʻohana ʻana i kahi kikowaena pūnaewele maʻalahi ma Go

Maanei hiki i ka palapala noi ke hana i nā noi 3000 me kahi latency p99 ma lalo o 60ms. ʻAʻole i uhaki ʻia ka SLO, a ua ʻae ʻia ke kumukūʻai penei:

10000 noi no kekona / no 3000 noi no ke kikowaena = 4 mau kikowaena + 1 (ua hōʻuluʻulu ka mea kākau, kokoke. mea unuhi)

E ho'āʻo kāua i kekahi pōʻaiapuni o ka hoʻopaʻa ʻana.

Kānāwai - kuhiakau

Hōʻiliʻili mākou a hōʻike i nā hopena o ka hoʻopau ʻana i ka noi ma 3000 noi i kēlā me kēia kekona:

SRE: Nānā Hana Hana. Ke ala hoʻonohonoho hoʻohana ʻana i kahi kikowaena pūnaewele maʻalahi ma Go

Hoʻohana ʻia ʻo 6% o ka manawa ma ka hoʻokumu ʻana i nā pilina. ʻO ka hoʻonohonoho ʻana i ka wai i hoʻomaikaʻi i ka hana, akā hiki iā ʻoe ke ʻike i ka hoʻomau ʻana o ka noi i ka hana ʻana i nā pilina hou i ka waihona.

Kuhiakau: Hoʻokuʻu ʻia a hoʻomaʻemaʻe ʻia nā pilina, ʻoiai me ka loaʻa ʻana o kahi loko wai, no laila pono ka noi e hoʻonohonoho hou iā lākou. ʻO ka hoʻonohonoho ʻana i ka helu o nā pili e kali nei i ka nui o ka loko wai e kōkua i ka latency ma ka hoʻemi ʻana i ka manawa a ka noi e hoʻolilo ai i kahi pilina..

Hoʻonohonoho i ka noi - hoʻokolohua

Ke ho'āʻo nei e hoʻokomo MaxIdleConns e like me ka nui o ka loko (i wehewehe pū ʻia maanei):

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

Ka hoʻokō ʻana, ka nānā ʻana, ka nānā ʻana

3000 noi i kekona

SRE: Nānā Hana Hana. Ke ala hoʻonohonoho hoʻohana ʻana i kahi kikowaena pūnaewele maʻalahi ma Go

He emi ka p99 ma mua o 60ms me ka emi loa o ka p100!

SRE: Nānā Hana Hana. Ke ala hoʻonohonoho hoʻohana ʻana i kahi kikowaena pūnaewele maʻalahi ma Go

ʻO ka nānā ʻana i ka pakuhi lapalapa e hōʻike ana ʻaʻole ʻike hou ʻia ka pilina! E nānā hou aku kākou pg(*conn).query - ʻaʻole mākou ʻike i ka hoʻokumu ʻia ʻana o ka pilina ma aneʻi.

SRE: Nānā Hana Hana. Ke ala hoʻonohonoho hoʻohana ʻana i kahi kikowaena pūnaewele maʻalahi ma Go

hopena

He mea koʻikoʻi ka loiloi hana no ka hoʻomaopopo ʻana i ka hoʻokō ʻia ʻana o nā manaʻolana o ka mea kūʻai aku a me nā pono hana ʻole. ʻO ka ʻikepili ma ka hoʻohālikelike ʻana i nā ʻike me nā manaʻo o ka mea kūʻai aku hiki ke kōkua i ka hoʻoholo ʻana i ka mea i ʻae ʻia a me ka mea ʻole. Hāʻawi ʻo Go i nā mea hana ikaika i kūkulu ʻia i loko o ka waihona maʻamau e maʻalahi a maʻalahi hoʻi ka nānā ʻana.

Source: www.habr.com

Pākuʻi i ka manaʻo hoʻopuka