Andmete baasi pÀringute optimeerimine B2B teenuse nÀitel ehitajatele

Kuidas kasvatada B2B pĂ€ringute arvu kĂŒmme korda, kolimata jĂ”udsamale serverile ja sĂ€ilitades sĂŒsteemi töövĂ”ime? RÀÀgin, kuidas me vĂ”itlesime andmebaasi jĂ”udluse langusega, kuidas me optimeerisime SQL pĂ€ringud nii, et teenindada vĂ”imalikult palju kasutajaid ja mitte suurendada kulutusi arvutusressurssidele.

Tegelen teenuse loomisega Ă€riprotsesside haldamiseks ehitusettevĂ”tetes. Meiega töötab umbes 3000 ettevĂ”tet. Üle 10 000 inimese töötab igapĂ€evaselt meie sĂŒsteemis 4–10 tundi. See lahendab mitmesuguseid planeerimise, teavitamise, hoiatamise ja valideerimise ĂŒlesandeid... Me kasutame PostgreSQL 9.6. Meie andmebaasis on umbes 300 tabelit ja iga pĂ€ev laekub sinna kuni 200 miljonit pĂ€ringut (10 000 erinevat). Keskmiselt on meil 3–4 tuhat pĂ€ringut sekundis, kĂ”ige aktiivsematel hetkedel ĂŒle 10 000 pĂ€ringu sekundis. Suur osa pĂ€ringutest on OLAP. Lisamised, muutmised ja kustutused on oluliselt vĂ€hem, seega OLTP koormus on suhteliselt vĂ€ike. KĂ”iki neid numbreid tĂ”in vĂ€lja, et saaksite hinnata meie projekti ulatust ja mĂ”ista, kui vÀÀrtuslik meie kogemus teie jaoks vĂ”iks olla.

Esimene pilt. LÀÀneline

Kui me arendust alustasime, ei mĂ”elnud me eriti sellele, milline koormus langeb andmebaasile ja mida me teeme, kui server enam ei jaksaks. Andmebaasi projekteerimisel jĂ€rgnesime ĂŒldistele soovitustele ja pĂŒĂŒdsime mitte endale jalga tulistada, kuid ei lĂ€inud kaugemale ĂŒldistest nĂ”uannetest nagu "Ă€rge kasutage mustrit Entity Attribute Values ," millega me ei olnud tuttavad. Projekteerisime normeerimise pĂ”himĂ”tetest lĂ€htuvalt, vĂ€ltides andmete liigset kopeerimist, ja ei tundnud muret erinevate pĂ€ringute kiirususe pĂ€rast. Kui esimesed kasutajad ilmusid, seisime silmitsi jĂ”udlusprobleemidega. Nagu tavaliselt, olime selleks tĂ€iesti ette valmistamata. Esimesed probleemid olid lihtsad. KĂ”ik lahendati tavaliselt uue indeksi lisamisega. Kuid jĂ”udis hetk, mil lihtsad lahendused enam ei töötanud. Teades, et meie kogemus ei ole piisav ja meil on ĂŒha keerulisem aru saada, mis probleemide pĂ”hjuseks on, palkasime spetsialiste, kes aitasid meil serverit Ă”igesti seadistada, ĂŒhendada jĂ€lgimisega ja nĂ€itasid meile, kuhu vaadata, et saada statistikat.

Teine pilt. Statistiline

Nii et meil on umbes 10 000 erinevat pÀringut, mis tÀidetakse meie andmebaasis ööpÀevas. Nendest 10 000 on koletised, mis tÀidetakse 2-3 miljonit korda keskmise tÀitmisajaga 0,1-0,3 ms, ja on pÀringud, mille keskmine tÀitmise aeg on 30 sekundit, mida kutsutakse 100 korda pÀevas.

Kuna ei olnud vĂ”imalik optimeerida kĂ”iki 10 000 pĂ€ringut, otsustasime mĂ”ista, kuhu suunata oma jĂ”upingutusi, et tĂ”sta andmebaasi jĂ”udlust Ă”igesti. PĂ€rast mitu iteratsiooni hakkasime pĂ€ringud liigitama tĂŒĂŒpideks.

TOP pÀringud

