PostgreSQL mēs rakstām par sublight: 1 resursdators, 1 diena, 1 TB

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.

PostgreSQL mēs rakstām par sublight: 1 resursdators, 1 diena, 1 TB

#1. SadalīŔana

Raksts par to, kā un kāpēc ir vērts organizēt pielietotā sadalÄ«Å”ana ā€œteorētiskiā€ jau ir bijis, Å”eit mēs runāsim par dažu pieeju pielietoÅ”anas praksi mÅ«su ietvaros uzraudzÄ«bas pakalpojums simtiem PostgreSQL serveru.

"PagājuŔo dienu lietas..."

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.

PostgreSQL mēs rakstām par sublight: 1 resursdators, 1 diena, 1 TB
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 trigeris BEFORE 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...

Kā izrādÄ«jās pēc rokasgrāmatas izpētÄ«Å”anas, Å”ajā versijā sākotnēji sadalÄ«tā tabula ir:

  • neatbalsta indeksu aprakstus
  • neatbalsta aktivizētājus
  • nevar bÅ«t neviena "pēcnācējs"
  • neatbalsta INSERT ... ON CONFLICT
  • nevar automātiski Ä£enerēt sadaļu

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:

  1. 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.
  2. AtbrÄ«vojās no "marÅ”rutÄ“Å”anas" trigeros - tas ir, no EXECUTE.
  3. Viņi to izņēma atseviŔķi veidņu tabula ar visiem indeksiemtā, ka tie nav pat starpniekserveru tabulā.

PostgreSQL mēs rakstām par sublight: 1 resursdators, 1 diena, 1 TB
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:

  • rakstÄ«t/lasÄ«t ātrāk mazāka sekcijas izmēra dēļ
  • 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%:

PostgreSQL mēs rakstām par sublight: 1 resursdators, 1 diena, 1 TB
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...

PostgreSQL mēs rakstām par sublight: 1 resursdators, 1 diena, 1 TB
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:

PostgreSQL mēs rakstām par sublight: 1 resursdators, 1 diena, 1 TB

#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:

PostgreSQL mēs rakstām par sublight: 1 resursdators, 1 diena, 1 TB

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:

setInterval(sendToDB, interval * (1 + 0.1 * (Math.random() - 0.5)))

#4. Mēs saglabājam nepiecieÅ”amo keÅ”atmiņu

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:

PostgreSQL mēs rakstām par sublight: 1 resursdators, 1 diena, 1 TB

Un tas ir saistītais uzglabāŔanas slodzes samazinājums:

PostgreSQL mēs rakstām par sublight: 1 resursdators, 1 diena, 1 TB

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.

PostgreSQL mēs rakstām par sublight: 1 resursdators, 1 diena, 1 TB

Avots: www.habr.com

Pievieno komentāru