Tunaandika katika PostgreSQL kwenye sublight: mwenyeji 1, siku 1, 1TB

Hivi majuzi nilikuambia jinsi, kwa kutumia mapishi ya kawaida kuongeza utendaji wa maswali ya kusoma ya SQL kutoka kwa hifadhidata ya PostgreSQL. Leo tutazungumzia jinsi gani kurekodi kunaweza kufanywa kwa ufanisi zaidi kwenye hifadhidata bila kutumia "mizunguko" yoyote kwenye usanidi - kwa kupanga tu mtiririko wa data kwa usahihi.

Tunaandika katika PostgreSQL kwenye sublight: mwenyeji 1, siku 1, 1TB

#1. Kutenganisha

Nakala kuhusu jinsi na kwa nini inafaa kupanga ugawaji uliotumika "katika nadharia" tayari imekuwa, hapa tutazungumza juu ya mazoezi ya kutumia njia kadhaa ndani yetu huduma ya ufuatiliaji kwa mamia ya seva za PostgreSQL.

"Mambo ya siku zilizopita ..."

Hapo awali, kama MVP yoyote, mradi wetu ulianza chini ya mzigo mwepesi - ufuatiliaji ulifanywa tu kwa seva kumi muhimu zaidi, meza zote zilikuwa ngumu ... , na kwa mara nyingine tena tulijaribu kufanya kitu na moja ya meza 1.5TB kwa ukubwa, tuligundua kwamba ingawa ilikuwa inawezekana kuendelea kuishi hivi, ilikuwa vigumu sana.

Nyakati zilikuwa karibu kama nyakati za ajabu, matoleo tofauti ya PostgreSQL 9.x yalikuwa muhimu, kwa hivyo ugawaji wote ulipaswa kufanywa "kwa mikono" - kupitia urithi wa meza na vichochezi uelekezaji kwa kutumia nguvu EXECUTE.

Tunaandika katika PostgreSQL kwenye sublight: mwenyeji 1, siku 1, 1TB
Suluhisho lililosababisha liligeuka kuwa la jumla vya kutosha kwamba linaweza kutafsiriwa kwa jedwali zote:

  • Jedwali tupu la mzazi la "kichwa" lilitangazwa, ambalo lilielezea yote viashiria muhimu na vichochezi.
  • Rekodi kutoka kwa mtazamo wa mteja ilifanywa kwenye jedwali la "mizizi", na kwa kutumia ndani kichochezi cha uelekezaji BEFORE INSERT rekodi iliingizwa "kimwili" kwenye sehemu inayohitajika. Ikiwa hakukuwa na kitu kama hicho bado, tulipata ubaguzi na ...
  • … kwa kutumia CREATE TABLE ... (LIKE ... INCLUDING ...) iliundwa kulingana na kiolezo cha jedwali kuu sehemu yenye kizuizi kwa tarehe inayotakiwaili data inaporejeshwa, usomaji unafanywa ndani yake tu.

PG10: jaribio la kwanza

Lakini ugawaji kupitia urithi haujafaa kihistoria kushughulikia mtiririko wa uandishi unaoendelea au idadi kubwa ya sehemu za watoto. Kwa mfano, unaweza kukumbuka kuwa algorithm ya kuchagua sehemu inayohitajika ilikuwa nayo utata wa quadratic, kwamba inafanya kazi na sehemu 100+, wewe mwenyewe unaelewa jinsi ...

Katika PG10 hali hii iliboreshwa sana kwa kutekeleza usaidizi ugawaji wa asili. Kwa hiyo, mara moja tulijaribu kuitumia mara baada ya kuhamia hifadhi, lakini ...

Kama ilivyotokea baada ya kuchimba mwongozo, jedwali lililogawanywa asili katika toleo hili ni:

  • haiauni maelezo ya faharasa
  • haiauni vichochezi juu yake
  • hawezi kuwa "mzao" wa mtu yeyote
  • usiunge mkono INSERT ... ON CONFLICT
  • haiwezi kutoa sehemu kiotomatiki

