Nesen es jums teicu, kÄ, izmantojot standarta receptes palielinÄt SQL lasÄ«Å”anas vaicÄjumu veiktspÄju no PostgreSQL datu bÄzes. Å odien mÄs runÄsim par to, kÄ ierakstÄ«Å”anu var veikt efektÄ«vÄk datu bÄzÄ, neizmantojot nekÄdus konfigurÄcijas āpagriezienusā - vienkÄrÅ”i pareizi organizÄjot datu plÅ«smas.
SÄkotnÄji, kÄ jau jebkurÅ” MVP, arÄ« mÅ«su projekts sÄkÄs ar diezgan vieglu slodzi - monitorings tika veikts tikai desmit kritiskÄkajiem serveriem, visas tabulas bija salÄ«dzinoÅ”i kompaktas... TaÄu, laikam ejot, uzraudzÄ«to saimnieku skaits kļuva arvien lielÄks. , un kÄrtÄjo reizi mÄÄ£inÄjÄm kaut ko darÄ«t ar vienu no galdi 1.5 TB izmÄrs, mÄs sapratÄm, ka, lai gan bija iespÄjams turpinÄt dzÄ«vot Å”Ädi, tas bija ļoti neÄrti.
Laiki bija gandrÄ«z kÄ episki, dažÄdas PostgreSQL 9.x versijas bija aktuÄlas, tÄpÄc visa sadalÄ«Å”ana bija jÄveic āmanuÄliā tabulas mantojums un trigeri marÅ”rutÄÅ”ana ar dinamisko EXECUTE.
IegÅ«tais risinÄjums izrÄdÄ«jÄs pietiekami universÄls, lai to varÄtu tulkot visÄs tabulÄs:
Tika deklarÄta tukÅ”a āgalvenesā vecÄktabula, kurÄ aprakstÄ«ts viss nepiecieÅ”amie indeksi un trigeri.
Ieraksts no klienta viedokļa tika veikts āsaknesā tabulÄ un iekÅ”Äji izmantojot marÅ”rutÄÅ”anas trigerisBEFORE INSERT ieraksts tika āfiziskiā ievietots vajadzÄ«gajÄ sadaļÄ. Ja tÄda vÄl nebija, pieÄ·ÄrÄm izÅÄmumu un...
ā¦ izmantojot CREATE TABLE ... (LIKE ... INCLUDING ...) tika izveidots, pamatojoties uz vecÄktabulas veidni sadaļa ar ierobežojumu vÄlamajÄ datumÄlai, izgÅ«stot datus, nolasÄ«Å”ana tiktu veikta tikai tajÄ.
PG10: pirmais mÄÄ£inÄjums
TaÄu sadalÄ«Å”ana, izmantojot mantoÅ”anu, vÄsturiski nav bijusi Ä«paÅ”i piemÄrota darbam ar aktÄ«vu rakstÄ«Å”anas straumi vai lielu skaitu pÄcnÄcÄju nodalÄ«jumu. PiemÄram, varat atcerÄties, ka vajadzÄ«gÄs sadaļas atlases algoritms bija kvadrÄtiskÄ sarežģītÄ«ba, ka strÄdÄ ar 100+ sadaļÄm, tu pats saproti, kÄ...
PG10 Ŕī situÄcija tika ievÄrojami optimizÄta, ievieÅ”ot atbalstu vietÄjÄ sadalÄ«Å”ana. TÄpÄc mÄs nekavÄjoties mÄÄ£inÄjÄm to lietot uzreiz pÄc krÄtuves migrÄÅ”anas, bet...
SaÅÄmuÅ”i sÄpÄ«gu sitienu ar grÄbekli pa pieri, sapratÄm, ka bez pieteikuma modifikÄcijas iztikt nevarÄs, un tÄlÄko izpÄti atlikÄm uz pusgadu.
PG10: otrÄ iespÄja
TÄtad, mÄs sÄkÄm risinÄt problÄmas, kas radÄs pa vienam:
Jo izraisa un ON CONFLICT mÄs atklÄjÄm, ka mums tie joprojÄm ir vajadzÄ«gi Å”eit un tur, tÄpÄc mÄs veicÄm starpposmu, lai tos izstrÄdÄtu starpniekserveru tabula.
AtbrÄ«vojÄs no "marÅ”rutÄÅ”anas" trigeros - tas ir, no EXECUTE.
ViÅi to izÅÄma atseviŔķi veidÅu tabula ar visiem indeksiemtÄ, ka tie nav pat starpniekserveru tabulÄ.
Visbeidzot, pÄc visa Ŕī, mÄs sÄkotnÄji sadalÄ«jÄm galveno tabulu. Jaunas sadaļas izveide joprojÄm ir atstÄta uz aplikÄcijas sirdsapziÅas.
āZÄÄ£ÄÅ”anasā vÄrdnÄ«cas
TÄpat kÄ jebkurÄ analÄ«tiskajÄ sistÄmÄ, arÄ« mums bija "fakti" un "griezumi" (vÄrdnÄ«cas). MÅ«su gadÄ«jumÄ Å”ajÄ statusÄ viÅi rÄ«kojÄs, piemÄram, veidnes korpuss lÄ«dzÄ«gi lÄni vaicÄjumi vai pats vaicÄjuma teksts.
āFaktiā jau sen tika sadalÄ«ti pa dienÄm, tÄpÄc mierÄ«gi dzÄsÄm novecojuÅ”Äs sadaļas, un tÄs mÅ«s netraucÄja (logs!). Bet bija problÄma ar vÄrdnÄ«cÄm...
Lai neteiktu, ka viÅu bija daudz, bet aptuveni 100 TB āfaktuā rezultÄtÄ tika izveidota 2.5 TB vÄrdnÄ«ca. No Å”Ädas tabulas neko nevar Ärti izdzÄst, nevar to saspiest pienÄcÄ«gÄ laikÄ, un rakstÄ«Å”ana tajÄ pamazÄm kļuva lÄnÄka.
KÄ vÄrdnÄ«ca... tajÄ katrs ieraksts ir jÄuzrÄda tieÅ”i vienu reizi... un tas ir pareizi, bet!.. Neviens mums neliedz katrai dienai atseviŔķa vÄrdnÄ«ca! JÄ, tas rada zinÄmu atlaiÅ”anu, bet ļauj:
patÄrÄ mazÄk atmiÅas strÄdÄjot ar kompaktÄkiem indeksiem
uzglabÄt mazÄk datu pateicoties iespÄjai Ätri noÅemt novecojuÅ”o
Visa pasÄkumu kompleksa rezultÄtÄ CPU slodze samazinÄta par ~30%, diska slodze par ~50%:
TajÄ paÅ”Ä laikÄ mÄs turpinÄjÄm datubÄzÄ ierakstÄ«t tieÅ”i to paÅ”u, tikai ar mazÄku slodzi.
#2. Datu bÄzes attÄ«stÄ«ba un pÄrstrukturÄÅ”ana
TÄpÄc mÄs izlÄmÄm par to, kas mums ir katrai dienai ir sava sadaļa ar datiem. PatiesÄ«bÄ CHECK (dt = '2018-10-12'::date) ā un ir nodalÄ«juma atslÄga un nosacÄ«jums, lai ieraksts iekļautos noteiktÄ sadaļÄ.
TÄ kÄ visi mÅ«su pakalpojuma pÄrskati ir veidoti konkrÄta datuma kontekstÄ, to indeksi kopÅ” ānesadalÄ«tajiem laikiemā ir bijuÅ”i visu veidu (serveris, Datums, plÄna veidne), (serveris, Datums, PlÄna mezgls), (Datums, kļūdu klase, serveris), ...
Bet tagad viÅi dzÄ«vo katrÄ sadaÄ¼Ä jÅ«su kopijas katrs Å”Äds rÄdÄ«tÄjs... Un katras sadaļas ietvaros datums ir konstante... IzrÄdÄs, ka tagad esam katrÄ Å”ÄdÄ rÄdÄ«tÄjÄ vienkÄrÅ”i ievadiet konstanti kÄ viens no laukiem, kas palielina gan tÄ apjomu, gan meklÄÅ”anas laiku tam, bet nenes nekÄdu rezultÄtu. GrÄbekli viÅi atstÄja sev, ups...
OptimizÄcijas virziens ir acÄ«mredzams ā vienkÄrÅ”s noÅemiet datuma lauku no visiem indeksiem uz sadalÄ«tiem galdiem. Å emot vÄrÄ mÅ«su apjomus, ieguvums ir aptuveni 1 TB nedÄļÄ!
Tagad atzÄ«mÄsim, ka Å”is terabaits tomÄr bija kaut kÄ jÄieraksta. Tas ir, mÄs arÄ« diskam tagad vajadzÄtu ielÄdÄt mazÄk! Å ajÄ attÄlÄ skaidri redzams efekts, kas iegÅ«ts no tÄ«rÄ«Å”anas, kurai mÄs veltÄ«jÄm nedÄļu:
#3. MaksimÄlÄs slodzes āizkliedÄÅ”anaā.
Viena no lielÄkajÄm ielÄdÄto sistÄmu problÄmÄm ir liekÄ sinhronizÄcija dažas darbÄ«bas, kurÄm tas nav nepiecieÅ”ams. ReizÄm ātÄpÄc, ka nepamanÄ«jaā, reizÄm ātÄ bija vieglÄkā, bet agri vai vÄlu no tÄ jÄtiek vaļÄ.
PietuvinÄsim iepriekÅ”Äjo attÄlu un redzÄsim, ka mums ir disks āsÅ«kÅiā zem slodzes ar dubultu amplitÅ«du starp blakus esoÅ”ajiem paraugiem, kam nepÄrprotami āstatistiskiā nevajadzÄtu notikt ar Å”Ädu darbÄ«bu skaitu:
Tas ir diezgan viegli sasniedzams. MÄs jau esam sÄkuÅ”i uzraudzÄ«bu gandrÄ«z 1000 serveru, katru apstrÄdÄ atseviŔķs loÄ£iskais pavediens, un katrs pavediens atiestata uzkrÄto informÄciju, kas jÄnosÅ«ta datu bÄzei noteiktÄ frekvencÄ, apmÄram Å”Ädi:
setInterval(sendToDB, interval)
ProblÄma Å”eit ir tieÅ”i tajÄ apstÄklÄ«, ka visi pavedieni sÄkas aptuveni vienÄ laikÄ, tÄpÄc to nosÅ«tÄ«Å”anas laiki gandrÄ«z vienmÄr sakrÄ«t. Ak, #2...
Par laimi to ir diezgan viegli salabot, pievienojot ānejauÅ”iā palaiÅ”anu pÄc laika:
TreÅ”Ä tradicionÄlÄ lielÄs slodzes problÄma ir nav keÅ”atmiÅas kur viÅÅ” ir varÄtu bÅ«t.
PiemÄram, mÄs ļÄvÄm analizÄt plÄna mezglu izteiksmÄ (visi Å”ie Seq Scan on users), bet uzreiz domÄju, ka tie lielÄkoties ir vienÄdi - viÅi aizmirsa.
NÄ, protams, atkal nekas netiek ierakstÄ«ts datu bÄzÄ, tas nogriež sprÅ«da ar INSERT ... ON CONFLICT DO NOTHING. Bet Å”ie dati joprojÄm sasniedz datu bÄzi, un tas nav nepiecieÅ”ams lasÄ«Å”ana, lai pÄrbaudÄ«tu konfliktu jÄdara. Ak, #3...
AtŔķirÄ«ba datu bÄzei nosÅ«tÄ«to ierakstu skaitÄ pirms/pÄc keÅ”atmiÅas ieslÄgÅ”anas ir acÄ«mredzama:
Un tas ir saistÄ«tais uzglabÄÅ”anas slodzes samazinÄjums:
KopÄ
āTerabaits dienÄā vienkÄrÅ”i izklausÄs biedÄjoÅ”i. Ja jÅ«s darÄt visu pareizi, tad tas ir vienkÄrÅ”i 2^40 baiti / 86400 sekundes = ~12.5 MB/ska pat darbvirsmas IDE skrÅ«ves turÄja. š
Bet ja nopietni, pat ar desmitkÄrtÄ«gu slodzes āŔķībuā dienas laikÄ jÅ«s varat viegli izpildÄ«t mÅ«sdienu SSD iespÄjas.