Em di PostgreSQL de li ser ronahiyê dinivîsin: 1 mêvandar, 1 roj, 1TB

Di van demên dawî de min ji we re got ku çawa, bi karanîna reçeteyên standard performansa pirsên xwendina SQL zêde bikin ji databasa PostgreSQL. Îro em ê li ser çawa biaxivin tomarkirin dikare bi bandortir were kirin di databasê de bêyî ku di mîhengê de tu "tewandin" bikar bîne - bi tenê bi rêkûpêk organîzekirina herikîna daneyan.

Em di PostgreSQL de li ser ronahiyê dinivîsin: 1 mêvandar, 1 roj, 1TB

#1. Beşkirin

Gotarek li ser çawa û çima ew hêjayî organîzekirinê ye dabeşkirina sepandin "di teoriyê de" berê bûye, li vir em ê behsa pratîka pêkanîna hin nêzîkatiyên di nava xwe de bikin karûbarê çavdêriyê ji bo bi sedan serverên PostgreSQL.

"Tiştên rojên derbasbûyî..."

Di destpêkê de, mîna her MVP-ê, projeya me di bin barek pir sivik de dest pê kir - çavdêrî tenê ji bo deh serverên herî krîtîk hate kirin, hemî tablo bi nisbeten tevlihev bûn... Lê her ku diçû, hejmara mêvandarên çavdêrîkirî her ku çû zêdetir bû. , û careke din me hewl da ku bi yek ji wan re tiştek bikin maseyên 1.5TB li size, me fêhm kir ku her çendî mimkûn bû ku bi vî rengî jiyana xwe bidomînin jî, ew pir nerehet bû.

Dem hema hema mîna demên epîk bûn, guhertoyên cihêreng ên PostgreSQL 9.x têkildar bûn, ji ber vê yekê pêdivî bû ku hemî dabeşkirin "bi destan" were kirin - bi riya mîrasê sifrê û tetikan rêveçûna bi dînamîk EXECUTE.

Em di PostgreSQL de li ser ronahiyê dinivîsin: 1 mêvandar, 1 roj, 1TB
Çareseriya encam bi têra xwe gerdûnî derket ku ew dikare li hemî tabloyan were wergerandin:

  • Tabloyek dêûbavê "serî" ya vala hate ragihandin, ku hemî diyar kir îndeks û pêlên pêwîst.
  • Qeyd ji nêrîna xerîdar di tabloya "root" de û di hundurê de hate bikar anîn tetikê rêvekirinê BEFORE INSERT qeyda "fizîkî" hate nav beşa pêwîst. Heger tiştekî wisa nebûya, me îstisnayek girt û...
  • … bi karanîna CREATE TABLE ... (LIKE ... INCLUDING ...) li ser bingeha şablonê tabloya dêûbav hate afirandin beşa bi sînordarkirina li ser date xwestinda ku dema ku dane têne wergirtin, xwendin tenê tê de tê kirin.

PG10: hewldana yekem

Lê dabeşkirina bi mîratê ji hêla dîrokî ve ji bo mijûlbûna bi rêkûpêk nivîsandina çalak an hejmareke mezin a dabeşkirina zarokan re ne xweş e. Mînakî, hûn dikarin bînin bîra xwe ku algorîtmaya hilbijartina beşa pêwîst hebû tevliheviya çargoşe, ku ew bi 100+ beşan re dixebite, hûn bixwe fam dikin ka çawa ...

Di PG10 de ev rewş bi pêkanîna piştgirîyê pir xweştir bû dabeşkirina xwecî. Ji ber vê yekê, me tavilê hewl da ku wê tavilê piştî koçkirina hilanînê bicîh bikin, lê ...

Wekî ku piştî kolandina manualê derket holê, di vê guhertoyê de tabloya dabeşkirî ya xwemalî ev e:

  • ravekirinên indexê piştgirî nake
  • li ser wê destek nake
  • nikare bibe "nifşê" kesî
  • piştgirî nakin INSERT ... ON CONFLICT
  • nikare beşek bixweber çêbike

