PostgreSQL-n idazten dugu azpiargia: 1 host, 1 day, 1TB

Duela gutxi kontatu dizut nola, errezeta estandarrak erabiliz SQL irakurketa kontsulten errendimendua handitu PostgreSQL datu-basetik. Gaur nola hitz egingo dugu grabaketa modu eraginkorragoan egin daiteke datu-basean konfigurazioan "bira"rik erabili gabe, datu-fluxuak behar bezala antolatuz.

PostgreSQL-n idazten dugu azpiargia: 1 host, 1 day, 1TB

#1. Sekzioa

Nola eta zergatik merezi duen antolatzeari buruzko artikulu bat zatiketa aplikatua "teorian" dagoeneko izan da, hemen gure barnean planteamendu batzuk aplikatzeko praktikari buruz hitz egingo dugu ehunka PostgreSQL zerbitzariren jarraipen-zerbitzua.

"Garai bateko gauzak..."

Hasieran, edozein MVP bezala, gure proiektua nahiko karga arinean hasi zen - monitorizazioa hamar zerbitzari kritikoenentzat bakarrik egiten zen, mahai guztiak nahiko trinkoak ziren... Baina denborak aurrera egin ahala, monitorizatutako ostalarien kopurua gero eta handiagoa zen. , eta beste behin saiatu ginen zerbait egiten batekin 1.5TBko taulak, konturatu ginen horrela bizitzen jarraitzea posible bazen ere, oso deserosoa zela.

Garaiak ia garai epikoak bezalakoak ziren, PostgreSQL 9.x-en bertsio desberdinak garrantzitsuak ziren, beraz, partizio guztiak "eskuz" egin behar ziren - bidez. taularen herentzia eta abiarazleak bideratzea dinamikoarekin EXECUTE.

PostgreSQL-n idazten dugu azpiargia: 1 host, 1 day, 1TB
Lortutako irtenbidea nahikoa unibertsala izan zen, taula guztietara itzultzeko:

  • "Goiburua" mahai nagusi huts bat deklaratu zen, guztiak deskribatzen zituena beharrezko indizeak eta abiarazleak.
  • Erregistroa bezeroaren ikuspuntutik β€œroot” taulan egin zen, eta barrutik erabiliz bideratze abiarazlea BEFORE INSERT erregistroa β€œfisikoki” txertatu zen eskatutako atalean. Oraindik halakorik ez bazegoen, salbuespen bat harrapatu genuen eta...
  • … erabiliz CREATE TABLE ... (LIKE ... INCLUDING ...) guraso-taularen txantiloian oinarrituta sortu da atala nahi den dataren mugarekinberaz, datuak berreskuratzen direnean, irakurketa bertan bakarrik egiten da.

PG10: lehen saiakera

Baina herentzia bidezko partizioa ez da historikoki egokia izan idazketa korronte aktibo bati edo seme-alaba partizio kopuru handi bati aurre egiteko. Esaterako, gogoratu dezakezu eskatutako atala hautatzeko algoritmoak zuela konplexutasun koadratikoa, 100 atal baino gehiagorekin funtzionatzen duela, zuk zeuk ulertzen duzu nola...

PG10ean egoera hori asko optimizatu zen euskarria ezarriz jatorrizko zatiketa. Hori dela eta, biltegiratzea migratu ondoren berehala aplikatzen saiatu ginen, baina...

Eskuliburuan arakatu ondoren atera den bezala, bertsio honetako jatorrizko zatitutako taula hau da:

  • ez ditu indizeen deskribapenak onartzen
  • ez du abiarazlerik onartzen
  • ezin da inoren "ondorengoa" izan
  • ez onartzen INSERT ... ON CONFLICT
  • ezin da atal bat automatikoki sortu

Kokokian kolpe mingarria jasota arrastelarekin, aplikazioa aldatu gabe ezinezkoa izango zela konturatu ginen eta sei hilabetez atzeratu genuen ikerketa gehiago.

PG10: bigarren aukera

Beraz, banan-banan sortutako arazoak konpontzen hasi ginen:

  1. Abiarazleak eta ON CONFLICT Han-hemenka oraindik behar genituela ikusi genuen, beraz, tarteko etapa bat egin genuen lantzeko proxy taula.
  2. "bideratzea" kendu dut abiarazleetan - hau da, batetik EXECUTE.
  3. Bereiz atera zuten txantiloi-taula indize guztiekinproxy taulan ere ez egon daitezen.

PostgreSQL-n idazten dugu azpiargia: 1 host, 1 day, 1TB
Azkenik, hau guztiaren ondoren, mahai nagusia modu natiboan banatu dugu. Atal berri bat sortzea oraindik aplikazioaren kontzientziaren esku geratzen da.

"Zerratu" hiztegiak

Edozein sistema analitikotan bezala, guk ere izan genuen "gertakariak" eta "mozketak" (hiztegiak). Gure kasuan, kargu horretan jardun zuten, adibidez, txantiloiaren gorputza antzeko kontsulta motelak edo kontsultaren testua bera.

"Gertaerak" egunez sekzionatuta zeuden jadanik, beraz, lasai ezabatu genituen atal zaharkituak, eta ez gintuzten molestatzen (erregistroak!). Baina arazo bat zegoen hiztegiekin...

Asko zirenik ez, gutxi gorabehera, baizik 100TB "gertaerak" 2.5TB hiztegia lortu zuen. Ezin duzu horrelako taula batetik ezer ezabatu, ezin duzu denbora egokian konprimitu eta pixkanaka idaztea moteldu egin zen.