Need on kĂ”ige raskemad pĂ€ringud, mis vĂ”tavad kĂ”ige rohkem aega (kokku aega). Need on pĂ€ringud, mida kas kutsutakse vĂ€ga sageli vĂ”i pĂ€ringud, mis tĂ€idetakse vĂ€ga kaua (pikad ja sagedased pĂ€ringud on optimeeritud juba varasemates iteratsioonides kiirusvĂ”itluses). LĂ”ppkokkuvĂ”ttes kulutab server nende tĂ€itmiseks kĂ”ige rohkem aega. Samuti on oluline eristada tipupĂ€ringud ĂŒldise tĂ€itmise ajaga ja eraldi IO ajaga. Nende pĂ€ringute optimeerimise viisid on veidi erinevad.

Tavaline praktika kĂ”igis ettevĂ”tetes on töötada TOP pĂ€ringutega. Neid on vĂ€he, ĂŒhegi pĂ€ringu optimeerimine vĂ”ib vabastada 5-10% ressursse. Kuid projekti „kasvades” muutub TOP pĂ€ringute optimeerimine ĂŒha keerulisemaks. KĂ”ik lihtsad meetodid on juba rakendatud ning isegi kĂ”ige „raske” pĂ€ring vĂ”tab „vaid” 3-5% ressursse. Kui TOP pĂ€ringud kokku vĂ”tavad alla 30-40% ajast, siis tĂ”enĂ€oliselt olete juba teinud jĂ”upingutusi, et need töötaksid kiirelt, ja on aeg liikuda jĂ€rgmise grupi pĂ€ringute optimeerimise juurde.
JÀÀb vastata kĂŒsimusele, kui palju ĂŒlemisi pĂ€ringuid sellesse gruppi lisada. Ma tavaliselt vĂ”taksin mitte vĂ€hem kui 10, kuid mitte rohkem kui 20. PĂŒĂŒan tagada, et TOP grupi esimese ja viimase tĂ€itmise aeg ei erine rohkem kui 10 korda. See tĂ€hendab, et kui pĂ€ringute tĂ€itmise aeg langeb jĂ€rsult 1. kohalt 10. kohale, vĂ”tan TOP-10, kui langus on sujuvam, siis suurendan grupi suurust 15 vĂ”i 20-ni.
Andmete baasi pÀringute optimeerimine B2B teenuse nÀitel ehitajatele

Keskmikud (medium)

Need on kĂ”ik pĂ€ringud, mis tulevad kohe pĂ€rast TOP-i, vĂ€lja arvatud viimased 5-10%. Tavalise optimeerimise puhul seisneb just nende pĂ€ringute juures vĂ”imalus oluliselt tĂ”sta serveri jĂ”udlust. Need pĂ€ringud vĂ”ivad „kaaluda” kuni 80%. Kuid isegi kui nende osakaal ĂŒletab 50%, on aeg vaadata neile lĂ€hemalt.

Saba (tail)

Nagu öeldud, tulevad need pĂ€ringud lĂ”pus ja nendele kulub 5-10% ajast. Neist vĂ”ib unustada, kui te ei kasuta automaatseid analĂŒĂŒsivahendeid, siis vĂ”ib nende optimeerimine samuti olla odav.

Kuidas hinnata iga gruppi?

Kasutame SQL-pĂ€ringut, mis aitab sellist hinnaandmist teha PostgreSQL jaoks (olen kindel, et paljude teiste andmebaasisĂŒsteemide jaoks saab kirjutada sarnase pĂ€ringu).

SQL-pÀring TOP-MEDIUM-TAIL gruppide suuruse hindamiseks.

SELECT sum(time_top) AS sum_top, sum(time_medium) AS sum_medium, sum(time_tail) AS sum_tail
FROM
(
  SELECT CASE WHEN rn  20 AND rn  800              THEN tt_percent ELSE 0 END AS time_tail
  FROM (
    SELECT total_time / (SELECT sum(total_time) FROM pg_stat_statements) * 100 AS tt_percent, query,
    ROW_NUMBER () OVER (ORDER BY total_time DESC) AS rn
    FROM pg_stat_statements
    ORDER BY total_time DESC
  ) AS t
)
AS ts

PĂ€ringu tulemus – kolm veergu, millest igaĂŒks sisaldab protsent aega, mis kulub selle grupi pĂ€ringute töötlemiseks. PĂ€ringu sees on kaks numbrit (minu puhul need on 20 ja 800), mis eraldavad grupi ĂŒhte tĂŒĂŒpi pĂ€ringud teistest.

Nii seondub pÀringute osakaal optimeerimise algusaegadel ja praegu.