Ji ber ku me derbeyek bi êş ji eniya xwe re bi kulmek girt, me fêm kir ku bêyî guheztina serîlêdanê ne gengaz e ku meriv bike, û lêkolîna din şeş mehan paşxist.

PG10: şansê duyemîn

Ji ber vê yekê, me dest pê kir ku pirsgirêkên ku derketin yek bi yek çareser bikin:

  1. Ji ber ku dibe sedema û ON CONFLICT Me dît ku em hîn jî li vir û wir hewceyê wan in, ji ber vê yekê me qonaxek navber çêkir da ku wan bixebitin tabloya proxy.
  2. Ji "rêxistinê" xilas bû di tetikan de - ango ji EXECUTE.
  3. Ew ji hev cuda derxistin sifrê şablonê bi hemû indexda ku ew di tabloya proxy de jî nebin.

Em di PostgreSQL de li ser ronahiyê dinivîsin: 1 mêvandar, 1 roj, 1TB
Di dawiyê de, piştî van hemûyan, me tabloya sereke bi xwemalî dabeş kir. Çêkirina beşa nû hê jî ji wijdanê sepanê re maye.

Ferhengên “Sawing”.

Weke her sîstemeke analîtîk, me jî hebû "rastî" û "birîn" (ferheng). Di rewşa me de, di vê kapasîteyê de wan tevdigerin, mînakî, bedena şablonê pirsên hêdî hêdî an jî nivîsa pirsê bixwe.

"Rastî" ji bo demek dirêj ve roj bi roj dihatin beş kirin, ji ber vê yekê me bi aramî beşên kevnar jêbirin, û wan me aciz nekir (têketin!). Lê di ferhengan de pirsgirêkek hebû...

Nabêje ku gelek ji wan hebûn, lê bi qasî 100TB ji "rastiyan" di ferhengeke 2.5TB de derket. Hûn nekarin bi rehetî tiştek ji tabloyek weha jêbikin, hûn nikaribin di wextê têrker de biqelînin, û nivîsandina li ser wê gav bi gav hêdîtir bû.

Weke ferhengekê... tê de, divê her navnîşek tam carekê were pêşkêş kirin... û ev rast e, lê!.. Tu kes rê li ber me nagire. ji bo her rojê ferhengek cuda! Erê, ev hin zêdebûnek tîne, lê destûrê dide:

  • zûtir binivîsin/xwendin ji ber mezinahiya beşa piçûktir
  • bîra kêm dixwe bi xebata bi indexên kompakttir re
  • kêm daneyan hilîne ji ber kapasîteya zû rakirina kevnar

Di encama tevahiya tevliheviya tedbîran de Barkirina CPU ~ 30%, barkirina dîskê ~ 50% kêm bû:

Em di PostgreSQL de li ser ronahiyê dinivîsin: 1 mêvandar, 1 roj, 1TB
Di heman demê de, me nivîsandina tam heman tişt di databasê de, tenê bi barkirina kêmtir berdewam kir.

#2. Pêşveçûn û vesazkirina databasê

Ji ber vê yekê em li ser tiştên ku di destê me de rûniştin her roj beşa xwe heye bi daneyan. Birastî, CHECK (dt = '2018-10-12'::date) - û mifteyek dabeşkirinê heye û şertê ku tomarek bikeve nav beşek taybetî.

Ji ber ku hemî raporên di karûbarê me de di çarçoveyek tarîxek taybetî de têne çêkirin, navnîşên wan ji "demên ne-parvekirî" ve hemî celeb in. (Server, Dîrok, Şablon Plan), (Server, Dîrok, girêka planê), (Dîrok, Çîna çewtiyê, Pêşkêşkar)...

Lê niha ew li ser her beşê dijîn kopiyên te her weha index... Û di nav her beşê de date berdewam e... Derdiket ku niha em di her indexek weha de ne bi tenê bikevin a berdewam wekî yek ji qadan, ku hem qebareya xwe û hem jî dema lêgerîna wê zêde dike, lê ti encam dernakeve. Rak ji xwe re hiştin, wey...