Baada ya kupokea pigo la uchungu kwenye paji la uso na reki, tuligundua kuwa haitawezekana kufanya bila kurekebisha ombi, na kuahirisha utafiti zaidi kwa miezi sita.

PG10: nafasi ya pili

Kwa hivyo, tulianza kutatua shida zilizotokea moja baada ya nyingine:

  1. Kwa sababu vichochezi na ON CONFLICT Tuligundua kuwa bado tulizihitaji hapa na pale, kwa hivyo tukatengeneza hatua ya kati kuzifanyia kazi meza ya wakala.
  2. Achana na "routing" katika vichochezi - yaani, kutoka EXECUTE.
  3. Waliitoa kando jedwali la kiolezo na faharisi zoteili hata zisiwepo kwenye jedwali la wakala.

Tunaandika katika PostgreSQL kwenye sublight: mwenyeji 1, siku 1, 1TB
Mwishowe, baada ya haya yote, tuligawanya meza kuu asili. Uundaji wa sehemu mpya bado umeachwa kwa dhamiri ya maombi.

Kamusi za "Sawing".

Kama ilivyo katika mfumo wowote wa uchambuzi, pia tulikuwa nayo "ukweli" na "kupunguzwa" (kamusi). Kwa upande wetu, kwa nafasi hii walitenda, kwa mfano, mwili wa template maswali ya polepole sawa au maandishi ya hoja yenyewe.

"Ukweli" uliwekwa kwa siku kwa muda mrefu tayari, kwa hivyo tulifuta kwa utulivu sehemu za zamani, na hazikutusumbua (magogo!). Lakini kulikuwa na shida na kamusi ...

Sio kusema kwamba kulikuwa na mengi yao, lakini takriban TB 100 ya "ukweli" ilisababisha kamusi ya 2.5TB. Hauwezi kufuta chochote kutoka kwa meza kama hiyo kwa urahisi, huwezi kuibana kwa wakati wa kutosha, na kuiandikia polepole ikawa polepole.

Kama kamusi... ndani yake, kila ingizo linapaswa kuwasilishwa mara moja tu... na hii ni sahihi, lakini!.. Hakuna anayetuzuia kuwa na kamusi tofauti kwa kila siku! Ndio, hii inaleta upungufu fulani, lakini inaruhusu:

  • andika/soma haraka kwa sababu ya ukubwa wa sehemu ndogo
  • hutumia kumbukumbu kidogo kwa kufanya kazi na faharisi za kompakt zaidi
  • kuhifadhi data kidogo kutokana na uwezo wa kuondoa haraka kizamani

Kama matokeo ya tata nzima ya hatua Upakiaji wa CPU ulipungua kwa ~ 30%, upakiaji wa diski kwa ~ 50%:

Tunaandika katika PostgreSQL kwenye sublight: mwenyeji 1, siku 1, 1TB
Wakati huo huo, tuliendelea kuandika kitu sawa kwenye hifadhidata, tukiwa na mzigo mdogo.

#2. Mageuzi ya hifadhidata na urekebishaji upya

Kwa hivyo tulitulia kwa kile tulichonacho kila siku ina sehemu yake na data. Kweli, CHECK (dt = '2018-10-12'::date) - na kuna ufunguo wa kugawa na hali ya rekodi kuanguka katika sehemu maalum.

Kwa kuwa ripoti zote katika huduma yetu zimeundwa katika muktadha wa tarehe mahususi, faharasa zake kwa kuwa "nyakati zisizo na mgawanyiko" zimekuwa za aina zote. (Seva, tarehe, Kiolezo cha Mpango), (Seva, tarehe, Mpango wa nodi), (tarehe, darasa la makosa, Seva), ...

Lakini sasa wanaishi kila sehemu nakala zako kila index vile... Na ndani ya kila sehemu tarehe ni ya kudumu... Inageuka kuwa sasa tuko katika kila index hiyo tu kuingia mara kwa mara kama moja ya uwanja, ambayo huongeza kiwango chake na wakati wa utaftaji, lakini haileti matokeo yoyote. Walijiachia mkwanja, lo...

