ZiÅojumÄ ir izklÄstÄ«tas dažas pieejas, kas ļauj uzraudzÄ«t SQL vaicÄjumu veiktspÄju, ja to dienÄ ir miljoniem, un ir simtiem uzraudzÄ«tu PostgreSQL serveru.
KÄdi tehniskie risinÄjumi ļauj efektÄ«vi apstrÄdÄt Å”Ädu informÄcijas apjomu un kÄ tas atvieglo vienkÄrÅ”a izstrÄdÄtÄja dzÄ«vi?
Kuram tas interesÄ? specifisku problÄmu analÄ«ze un dažÄdas optimizÄcijas metodes SQL vaicÄjumi un tipisku DBA problÄmu risinÄÅ”ana programmÄ PostgreSQL ā arÄ« jÅ«s varat izlasi rakstu sÄriju par Å”o tÄmu.
Mani sauc Kirils Borovikovs, es pÄrstÄvu UzÅÄmums Tensor. KonkrÄti, es specializÄjos darbÄ ar datu bÄzÄm mÅ«su uzÅÄmumÄ.
Å odien es jums pastÄstÄ«Å”u, kÄ mÄs optimizÄjam vaicÄjumus, kad jums nav ājÄizŔķirā viena vaicÄjuma veiktspÄja, bet gan jÄatrisina problÄma masveidÄ. Kad ir miljoniem pieprasÄ«jumu, un jums tie ir jÄatrod pieejas risinÄjumam Ŕī lielÄ problÄma.
KopumÄ Tensor miljoniem mÅ«su klientu ir VLSI ir mÅ«su lietojumprogramma: korporatÄ«vais sociÄlais tÄ«kls, risinÄjumi video komunikÄcijai, iekÅ”Äjai un ÄrÄjai dokumentu apritei, uzskaites sistÄmas grÄmatvedÄ«bai un noliktavÄm,... RespektÄ«vi, tÄds āmegakombainsā integrÄtai biznesa vadÄ«bai, kurÄ ir vairÄk nekÄ 100 dažÄdu iekÅ”Äjie projekti.
Lai nodroÅ”inÄtu, ka tie visi strÄdÄ un attÄ«stÄs normÄli, mums ir 10 attÄ«stÄ«bas centri visÄ valstÄ«, un tajos ir vÄl vairÄk 1000 izstrÄdÄtÄju.
MÄs strÄdÄjam ar PostgreSQL kopÅ” 2008. gada un esam uzkrÄjuÅ”i lielu daudzumu no tÄ, ko apstrÄdÄjam - klientu datus, statistiskos, analÄ«tiskos, datus no ÄrÄjÄm informÄcijas sistÄmÄm - vairÄk nekÄ 400 TB. RažoÅ”anÄ vien ir aptuveni 250 serveru, un kopumÄ ir aptuveni 1000 datu bÄzes serveru, kurus mÄs uzraugÄm.
SQL ir deklaratÄ«va valoda. JÅ«s aprakstÄt nevis "kÄ" kaut kam vajadzÄtu darboties, bet gan "ko" vÄlaties sasniegt. DBVS labÄk zina, kÄ izveidot JOIN ā kÄ savienot tabulas, kÄdus nosacÄ«jumus uzlikt, kas tiks rÄdÄ«ts, kas nÄ...
Dažas DBVS pieÅem ieteikumus: āNÄ, savienojiet Ŕīs divas tabulas tÄdÄ un tÄdÄ rindÄā, taÄu PostgreSQL to nevar izdarÄ«t. TÄ ir vadoÅ”o izstrÄdÄtÄju apzinÄta nostÄja: āMÄs labprÄtÄk pabeigsim vaicÄjumu optimizÄtÄju, nevis ļautu izstrÄdÄtÄjiem izmantot kÄdus mÄjienus.ā
Bet, neskatoties uz to, ka PostgreSQL neļauj āÄrÄjaiā sevi kontrolÄt, tas lieliski atļauj redzÄt, kas notiek viÅÄkad izpildÄt vaicÄjumu un kur ar to rodas problÄmas.
Ar kÄdÄm klasiskÄm problÄmÄm parasti nÄk [uz DBA] izstrÄdÄtÄjs? āÅ eit mÄs izpildÄ«jÄm lÅ«gumu, un pie mums viss notiek lÄni, viss karÄjas, kaut kas notiek... Kaut kÄdas nepatikÅ”anas!ā
Iemesli gandrÄ«z vienmÄr ir vienÄdi:
neefektÄ«vs vaicÄjuma algoritms
IzstrÄdÄtÄjs: "Tagad es viÅam dodu 10 tabulas SQL, izmantojot JOIN..." - un sagaida, ka viÅa nosacÄ«jumi brÄ«numainÄ kÄrtÄ tiks efektÄ«vi "atsaistÄ«ti" un viÅÅ” visu Ätri iegÅ«s. Bet brÄ«numi nenotiek, un jebkura sistÄma ar tÄdu mainÄ«gumu (10 tabulas vienÄ FROM) vienmÄr dod kaut kÄdu kļūdu. [raksts]
novecojusi statistika
Å is punkts ir ļoti bÅ«tisks tieÅ”i PostgreSQL, kad jÅ«s "ielej" lielu datu kopu uz serveri, veicat pieprasÄ«jumu, un tas "sekskanizÄ" jÅ«su planÅ”etdatoru. Jo vakar tajÄ bija 10 ieraksti un Å”odien 10 miljoni, bet PostgreSQL to vÄl nezina, un mums tas par to jÄpastÄsta. [raksts]
"pieslÄgt" resursiem
JÅ«s esat instalÄjis lielu un smagi noslogotu datubÄzi vÄjÄ serverÄ«, kuram nav pietiekami daudz diska, atmiÅas vai procesora veiktspÄjas. Un tas arÄ« viss... Kaut kur ir snieguma griesti, virs kuriem vairs nevar uzlÄkt.
bloÄ·ÄÅ”ana
Tas ir sarežģīts punkts, taÄu tie visvairÄk attiecas uz dažÄdiem modificÄjoÅ”iem vaicÄjumiem (INSERT, UPDATE, DELETE) - Ŕī ir atseviŔķa liela tÄma.
PlÄna iegÅ«Å”ana
...Un par visu pÄrÄjo mÄs vajag plÄnu! Mums jÄredz, kas notiek servera iekÅ”ienÄ.
PostgreSQL vaicÄjuma izpildes plÄns ir vaicÄjuma izpildes algoritma koks teksta attÄlojumÄ. TieÅ”i algoritms plÄnotÄja veiktÄs analÄ«zes rezultÄtÄ tika atzÄ«ts par visefektÄ«vÄko.
Katrs koka mezgls ir darbÄ«ba: datu izgÅ«Å”ana no tabulas vai indeksa, bitkartes izveidoÅ”ana, divu tabulu savienoÅ”ana, atlases savienoÅ”ana, krustoÅ”anÄs vai izslÄgÅ”ana. VaicÄjuma izpilde ietver staigÄÅ”anu pa Ŕī koka mezgliem.
Lai iegÅ«tu vaicÄjuma plÄnu, vienkÄrÅ”Äkais veids ir izpildÄ«t paziÅojumu EXPLAIN. Lai iegÅ«tu visus reÄlos atribÅ«tus, tas ir, lai faktiski izpildÄ«tu vaicÄjumu bÄzÄ - EXPLAIN (ANALYZE, BUFFERS) SELECT ....
SliktÄ daļa: palaižot to, tas notiek "Å”eit un tagad", tÄpÄc tas ir piemÄrots tikai vietÄjai atkļūdoÅ”anai. Ja izmantojat ļoti noslogotu serveri, kurÄ notiek spÄcÄ«ga datu izmaiÅu plÅ«sma, un redzat: āAk! Å eit mums ir lÄna izpildexia pieprasÄ«jums." Pirms pusstundas, pirms stundas ā kamÄr jÅ«s darbojÄties un saÅÄmÄt Å”o pieprasÄ«jumu no žurnÄliem, nogÄdÄjot to atpakaļ uz serveri, tika mainÄ«ta visa jÅ«su datu kopa un statistika. Palaižat to, lai atkļūdotu ā un tas darbojas Ätri! Un tu nevari saprast, kÄpÄc, kÄpÄc tas bija lÄnÄm.
Lai saprastu, kas notika tieÅ”i tajÄ brÄ«dÄ«, kad serverÄ« tika izpildÄ«ts pieprasÄ«jums, rakstÄ«ja gudri cilvÄki auto_explain modulis. Tas ir pieejams gandrÄ«z visos visizplatÄ«tÄkajos PostgreSQL izplatÄ«jumos, un to var vienkÄrÅ”i aktivizÄt konfigurÄcijas failÄ.
Ja tas saprot, ka kÄds pieprasÄ«jums tiek izpildÄ«ts ilgÄk par jÅ«su norÄdÄ«to ierobežojumu, tas notiek Ŕī pieprasÄ«juma plÄna āmomentuzÅÄmumuā un ieraksta tos kopÄ Å¾urnÄlÄ.
Tagad it kÄ viss kÄrtÄ«bÄ, ejam uz baļķi un tur redzam... [teksts kÄju lupatiÅa]. Bet mÄs par to nevaram pateikt neko citu, kÄ vien to, ka tas ir lielisks plÄns, jo tÄ izpilde prasÄ«ja 11 ms.
Å Ä·iet, ka viss ir kÄrtÄ«bÄ, bet nekas nav skaidrs, kas patiesÄ«bÄ notika. IzÅemot vispÄrÄjo laiku, mÄs neko Ä«sti neredzam. Jo skatÄ«ties uz Å”Ädu vienkÄrÅ”a teksta ājÄruā parasti nav vizuÄli.
Bet pat tad, ja tas nav acÄ«mredzams, pat ja tas ir neÄrti, pastÄv daudz bÅ«tiskÄkas problÄmas:
Mezgls norÄda visa apakÅ”koka resursu summa zem viÅa. Tas nozÄ«mÄ, ka jÅ«s nevarat vienkÄrÅ”i uzzinÄt, cik daudz laika tika pavadÄ«ts Å”ai konkrÄtajai indeksa skenÄÅ”anai, ja zem tÄ ir kÄds ligzdots stÄvoklis. Mums ir dinamiski jÄskatÄs, lai redzÄtu, vai iekÅ”Ä ir ābÄrniā un nosacÄ«juma mainÄ«gie, CTE ā un tas viss āmÅ«su prÄtÄā jÄatÅem.
Otrais punkts: uz mezgla norÄdÄ«tais laiks ir viena mezgla izpildes laiks. Ja Å”is mezgls tika izpildÄ«ts, piemÄram, vairÄkas reizes veicot cilpu caur tabulas ierakstiem, tad plÄnÄ palielinÄs cilpu ā Ŕī mezgla ciklu ā skaits. Bet pats atomu izpildes laiks plÄna ziÅÄ paliek nemainÄ«gs. Tas ir, lai saprastu, cik ilgi Å”is mezgls tika veikts kopumÄ, jums ir jÄreizina viena lieta ar otru - atkal "galvÄ".
Å ÄdÄs situÄcijÄs saprotiet: "KurÅ” ir vÄjÄkais posms?" gandrÄ«z neiespÄjami. TÄpÄc pat paÅ”i izstrÄdÄtÄji to raksta ārokasgrÄmatÄā. "Izpratne par plÄnu ir mÄksla, kas jÄapgÅ«st, jÄpiedzÄ«vo...".
TaÄu mums ir 1000 izstrÄdÄtÄju, un jÅ«s nevarat nodot Å”o pieredzi katram no viÅiem. Es, tu, viÅÅ” zinu, bet kÄds tur vairs nezina. VarbÅ«t viÅÅ” iemÄcÄ«sies, vai varbÅ«t ne, bet viÅam tagad vajag strÄdÄt - un kur viÅÅ” iegÅ«tu Å”o pieredzi?
PlÄna vizualizÄcija
TÄpÄc mÄs sapratÄm, ka, lai tiktu galÄ ar Ŕīm problÄmÄm, mums ir nepiecieÅ”ams laba plÄna vizualizÄcija. [raksts]
Vispirms mÄs izgÄjÄm āpa tirguā - paskatÄ«simies internetÄ, lai redzÄtu, kas vispÄr pastÄv.
Bet izrÄdÄ«jÄs, ka ir ļoti maz salÄ«dzinoÅ”i ādzÄ«vuā risinÄjumu, kas vairÄk vai mazÄk attÄ«stÄs - burtiski tikai viens: paskaidrojiet.depesz.com autors Huberts LubaÄevskis. Ievadot plÄna teksta attÄlojumu laukÄ āplÅ«smaā, tiek parÄdÄ«ta tabula ar parsÄtajiem datiem:
paÅ”a mezgla apstrÄdes laiks
kopÄjais laiks visam apakÅ”kokam
statistiski paredzamo izgūto ierakstu skaits
pats mezgla Ä·ermenis
Å im pakalpojumam ir arÄ« iespÄja koplietot saiÅ”u arhÄ«vu. JÅ«s iemetÄt tur savu plÄnu un teicÄt: "Ei, Vasja, Å”eit ir saite, tur kaut kas nav kÄrtÄ«bÄ."
TaÄu ir arÄ« nelielas problÄmas.
PirmkÄrt, milzÄ«gs daudzums ācopy-pasteā. JÅ«s paÅemat baļķa gabalu, iebÄžat to tur, un atkal un atkal.
OtrkÄrt, nav nolasÄ«to datu apjoma analÄ«zes ā tie paÅ”i buferi, kas izvada EXPLAIN (ANALYZE, BUFFERS), mÄs to Å”eit neredzam. ViÅÅ” vienkÄrÅ”i nezina, kÄ tos izjaukt, saprast un strÄdÄt ar tiem. Kad lasÄt daudz datu un saprotat, ka, iespÄjams, nepareizi sadalÄt disku un atmiÅas keÅ”atmiÅu, Ŕī informÄcija ir ļoti svarÄ«ga.
TreÅ”ais negatÄ«vais punkts ir Ŕī projekta ļoti vÄjÄ attÄ«stÄ«ba. SaistÄ«bas ir ļoti mazas, ir labi, ja reizi seÅ”os mÄneÅ”os, un kods ir Perl.
Bet tas viss ir ādziesmu vÄrdiā, mÄs ar to varÄtu kaut kÄ sadzÄ«vot, taÄu ir viena lieta, kas mÅ«s ļoti atturÄja no Ŕī pakalpojuma. TÄs ir kļūdas kopÄjÄs tabulas izteiksmes (CTE) un dažÄdu dinamisku mezglu, piemÄram, InitPlan/SubPlan, analÄ«zÄ.
Ja ticat Å”im attÄlam, katra atseviŔķa mezgla kopÄjais izpildes laiks ir lielÄks par visa pieprasÄ«juma kopÄjo izpildes laiku. Tas ir vienkÄrÅ”i - Ŕī CTE Ä£enerÄÅ”anas laiks netika atÅemts no CTE Scan mezgla. TÄpÄc mÄs vairs nezinÄm pareizo atbildi uz to, cik ilgi bija nepiecieÅ”ama pati CTE skenÄÅ”ana.
Tad sapratÄm, ka laiks rakstÄ«t savÄjo - urÄ! Katrs izstrÄdÄtÄjs saka: "Tagad mÄs rakstÄ«sim paÅ”i, tas bÅ«s ļoti vienkÄrÅ”i!"
MÄs izmantojÄm tÄ«mekļa pakalpojumiem raksturÄ«gu kaudzi: kodolu, kura pamatÄ ir Node.js + Express, izmantojÄm Bootstrap un D3.js, lai iegÅ«tu skaistas diagrammas. Un mÅ«su cerÄ«bas bija pilnÄ«bÄ pamatotas - pirmo prototipu saÅÄmÄm 2 nedÄļu laikÄ:
pielÄgota plÄna parsÄtÄjs
Tas ir, tagad mÄs varam parsÄt jebkuru plÄnu no tiem, ko Ä£enerÄja PostgreSQL.
buferu sadalÄ«juma analÄ«ze - kur datu lapas tiek lasÄ«tas no atmiÅas, kur no lokÄlÄs keÅ”atmiÅas, kur no diska
ieguva skaidrību
Lai to visu āneraktuā žurnÄlÄ, bet bildÄ uzreiz redzÄtu āvÄjÄko posmuā.
Mums ir kaut kas lÄ«dzÄ«gs Å”im ar iekļautu sintakses izcelÅ”anu. Bet parasti mÅ«su izstrÄdÄtÄji vairs nestrÄdÄ ar pilnÄ«gu plÄna attÄlojumu, bet gan ar Ä«sÄku. Galu galÄ mÄs jau esam parsÄjuÅ”i visus skaitļus un izmetuÅ”i tos pa kreisi un pa labi, un pa vidu atstÄjÄm tikai pirmo rindiÅu, kas tas par mezglu: CTE Scan, CTE paaudze vai Seq Scan pÄc kÄdas zÄ«mes.
Å is ir saÄ«sinÄtais attÄlojums, ko mÄs saucam plÄna veidne.
Kas vÄl bÅ«tu Ärti? BÅ«tu Ärti redzÄt, kÄda daļa no mÅ«su kopÄjÄ laika ir atvÄlÄta kuram mezglam - un vienkÄrÅ”i "pielikt" malÄ sektoru diagramma.
RÄdÄm uz mezglu un redzam ā izrÄdÄs, ka Seq Scan aizÅÄma mazÄk par ceturtdaļu no kopÄjÄ laika, bet atlikuÅ”Äs 3/4 paÅÄma CTE Scan. Å ausmas! Å Ä« ir neliela piezÄ«me par CTE Scan āuguns Ätrumuā, ja jÅ«s tos aktÄ«vi izmantojat savos vaicÄjumos. Tie nav Ä«paÅ”i Ätri - tie ir zemÄki pat par parasto tabulu skenÄÅ”anu. [raksts][raksts]
Bet parasti Å”Ädas diagrammas ir interesantÄkas, sarežģītÄkas, kad mÄs uzreiz norÄdÄm uz segmentu un redzam, piemÄram, ka vairÄk nekÄ pusi no laika kÄds Seq Scan āapÄdaā. TurklÄt iekÅ”Ä bija kaut kÄds Filtrs, pÄc tÄ tika izmesti daudz ierakstu... Vari tieÅ”i Å”o bildi iemest izstrÄdÄtÄjam un teikt: āVasja, tev te viss ir slikti! IzdomÄ, paskaties ā kaut kas nav kÄrtÄ«bÄ!ā
Protams, bija iesaistÄ«ti daži āgrÄbekļiā.
PirmÄ lieta, ko mÄs saskÄrÄmies, bija noapaļoÅ”anas problÄma. Katra atseviŔķa mezgla laiks plÄnÄ ir norÄdÄ«ts ar precizitÄti 1 Ī¼s. Un, kad mezglu ciklu skaits pÄrsniedz, piemÄram, 1000 - pÄc izpildes PostgreSQL dalÄ«ts "precizitÄtes robežÄs", tad, aprÄÄ·inot atpakaļ, mÄs iegÅ«stam kopÄjo laiku "kaut kur starp 0.95 ms un 1.05 ms". Ja skaitÄ«Å”ana pÄriet uz mikrosekundÄm, tas ir labi, bet, kad tas jau ir [miljoni]sekundes, Ŕī informÄcija ir jÄÅem vÄrÄ, āatsaistotā resursus no plÄna ākurÅ” cik patÄrÄjaā mezgliem.
Otrs, sarežģītÄks punkts ir resursu (Å”o buferu) sadale starp dinamiskajiem mezgliem. Tas mums izmaksÄja pirmÄs 2 prototipa nedÄļas un vÄl 4 nedÄļas.
Ir diezgan viegli iegÅ«t Å”Äda veida problÄmu ā mÄs veicam CTE un it kÄ kaut ko tajÄ lasÄm. Faktiski PostgreSQL ir āgudrsā un tur neko tieÅ”i nelasÄ«s. Tad mÄs no tÄ Åemam pirmo ierakstu un simts pirmo ierakstu no tÄ paÅ”a CTE.
MÄs skatÄmies uz plÄnu un saprotam - tas ir dÄ«vaini, mums ir āpatÄrÄtiā 3 buferi (datu lapas) Seq Scan, vÄl 1 CTE Scan un vÄl 2 otrajÄ CTE Scan. Tas ir, ja mÄs vienkÄrÅ”i visu summÄjam, mÄs iegÅ«sim 6, bet no planÅ”etdatora mÄs nolasÄm tikai 3! CTE Scan neko nelasa no jebkuras vietas, bet darbojas tieÅ”i ar procesa atmiÅu. RespektÄ«vi, Å”eit kaut kas nepÄrprotami nav kÄrtÄ«bÄ!
PatiesÄ«bÄ izrÄdÄs, ka Å”eit ir visas tÄs 3 datu lapas, kas tika pieprasÄ«tas no Seq Scan, vispirms 1 prasÄ«ja 1. CTE Scan, un tad 2. un vÄl 2 viÅam tika nolasÄ«tas.Tas ir, kopÄ Dati tika nolasÄ«ti 3 lappusÄs, nevis 6.
Un Ŕī bilde lika mums saprast, ka plÄna izpilde vairs nav koks, bet vienkÄrÅ”i kaut kÄds aciklisks grafiks. Un mÄs saÅÄmÄm Å”Ädu diagrammu, lai mÄs saprastu, ākas vispirms ir no kurienes nÄcaā. Tas ir, Å”eit mÄs izveidojÄm CTE no pg_class un lÅ«dzÄm to divreiz, un gandrÄ«z viss mÅ«su laiks tika pavadÄ«ts filiÄlÄ, kad mÄs to lÅ«dzÄm otro reizi. Skaidrs, ka 2. ieraksta lasÄ«Å”ana ir daudz dÄrgÄka nekÄ tikai 101. ieraksta lasÄ«Å”ana no planÅ”etdatora.
KÄdu brÄ«di izelpojÄm. ViÅi teica: āTagad, Neo, tu zini kung fu! Tagad mÅ«su pieredze ir tieÅ”i jÅ«su ekrÄnÄ. Tagad jÅ«s varat to izmantot." [raksts]
Baļķu konsolidÄcija
MÅ«su 1000 izstrÄdÄtÄju atviegloti nopÅ«tÄs. Bet mÄs sapratÄm, ka mums ir tikai simtiem ākaujasā serveru, un visa Ŕī izstrÄdÄtÄju ākopÄÅ”ana-ielÄ«mÄÅ”anaā nepavisam nav Ärta. SapratÄm, ka jÄsavÄc paÅ”iem.
KopumÄ ir standarta modulis, kas var apkopot statistiku, tomÄr tas ir jÄaktivizÄ arÄ« konfigurÄcijÄ - tas modulis pg_stat_statements. Bet viÅÅ” mums nederÄja.
PirmkÄrt, tas pieŔķir vieniem un tiem paÅ”iem vaicÄjumiem, izmantojot dažÄdas shÄmas vienÄ datu bÄzÄ dažÄdi vaicÄjuma ID. Tas ir, ja jÅ«s vispirms to darÄt SET search_path = '01'; SELECT * FROM user LIMIT 1;un tad SET search_path = '02'; un tas pats pieprasÄ«jums, tad Ŕī moduļa statistikai bÅ«s dažÄdi ieraksti, un es nevarÄÅ”u savÄkt vispÄrÄ«gu statistiku tieÅ”i Ŕī pieprasÄ«juma profila kontekstÄ, neÅemot vÄrÄ shÄmas.
Otrs punkts, kas neļÄva mums to izmantot, ir plÄnu trÅ«kums. Tas ir, plÄna nav, ir tikai pats pieprasÄ«jums. MÄs redzam, kas palÄninÄjÄs, bet nesaprotam, kÄpÄc. Un Å”eit mÄs atgriežamies pie strauji mainÄ«gas datu kopas problÄmas.
Un pÄdÄjais brÄ«dis - "faktu" trÅ«kums. Tas ir, jÅ«s nevarat risinÄt konkrÄtu vaicÄjuma izpildes gadÄ«jumu ā tÄda nav, ir tikai apkopota statistika. Lai gan ar to ir iespÄjams strÄdÄt, tas ir vienkÄrÅ”i ļoti grÅ«ti.
TÄpÄc nolÄmÄm cÄ«nÄ«ties ar copy-paste un sÄkÄm rakstÄ«t kolektors.
Kolektors izveido savienojumu, izmantojot SSH, izveido droÅ”u savienojumu ar serveri ar datu bÄzi, izmantojot sertifikÄtu, un tail -F āpieÄ·erasā tam žurnÄla failÄ. TÄtad Å”ajÄ sesijÄ mÄs iegÅ«stam pilnÄ«gu visa žurnÄlfaila "spoguli"., ko serveris Ä£enerÄ. PaÅ”a servera slodze ir minimÄla, jo mÄs tur neko neparsÄjam, mÄs tikai atspoguļojam trafiku.
TÄ kÄ interfeisu jau bijÄm sÄkuÅ”i rakstÄ«t Node.js, turpinÄjÄm tajÄ rakstÄ«t savÄcÄju. Un Ŕī tehnoloÄ£ija sevi ir attaisnojusi, jo ir ļoti Ärti izmantot JavaScript, lai strÄdÄtu ar vÄji formatÄtiem teksta datiem, kas ir žurnÄls. Un pati Node.js infrastruktÅ«ra kÄ aizmugures platforma ļauj viegli un Ärti strÄdÄt ar tÄ«kla savienojumiem un, protams, ar jebkÄdÄm datu plÅ«smÄm.
AttiecÄ«gi mÄs āizstiepjamā divus savienojumus: pirmo, lai āklausÄ«tosā paÅ”Ä Å¾urnÄlÄ un Åemtu to sev, un otro, lai periodiski jautÄtu bÄzei. āBet žurnÄlÄ redzams, ka zÄ«me ar 123. ID ir bloÄ·Ätaā, taÄu izstrÄdÄtÄjam tas neko nenozÄ«mÄ, un bÅ«tu jauki pajautÄt datubÄzei: āKas tik un tÄ ir OID = 123?ā TÄpÄc mÄs periodiski jautÄjam bÄzei to, ko vÄl nezinÄm par sevi.
"Ir tikai viena lieta, ko jÅ«s neÅÄmÄt vÄrÄ, ir ziloÅiem lÄ«dzÄ«gu biÅ”u suga!..." MÄs sÄkÄm izstrÄdÄt Å”o sistÄmu, kad vÄlÄjÄmies uzraudzÄ«t 10 serverus. MÅ«su izpratnÄ viskritiskÄkais, kur radÄs dažas problÄmas, ar kurÄm bija grÅ«ti tikt galÄ. Bet pirmajÄ ceturksnÄ« par monitoringu saÅÄmÄm simtu - jo sistÄma darbojÄs, visi to gribÄja, visiem bija Ärti.
Tas viss ir jÄsaskaita, datu plÅ«sma ir liela un aktÄ«va. PatiesÄ«bÄ tas, ko mÄs uzraugÄm, ar ko varam tikt galÄ, ir tas, ko mÄs izmantojam. MÄs arÄ« izmantojam PostgreSQL kÄ datu krÄtuvi. Un nekas nevar ÄtrÄk āielietā datus par operatoru COPY VÄl nÄ.
Bet vienkÄrÅ”i datu āielieÅ”anaā patiesÄ«bÄ nav mÅ«su tehnoloÄ£ija. Jo, ja jums ir aptuveni 50 100 pieprasÄ«jumu sekundÄ uz simts serveriem, tas Ä£enerÄs 150āXNUMX GB žurnÄlu dienÄ. TÄpÄc mums bija rÅ«pÄ«gi ājÄnogriežā pamatne.
PirmkÄrt, mÄs to izdarÄ«jÄm sadalÄ«Å”ana pa dienÄm, jo pa lielam nevienu neinteresÄ korelÄcija starp dienÄm. KÄda nozÄ«me ir tam, kas jums bija vakar, ja Å”ovakar jÅ«s izlaidÄt jaunu lietojumprogrammas versiju un jau jaunu statistiku.
OtrkÄrt, mÄs mÄcÄ«jÄmies (bijÄm spiesti) ļoti, ļoti Ätri rakstÄ«t, izmantojot COPY. Tas ir, ne tikai COPYjo viÅÅ” ir ÄtrÄks par INSERT, un vÄl ÄtrÄk.
TreÅ”ais punkts ā vajadzÄja attiecÄ«gi atteikties no trigeriem un ÄrÄjÄm atslÄgÄm. Tas ir, mums vispÄr nav atsauces integritÄtes. Jo, ja jums ir tabula, kurÄ ir pÄris FK, un jÅ«s datu bÄzes struktÅ«rÄ sakÄt, ka "Å”eit ir žurnÄla ieraksts, uz kuru FK atsaucas, piemÄram, uz ierakstu grupu", tad, ievietojot to, PostgreSQL nekas cits neatliek, kÄ to Åemt un darÄ«t godÄ«gi SELECT 1 FROM master_fk1_table WHERE ... ar identifikatoru, kuru mÄÄ£inÄt ievietot - tikai, lai pÄrbaudÄ«tu, vai Å”is ieraksts tur ir, vai jÅ«s ar ievietoÅ”anu nenojaucat Å”o ÄrÄjo atslÄgu.
Viena ieraksta vietÄ mÄrÄ·a tabulai un tÄs indeksiem mÄs gÅ«stam papildu labumu, lasot visas tabulas, uz kurÄm tÄ attiecas. Bet mums tas nemaz nav vajadzÄ«gs - mÅ«su uzdevums ir ierakstÄ«t pÄc iespÄjas vairÄk un pÄc iespÄjas ÄtrÄk ar mazÄko slodzi. TÄtad FK - uz leju!
NÄkamais punkts ir apkopoÅ”ana un jaukÅ”ana. SÄkotnÄji mÄs tos ieviesÄm datu bÄzÄ - galu galÄ ir Ärti uzreiz, kad pienÄk ieraksts, to izdarÄ«t kaut kÄdÄ planÅ”etdatorÄ "plus viens" tieÅ”i trigerÄ«. Nu, tas ir Ärti, bet tas pats slikts - jÅ«s ievietojat vienu ierakstu, bet esat spiests lasÄ«t un rakstÄ«t kaut ko citu no citas tabulas. TurklÄt jÅ«s ne tikai lasÄt un rakstÄt, bet arÄ« darÄt to katru reizi.
Tagad iedomÄjieties, ka jums ir tabula, kurÄ jÅ«s vienkÄrÅ”i saskaitÄt pieprasÄ«jumu skaitu, kas ir nosÅ«tÄ«ti caur noteiktu resursdatoru: +1, +1, +1, ..., +1. Un jums principÄ tas nav vajadzÄ«gs - tas viss ir iespÄjams summa atmiÅÄ uz kolekcionÄra un nosÅ«tiet uz datu bÄzi vienÄ piegÄjienÄ +10.
JÄ, dažu problÄmu gadÄ«jumÄ jÅ«su loÄ£iskÄ integritÄte var āizjuktā, bet tas ir gandrÄ«z nereÄls gadÄ«jums - jo jums ir parasts serveris, tam ir akumulators kontrollerÄ«, jums ir darÄ«jumu žurnÄls, žurnÄls failu sistÄma... KopumÄ nav tÄ vÄrts. ProduktivitÄtes zudums, ko iegÅ«stat, darbinot trigerus/FK, nav to izdevumu vÄrts, kas jums rodas.
TÄpat ir ar jaukÅ”anu. Pie jums atlido noteikts pieprasÄ«jums, jÅ«s no tÄ datu bÄzÄ izskaitļojat noteiktu identifikatoru, ierakstÄt to datu bÄzÄ un pÄc tam pastÄstÄt visiem. Viss ir kÄrtÄ«bÄ, lÄ«dz ierakstÄ«Å”anas laikÄ pie jums pienÄk otra persona, kas vÄlas ierakstÄ«t to paÅ”u - un jÅ«s tiekat bloÄ·Äts, un tas jau ir slikti. TÄpÄc, ja dažu ID Ä£enerÄÅ”anu varat pÄrsÅ«tÄ«t klientam (attiecÄ«bÄ pret datu bÄzi), labÄk to darÄ«t.
Mums bija vienkÄrÅ”i ideÄli izmantot MD5 no teksta - pieprasÄ«jums, plÄns, veidne,... MÄs to aprÄÄ·inÄm savÄcÄja pusÄ, un gatavo ID āieberamā datu bÄzÄ. MD5 garums un ikdienas sadalÄ«Å”ana ļauj mums neuztraukties par iespÄjamÄm sadursmÄm.
Bet, lai to visu Ätri ierakstÄ«tu, mums bija jÄmaina pati ierakstÄ«Å”anas procedÅ«ra.
KÄ jÅ«s parasti rakstÄt datus? Mums ir kaut kÄda datu kopa, mÄs to sadalÄm vairÄkÄs tabulÄs, un tad KOPÄJAM - vispirms pirmajÄ, tad otrajÄ, treÅ”ajÄ... Tas ir neÄrti, jo Ŕķiet, ka mÄs rakstÄm vienu datu straumi trÄ«s soļos. secÄ«gi. NepatÄ«kami. Vai to var izdarÄ«t ÄtrÄk? Var!
Lai to izdarÄ«tu, pietiek tikai sadalÄ«t Ŕīs plÅ«smas paralÄli viena otrai. IzrÄdÄs, ka mums ir kļūdas, pieprasÄ«jumi, veidnes, bloÄ·ÄÅ”ana, ... lido atseviŔķos pavedienos - un mÄs to visu rakstÄm paralÄli. Pietiekami Å”im pastÄvÄ«gi atvÄrt COPY kanÄlu katrai atseviŔķai mÄrÄ·a tabulai.
Tas ir, pie kolekcionÄra vienmÄr ir straume, kurÄ varu ierakstÄ«t sev nepiecieÅ”amos datus. Bet, lai datu bÄze redzÄtu Å”os datus un kÄds neiestrÄgtu, gaidot, kad Å”ie dati tiks ierakstÄ«ti, COPY ir jÄpÄrtrauc noteiktos intervÄlos. Mums visefektÄ«vÄkais periods bija apmÄram 100ms - aizveram un uzreiz atkal atveram pie tÄ paÅ”a galda. Un, ja mums nav pietiekami daudz vienas plÅ«smas dažu maksimumu laikÄ, mÄs veicam apvienoÅ”anu lÄ«dz noteiktai robežai.
TurklÄt mÄs noskaidrojÄm, ka Å”Ädam slodzes profilam jebkura apkopoÅ”ana, kad ieraksti tiek vÄkti pa partijÄm, ir ļauni. Klasiskais ļaunums ir INSERT ... VALUES un vÄl 1000 ierakstu. Jo tajÄ brÄ«dÄ« jums ir rakstÄ«Å”anas maksimums datu nesÄjÄ, un visi pÄrÄjie, kas mÄÄ£inÄs kaut ko ierakstÄ«t diskÄ, gaidÄ«s.
Lai atbrÄ«votos no Å”ÄdÄm anomÄlijÄm, vienkÄrÅ”i neko neapkopojiet, nebuferÄjiet vispÄr. Un, ja notiek buferizÄcija uz diska (par laimi, Stream API Node.js ļauj to uzzinÄt) - atlikt Å”o savienojumu. Kad saÅemat pasÄkumu, ka tas atkal ir bezmaksas, rakstiet uz to no uzkrÄtÄs rindas. Un, kamÄr tas ir aizÅemts, paÅemiet nÄkamo brÄ«vo no baseina un uzrakstiet tam.
Pirms Ŕīs pieejas ievieÅ”anas datu ierakstÄ«Å”anai mums bija aptuveni 4K rakstÄ«Å”anas darbÄ«bas, un tÄdÄ veidÄ mÄs samazinÄjÄm slodzi 4 reizes. Tagad tÄs ir auguÅ”as vÄl 6 reizes, pateicoties jaunÄm uzraudzÄ«tÄm datubÄzÄm ā lÄ«dz 100MB/s. Un tagad mÄs glabÄjam žurnÄlus pÄdÄjos 3 mÄneÅ”us apmÄram 10-15 TB apjomÄ, cerot, ka tikai trÄ«s mÄneÅ”u laikÄ jebkurÅ” izstrÄdÄtÄjs spÄs atrisinÄt jebkuru problÄmu.
MÄs saprotam problÄmas
Bet vienkÄrÅ”i savÄkt visus Å”os datus ir labi, noderÄ«gi, atbilstoÅ”i, bet nepietiek ā tas ir jÄsaprot. Jo tie ir miljoniem dažÄdu plÄnu dienÄ.
Bet miljoni ir nepÄrvaldÄmi, vispirms ir jÄdara āmazÄkā. Un, pirmkÄrt, jums ir jÄizlemj, kÄ jÅ«s organizÄsit Å”o āmazÄkoā lietu.
kurŔ nosūtīja Ŕo pieprasījumu
Tas ir, no kuras lietojumprogrammas tas ānonÄcaā: tÄ«mekļa saskarne, aizmugursistÄma, maksÄjumu sistÄma vai kaut kas cits.
kur tas notika
Uz kÄda konkrÄta servera? Jo, ja jums ir vairÄki serveri zem vienas aplikÄcijas, un pÄkÅ”Åi viens "stulbst" (jo "disks ir sapuvis", "atmiÅa noplÅ«da", kÄda cita problÄma), tad jums ir Ä«paÅ”i jÄvÄrÅ”as pie servera.
kÄ problÄma tÄ vai citÄdi izpaudÄs
Lai saprastu, "kas" mums nosÅ«tÄ«ja pieprasÄ«jumu, mÄs izmantojam standarta rÄ«ku - sesijas mainÄ«gÄ iestatÄ«Å”anu: SET application_name = '{bl-host}:{bl-method}'; ā mÄs nosÅ«tÄm tÄ biznesa loÄ£ikas resursdatora nosaukumu, no kura tiek saÅemts pieprasÄ«jums, un tÄs metodes vai lietojumprogrammas nosaukumu, kas to ierosinÄja.
Kad esam nodevuÅ”i pieprasÄ«juma āÄ«paÅ”niekuā, tas ir jÄizvada žurnÄlÄ - Å”im nolÅ«kam mÄs konfigurÄjam mainÄ«go log_line_prefix = ' %m [%p:%v] [%d] %r %a'. Interesentiem, varbÅ«t paskaties rokasgrÄmatÄko tas viss nozÄ«mÄ. IzrÄdÄs, ka mÄs žurnÄlÄ redzam:
laiks
procesu un darījumu identifikatori
datu bÄzes nosaukums
TÄs personas IP, kura nosÅ«tÄ«ja Å”o pieprasÄ«jumu
un metodes nosaukums
Tad sapratÄm, ka nav Ä«paÅ”i interesanti skatÄ«ties korelÄciju vienam pieprasÄ«jumam starp dažÄdiem serveriem. Nereti gadÄs, ka viena lietojumprogramma Å”ur un tur vienÄdi sabojÄjas. Bet pat tad, ja tas ir vienÄds, apskatiet kÄdu no Å”iem serveriem.
TÄtad, lÅ«k, griezums "viens serveris - viena diena" mums ar to pietika jebkurai analÄ«zei.
PirmÄ analÄ«tiskÄ sadaļa ir tÄda pati "paraugs" - plÄna saÄ«sinÄta prezentÄcijas forma, attÄ«rÄ«ta no visiem skaitliskiem rÄdÄ«tÄjiem. Otrais griezums ir lietojumprogramma vai metode, bet treÅ”ais ir konkrÄtais plÄna mezgls, kas mums radÄ«ja problÄmas.
PÄrejot no konkrÄtiem gadÄ«jumiem uz veidnÄm, mÄs ieguvÄm uzreiz divas priekÅ”rocÄ«bas:
daudzkÄrtÄja analÄ«zes objektu skaita samazinÄÅ”ana
Mums problÄma vairs nav jÄanalizÄ pÄc tÅ«kstoÅ”iem vaicÄjumu vai plÄnu, bet pÄc desmitiem veidÅu.
laika skala
Tas ir, apkopojot āfaktusā noteiktÄ sadaļÄ, jÅ«s varat parÄdÄ«t to izskatu dienas laikÄ. Un te var saprast, ka, ja tev ir kaut kÄds modelis, kas notiek, piemÄram, reizi stundÄ, bet tam vajadzÄtu notikt reizi dienÄ, ir jÄpadomÄ, kas nogÄja greizi - kas to izraisÄ«ja un kÄpÄc, varbÅ«t tam vajadzÄtu bÅ«t Å”eit nevajadzÄtu. Å Ä« ir vÄl viena neskaitliska, tÄ«ri vizuÄla analÄ«zes metode.
PÄrÄjÄs metodes ir balstÄ«tas uz rÄdÄ«tÄjiem, kurus mÄs iegÅ«stam no plÄna: cik reizes Å”Äds modelis notika, kopÄjais un vidÄjais laiks, cik daudz datu tika nolasÄ«ts no diska un cik no atmiÅas...
TÄ kÄ, piemÄram, jÅ«s nonÄkat resursdatora analÄ«tikas lapÄ, paskatieties - diskÄ kaut kas sÄk lasÄ«t pÄrÄk daudz. ServerÄ« esoÅ”ais disks to nevar apstrÄdÄt ā kurÅ” no tÄ lasa?
Un jÅ«s varat kÄrtot pÄc jebkuras kolonnas un izlemt, ar ko jÅ«s tagad nodarbosities - procesora vai diska slodze, vai kopÄjais pieprasÄ«jumu skaits... MÄs to sakÄrtojÄm, apskatÄ«jÄm āaugÅ”Äkosā, labojÄm un izlaida jaunu lietojumprogrammas versiju. [videolekcija]
Un uzreiz jÅ«s varat redzÄt dažÄdas lietojumprogrammas, kurÄm ir viena un tÄ pati veidne no pieprasÄ«juma, piemÄram, SELECT * FROM users WHERE login = 'Vasya'. PriekÅ”gals, aizmugursistÄma, apstrÄde... Un jÅ«s domÄjat, kÄpÄc apstrÄde nolasa lietotÄju, ja viÅÅ” ar viÅu nesazinÄs.
PretÄjs veids ir uzreiz redzÄt no lietojumprogrammas, ko tÄ dara. PiemÄram, frontend ir tas, tas, Å”is un tas reizi stundÄ (laika skala palÄ«dz). Un uzreiz rodas jautÄjums: Ŕķiet, ka nav frontend uzdevums reizi stundÄ kaut ko darÄ«t...
PÄc kÄda laika mÄs sapratÄm, ka mums trÅ«kst apkopojuma statistika pÄc plÄna mezgliem. No plÄniem izolÄjÄm tikai tos mezglus, kas kaut ko dara ar paÅ”u tabulu datiem (lasa/raksta tos pÄc indeksa vai ne). Faktiski salÄ«dzinÄjumÄ ar iepriekÅ”Äjo attÄlu tiek pievienots tikai viens aspekts - cik ierakstus Å”is mezgls mums atnesa?, un cik tika atmesti (Filtra noÅemtÄs rindas).
Jums nav piemÄrota indeksa uz plÄksnÄ«tes, jÅ«s tai iesniedzat pieprasÄ«jumu, tas lido garÄm indeksam, iekrÄ«t Seq Scan... jÅ«s esat izfiltrÄjis visus ierakstus, izÅemot vienu. KÄpÄc jums ir nepiecieÅ”ami 100 miljoni filtrÄtu ierakstu dienÄ? Vai nav labÄk apkopot indeksu?
IzanalizÄjot visus plÄnus pÄc mezgla, mÄs sapratÄm, ka plÄnos ir dažas tipiskas struktÅ«ras, kas, visticamÄk, izskatÄs aizdomÄ«gas. Un bÅ«tu jauki pateikt izstrÄdÄtÄjam: āDraugs, Å”eit jÅ«s vispirms izlasiet pÄc indeksa, pÄc tam kÄrtojat un pÄc tam nogriežatā - parasti ir viens ieraksts.
Ikviens, kurÅ” rakstÄ«jis vaicÄjumus, droÅ”i vien ir saskÄries ar Å”Ädu modeli: āIedodiet man pÄdÄjo Vasjas pasÅ«tÄ«jumu, tÄ datumu.ā Un, ja jums nav datu indeksa vai izmantotajÄ rÄdÄ«tÄjÄ nav datuma, tad jÅ«s uzkÄp tieÅ”i uz tÄ paÅ”a āgrÄbekļaā .
Bet mÄs zinÄm, ka tas ir "grÄbeklis" - kÄpÄc gan nekavÄjoties nepaziÅot izstrÄdÄtÄjam, kas viÅam jÄdara. AttiecÄ«gi, tagad atverot plÄnu, mÅ«su izstrÄdÄtÄjs uzreiz redz skaistu bildi ar padomiem, kur uzreiz viÅam saka: āTev ir problÄmas Å”ur tur, bet tÄs tiek risinÄtas tÄ un tÄ.ā
LÄ«dz ar to pieredzes apjoms, kas bija nepiecieÅ”ams problÄmu risinÄÅ”anai sÄkumÄ un tagad, ir ievÄrojami samazinÄjies. TÄds rÄ«ks mums ir.