Em di PostgreSQL de li ser ronahiyê dinivîsin: 1 mêvandar, 1 roj, 1TB
Rêwîtiya xweşbîniyê diyar e - hêsan qada tarîxê ji hemî navnîşan derxe li ser maseyên dabeşkirî. Li gorî cildên me, qezenc li ser e 1 TB / hefte!

Naha em bala xwe bidinê ku ev terabyte hîn jî diviyabû ku bi rengekî were tomar kirin. Yanî em jî divê dîsk êdî kêmtir bar bike! Ev wêne bi zelalî bandora ku ji paqijkirina ku me hefteyek terxan kir, destnîşan dike:

Em di PostgreSQL de li ser ronahiyê dinivîsin: 1 mêvandar, 1 roj, 1TB

#3. "Belavkirina" barê lûtkeyê

Yek ji pirsgirêkên mezin ên pergalên barkirî ye hevdemkirina zêde hin operasyonên ku ne hewce ne. Carinan "ji ber ku wan ferq nekir", carinan "bi vî rengî hêsantir bû", lê zû an dereng divê hûn jê xilas bibin.

Ka em li ser wêneyê berê zoom bikin û bibînin ku dîskek me heye "pompe" di bin barkirinê de bi amplitude du qat di navbera nimûneyên cîran de, ku bi eşkere "îstatîstîkî" divê bi hejmarek operasyonan re çênebe:

Em di PostgreSQL de li ser ronahiyê dinivîsin: 1 mêvandar, 1 roj, 1TB

Ev pir hêsan e ku meriv bigihîje. Jixwe me dest bi şopandinê kiriye hema hema 1000 server, her yek ji hêla mijarek mentiqî ya cihê ve tê hilanîn, û her mijar agahdariya berhevkirî ji nû ve vedigire ku ji databasê re bi frekansek diyarkirî re were şandin, tiştek mîna vê:

setInterval(sendToDB, interval)

Pirsgirêka li vir tam di vê rastiyê de ye hemî mijar hema hema di heman demê de dest pê dikin, ji ber vê yekê demên şandina wan hema hema her gav "ji bo xalê" hevûdu ne. Oops #2...

Xweşbextane, ev yek pir hêsan e ku meriv rast bike, lêzêdekirina "random" run-up bi demê:

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

#4. Tiştê ku ji me re lazim e em cache dikin

Pirsgirêka bilindkirina kevneşopî ya sêyemîn e no cache ew li ku ye dikaribû be.

Mînakî, me îmkan da ku em di warê girêkên plansaziyê de analîz bikin (van hemî Seq Scan on users), lê tavilê difikirin ku ew, bi piranî, yek in - wan ji bîr kir.

Na, bê guman, dîsa tiştek ji databasê re nayê nivîsandin, ev bi tetikê qut dike INSERT ... ON CONFLICT DO NOTHING. Lê ev dane hîn jî digihîje databasê, û ew nepêwist e xwendin ji bo pevçûnê kontrol bikin divê bikin. Oops #3...

Cûdahiya di hejmara tomarên ku ji databasê re hatine şandin berî/piştî ku cachkirinê were çalak kirin eşkere ye:

Em di PostgreSQL de li ser ronahiyê dinivîsin: 1 mêvandar, 1 roj, 1TB

Û ev daketina pêvek a barkirina hilanînê ye:

Em di PostgreSQL de li ser ronahiyê dinivîsin: 1 mêvandar, 1 roj, 1TB

Tevahî

"Terabyte-per-day" tenê tirsnak xuya dike. Ger hûn her tiştî rast bikin, wê hingê ev tenê ye 2^40 bytes / 86400 çirke = ~ 12.5 MB/sku tewra pêlên IDE yên sermaseyê jî girtin. 🙂

Lê bi ciddî, ​​di nav rojê de bi deh qat "skew" jî, hûn dikarin bi hêsanî kapasîteyên SSD-yên nûjen bibînin.

Em di PostgreSQL de li ser ronahiyê dinivîsin: 1 mêvandar, 1 roj, 1TB

Source: www.habr.com

Add a comment