Tunaandika katika PostgreSQL kwenye sublight: mwenyeji 1, siku 1, 1TB
Mwelekeo wa optimization ni dhahiri - rahisi ondoa uga wa tarehe kutoka kwa faharisi zote kwenye meza zilizogawanywa. Kwa kuzingatia wingi wetu, faida ni karibu 1TB/wiki!

Sasa hebu tukumbuke kwamba terabyte hii bado ilipaswa kurekodi kwa namna fulani. Hiyo ni, sisi pia diski inapaswa sasa kupakia kidogo! Picha hii inaonyesha wazi athari iliyopatikana kutoka kwa kusafisha, ambayo tulijitolea kwa wiki:

Tunaandika katika PostgreSQL kwenye sublight: mwenyeji 1, siku 1, 1TB

#3. "Kueneza" mzigo wa kilele

Moja ya shida kubwa za mifumo iliyopakiwa ni maingiliano yasiyo ya lazima shughuli zingine ambazo haziitaji. Wakati mwingine "kwa sababu hawakuona", wakati mwingine "ilikuwa rahisi kwa njia hiyo", lakini mapema au baadaye unapaswa kuiondoa.

Hebu tuzame kwenye picha iliyotangulia na tuone kwamba tunayo diski "pampu" chini ya mzigo na amplitude mbili kati ya sampuli za karibu, ambazo kwa uwazi "kitakwimu" hazipaswi kutokea na idadi ya shughuli kama hizi:

Tunaandika katika PostgreSQL kwenye sublight: mwenyeji 1, siku 1, 1TB

Hii ni rahisi sana kufikia. Tayari tumeanza ufuatiliaji karibu seva 1000, kila moja inachakatwa na uzi tofauti wa kimantiki, na kila uzi huweka upya habari iliyokusanywa kutumwa kwa hifadhidata kwa masafa fulani, kitu kama hiki:

setInterval(sendToDB, interval)

Tatizo hapa liko katika ukweli kwamba nyuzi zote huanza takriban kwa wakati mmoja, kwa hiyo nyakati zao za kutuma karibu sikuzote zinapatana β€œkwa uhakika.” Lo #2...

Kwa bahati nzuri, hii ni rahisi sana kurekebisha, kuongeza uendelezaji wa "nasibu". kwa wakati:

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

#4. Tunahifadhi kile tunachohitaji

Tatizo la tatu la upakiaji wa jadi ni hakuna akiba yuko wapi inaweza kuwa.

Kwa mfano, tulifanya iwezekane kuchambua kulingana na nodi za mpango (yote haya Seq Scan on users), lakini mara moja fikiria kwamba wao ni, kwa sehemu kubwa, sawa - wamesahau.

Hapana, kwa kweli, hakuna kitu kilichoandikwa kwa hifadhidata tena, hii inakata kichochezi INSERT ... ON CONFLICT DO NOTHING. Lakini data hii bado inafikia hifadhidata, na sio lazima kusoma ili kuangalia migogoro kufanya. Lo #3...

Tofauti katika idadi ya rekodi zilizotumwa kwenye hifadhidata kabla/baada ya kuweka akiba kuwezeshwa ni dhahiri:

Tunaandika katika PostgreSQL kwenye sublight: mwenyeji 1, siku 1, 1TB

Na hii ndio kushuka kuandamana kwa mzigo wa uhifadhi:

Tunaandika katika PostgreSQL kwenye sublight: mwenyeji 1, siku 1, 1TB

Katika jumla ya

"Terabyte-per-siku" inaonekana tu ya kutisha. Ikiwa unafanya kila kitu sawa, basi hii ni haki 2^40 baiti / sekunde 86400 = ~12.5MB/skwamba hata skrubu za IDE za eneo-kazi zilishikiliwa. πŸ™‚

Lakini kwa uzito, hata kwa "skew" mara kumi ya mzigo wakati wa mchana, unaweza kufikia urahisi uwezo wa SSD za kisasa.

Tunaandika katika PostgreSQL kwenye sublight: mwenyeji 1, siku 1, 1TB

Chanzo: mapenzi.com

Kuongeza maoni