Andmete baasi pÀringute optimeerimine B2B teenuse nÀitel ehitajatele

Diagrammist on nĂ€ha, et TOP pĂ€ringute osakaal on jĂ€rsult vĂ€henenud, aga “keskmike” osakaal on suurenenud.
Alguses tĂ”id TOP pĂ€ringud sisse ilmseid vigu. Aja jooksul kadusid lapsehaigused, TOP pĂ€ringute osakaal vĂ€henes, tuli pingutada ĂŒha rohkem, et aeglaseid pĂ€ringuid kiirendada.

PÀringute tekstide saamiseks kasutame jÀrgmist pÀringut.

SELECT * FROM (
  SELECT ROW_NUMBER () OVER (ORDER BY total_time DESC) AS rn, total_time / (SELECT sum(total_time) FROM pg_stat_statements) * 100 AS tt_percent, query
  FROM pg_stat_statements
  ORDER BY total_time DESC
) AS T
WHERE
rn  20 AND rn  800  -- TAIL

Siin on loetelu kÔige sagedamini kasutatud meetoditest, mis aitasid meil kiirendada TOP pÀringuid:

  • SĂŒsteemi ĂŒmberkujundamine, nĂ€iteks teate loogika ĂŒmbersuunamine sĂ”numite vahendajale perioodiliste pĂ€ringute asemel andmebaasi.
  • Indeksite lisamine vĂ”i muutmine.
  • ORM pĂ€ringute ĂŒmberkirjutamine puhtaks SQL-iks.
  • Laise andmete laadimise loogika ĂŒmberkirjutamine.
  • KĂŒpsetamine lĂ€bi andmete denormaliseerimise. NĂ€iteks on meil seos tabelite Transport -> Arve -> PĂ€ring -> Taotlus. Iga transport on seotud taotlusega teiste tabelite kaudu. Et mitte siduda iga pĂ€ringuga kĂ”iki tabeleid, kopeerisime viite taotlusele tabelisse Transport.
  • Kohandatud staatiliste tabelite vahemĂ€lu, kus on viidatud ja harva muudetud tabelid programmi mĂ€lus.

MĂ”nikord tĂ”id muudatused kaasa suure ĂŒmberkujundamise, kuid vĂ”imaldasid sĂŒsteemi koormuse vĂ€hendamist 5-10% ja olid seega Ă”igustatud. Aja jooksul tĂ”usis vĂ€ljund jĂ€rjest vĂ€hemaks, samas kui nĂ”udmine tĂ”sise ĂŒmberkujundamise jĂ€rele kasvas.

Siis pöörasime tĂ€helepanu teisele pĂ€ringute rĂŒhmale – keskmike rĂŒhmale. Selles oli palju rohkem pĂ€ringuid ja tundus, et terve grupi analĂŒĂŒsimine vĂ”tab kaua aega. Kuid enamik pĂ€ringutest osutusid optimeerimiseks vĂ€ga lihtsateks, ja paljud probleemid kordusid kĂŒmnete erinevate variatsioonide kaudu. Siin on mĂ”ned tĂŒĂŒpilised optimeerimised, mida kasutasime kĂŒmnete sarnaste pĂ€ringute jaoks, ja iga optimeeritud pĂ€ringute grupp vĂ€hendas andmebaasi koormust 3-5%.

  • COUNT abil salvestuste olemasolu kontrollimise asemel hakkasime kasutama EXISTS.
  • Vabandasime DISTINCT'i (ĂŒldreeglit ei ole, kuid mĂ”nikord on vĂ”imalik sellest hĂ”lpsasti vabaneda, kiirendades pĂ€ringut 10-100 korda).

    NÀiteks, suurte kohaletoimetamise tabelite (DELIVERY) pÔhjal kÔikide juhtide valimise pÀringu asemel.

    SELECT DISTINCT P.ID, P.FIRST_NAME, P.LAST_NAME
    FROM DELIVERY D JOIN PERSON P ON D.DRIVER_ID = P.ID
    

    tegime pÀringu suhteliselt vÀikese PERSON tabeli pÔhjal.

    SELECT P.ID, P.FIRST_NAME, P.LAST_NAME
    FROM PERSON
    WHERE EXISTS(SELECT D.ID FROM DELIVERY WHERE D.DRIVER_ID = P.ID)
    

    Tundub, et kasutasime seotud alam-pÀringut, kuid see kiirus tÔusis rohkem kui 10 korda.

  • Paljude juhtumite korral loobusime ĂŒldse COUNT-st ja
    asendasime selle ligikaudse vÀÀrtuse arvutamisega.
  • asemel
    UPPER(s) LIKE JOHN%’ 
    

    kasutame

    s ILIKE “John%”
    