Hiztegi bat bezala... bertan, sarrera bakoitza zehatz-mehatz behin aurkeztu behar da... eta hau zuzena da, baina!... Inork ez digu edukitzea eragozten. egun bakoitzeko hiztegi bereizia! Bai, honek nolabaiteko erredundantzia dakar, baina aukera ematen du:

  • idatzi/irakurtu azkarrago atalaren tamaina txikiagoa dela eta
  • memoria gutxiago kontsumitu indize trinkoagoekin lan eginez
  • datu gutxiago gordetzea zaharkitua azkar kentzeko gaitasuna dela eta

Neurri-multzo osoaren ondorioz CPUaren karga % 30 gutxitu da, eta % 50 diskoaren karga:

PostgreSQL-n idazten dugu azpiargia: 1 host, 1 day, 1TB
Aldi berean, datu-basean gauza bera idazten jarraitu genuen, karga gutxiagorekin.

#2. Datu-basearen bilakaera eta birfactorizazioa

Beraz, daukagunarekin finkatu ginen egun bakoitzak bere atala du datuekin. Egia esan, CHECK (dt = '2018-10-12'::date) β€” eta zatiketa-gako bat dago eta erregistro bat atal zehatz batean erortzeko baldintza dago.

Gure zerbitzuko txosten guztiak data zehatz baten testuinguruan eraikitzen direnez, "zatiketarik gabeko garai"-tik hona horien indizeak mota guztietakoak izan dira. (Zerbitzaria, Data, Plan txantiloia), (Zerbitzaria, Data, Plan nodoa), (Data, Error klasea, Zerbitzaria), ...

Baina orain atal guztietan bizi dira zure kopiak halako indize bakoitza... Eta atal bakoitzaren barruan data konstante bat da... Bihurtzen da orain indize bakoitzean gaudela konstante bat sartu besterik ez eremuetako bat bezala, bere bolumena eta bilaketa-denbora handitzen dituena, baina ez du inolako emaitzarik ekartzen. Beraiek utzi zuten arrastoa, aupa...

PostgreSQL-n idazten dugu azpiargia: 1 host, 1 day, 1TB
Optimizazioaren norabidea bistakoa da - sinplea kendu data eremua indize guztietatik zatitutako mahaietan. Gure bolumenak kontuan hartuta, irabazia ingurukoa da 1TB/astean!

Orain kontuan izan dezagun terabyte hori oraindik nolabait grabatu behar zela. Hau da, guk ere orain diskoak gutxiago kargatu beharko luke! Irudi honek garbi erakusten du aste bat eskaini genion garbiketaren ondorioz lortutako eragina:

PostgreSQL-n idazten dugu azpiargia: 1 host, 1 day, 1TB

#3. Zama gailurra "zabaltzea".

Kargatutako sistemen arazo handietako bat da sinkronizazio erredundantea eskatzen ez duten eragiketa batzuk. Batzuetan β€œohartu ez zirelako”, beste batzuetan β€œerrazagoa zen horrela”, baina lehenago edo beranduago kendu egin behar duzu.

Handitu dezagun aurreko argazkia eta ikus dezagun disko bat dugula "ponpak" karga azpian anplitude bikoitzarekin ondoko laginen artean, argi eta garbi "estatistikoki" ez litzatekeela gertatu behar horrelako eragiketekin:

PostgreSQL-n idazten dugu azpiargia: 1 host, 1 day, 1TB

Hau lortzea nahiko erraza da. Dagoeneko jarraipena egiten hasi gara ia 1000 zerbitzari, bakoitza hari logiko batek prozesatzen du, eta hari bakoitzak maiztasun jakin batean datu-basera bidali beharreko metatutako informazioa berrezartzen du, honelako zerbait:

setInterval(sendToDB, interval)

Hemen arazoa hain zuzen ere horretan datza hari guztiak gutxi gorabehera aldi berean hasten dira, beraz, bidaltzeko denborak ia beti bat datoz "punturaino". Aupa #2...

Zorionez, hau nahiko erraza da konpontzen, "ausazko" igoera bat gehituz denboraren arabera:

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

#4. Behar duguna gordetzen dugu

Karga handiko hirugarren arazo tradizionala da cacherik ez non dagoen liteke izan.

Adibidez, plan-nodoen arabera aztertzea posible egin dugu (horiek guztiak Seq Scan on users), baina berehala pentsatu, gehienetan, berdinak direla - ahaztu egin ziren.

Ez, noski, ez da ezer idazten datu-basean berriro, honek abiarazlea mozten du INSERT ... ON CONFLICT DO NOTHING. Baina datu hauek datu-basera iristen dira oraindik, eta ez dira beharrezkoak irakurtzea gatazkak egiaztatzeko egin behar. Aupa #3...

Cachea gaitu aurretik/ondoren datu-basera bidalitako erregistro-kopuruaren aldea agerikoa da:

PostgreSQL-n idazten dugu azpiargia: 1 host, 1 day, 1TB

Eta hauxe da biltegiratze-kargaren jaitsiera:

PostgreSQL-n idazten dugu azpiargia: 1 host, 1 day, 1TB

Guztira

"Terabyte-per-day"-k beldurra ematen du. Dena ondo egiten baduzu, hau besterik ez da 2^40 byte / 86400 segundo = ~12.5MB/smahaigaineko IDE torlojuak ere eutsita. πŸ™‚

Baina serioski, egunean zehar karga hamar aldiz "okertu" bada ere, SSD modernoen gaitasunak erraz bete ditzakezu.

PostgreSQL-n idazten dugu azpiargia: 1 host, 1 day, 1TB

Iturria: www.habr.com

Gehitu iruzkin berria