Iga konkreetset pĂ€ringut Ă”nnestus mĂ”nikord kiirendada 3-1000 korda. Hoolimata muljetavaldavatest tulemustest arvasime alguses, et pĂ€ringu optimeerimine, mis kestab 10 ms, ei ole mĂ”ttetu, olles kolmesaja kĂ”ige raskema pĂ€ringu seas ja andmebaasi koormuse ĂŒldises ajas kulutades sajandik protsenti. Kuid sama retsepti rakendamine sarnaste pĂ€ringute rĂŒhmale tĂ”i meile tagasi mitu protsenti. Aja raiskamise vĂ€ltimiseks kogu sadu pĂ€ringute kĂ€sitsi ĂŒlevaatamiseks kirjutasime vĂ€lja mĂ”ned lihtsad skriptid, mis regulaarsete avaldiste abil leidsid sarnased pĂ€ringud. LĂ”ppkokkuvĂ”ttes vĂ”imaldas automaatne pĂ€ringute rĂŒhmade leidmine meil veelgi parandada oma efektiivsust, kulutades tagasihoidlikke jĂ”upingutusi.

Oleme juba kolm aastat töötanud sama riistvaraga. Keskmine koormus on umbes 30%, tipphetkel jĂ”uab see kuni 70%. Taotluste arvu ja kasutajate arv on kasvanud umbes kĂŒmme korda. Ja see kĂ”ik on vĂ”imalik pideva jĂ€lgimise tĂ”ttu nende TOP-MEDIUM pĂ€ringute gruppide suhtes. Niipea, kui mĂ”ni uus pĂ€ring ilmub TOP gruppi, analĂŒĂŒsime seda kohe ja ĂŒritame kiirusest maksimum vĂ”tta. MEDIUM gruppi vaatame kord nĂ€dalas pĂ€ringute analĂŒĂŒsi skriptide abil. Kui leiame uusi pĂ€ringuid, mille optimeerimise viise juba teame, muudetakse neid kiiresti. MĂ”nikord avastame uusi optimeerimise meetodeid, mida saab koheselt rakendada mitmele pĂ€ringule.

Meie prognooside kohaselt talub praegune server kasutajate arvu kasvu veel 3-5 korda. TĂ”si, meil on veel ĂŒks trump varrukas—me ei ole veel SELECT pĂ€ringute peegeldust soovituslikult ĂŒmber lĂŒlitanud. Kuid me teeme seda teadlikult, kuna tahame esmalt tĂ€ielikult Ă€ra kasutada "nutika" optimeerimise vĂ”imalusi, enne kui lĂŒlitame sisse "raskema suurtĂŒki".
Kriitiline vaade tehtud tööle vĂ”ib vihjata, et tasub kaaluda vertikaalset skaleerimist. Osta vĂ”imsam server, selle asemel et spetsialistide aega raisata. Server ei pruugi olla nii kallis, arvestades, et meie vertikaalse skaleerimise piirangud ei ole veel ammendatud. Kuigi pĂ€ringute arv on kasvanud kĂŒmme korda. Aastate jooksul on sĂŒsteemi funktsionaalsus suurenenud ja praegu on erinevaid pĂ€ringute tĂŒĂŒpe rohkem. KĂ”ik, mis oli olemas, tĂ€itub vĂ€hemate, kuid tĂ”husamate pĂ€ringute kaudu tĂ€nu sisseseadmiseks. Seega, et saada reaalseid kiirusetegureid, vĂ”ib julgelt korrutada veel viiega. Nii midagi vĂ€hem ametlikku, vĂ”ib öelda, et kiirus on suurenenud 50 ja rohkem korda. Serveri vertikaalne tĂ”stmine 50 korda maksaks rohkem. Eriti arvestades, et ĂŒks kord teostatud optimeerimine töötab kogu aeg, samas kui renditud serveri arve tuleb igakuiselt.

Allikas: habr.com

Osta usaldusvÀÀrne hostimine veebilehtede jaoks DDoS-i kaitsega, VPS VDS serverid đŸ”„ Osta usaldusvÀÀrne hostimine veebilehtede jaoks DDoS-i kaitsega, VPS VDS serverid | ProHoster