Sissejuhatus
âPeame jooksma kĂ”ikide jĂ”ududega, et lihtsalt paigal pĂŒsida,
ja kuhugi jĂ”udmiseks tuleb joosta vĂ€hemalt kahekordselt kiiremini!â
(c) Alice Imedemaal
MĂ”ni aeg tagasi paluti mul pidada loeng analĂŒĂŒtikutele meie ettevĂ”ttes andmete mudelite kavandamise teemal, sest veedame kaua aega projektides (mĂ”nikord mitu aastat), unustades, mis toimub IT-tehnoloogia maailmas. Meie ettevĂ”ttes (kuid nii on lĂ€inud) ei kasutata paljudes projektides NoSQL andmebaase (vĂ€hemalt seni), seetĂ”ttu keskendusin oma loengus veidi rohkem neile HBase nĂ€itel ning pĂŒĂŒdsin suunata sisu neid, kes ei ole kunagi nendega töötanud. EelkĂ”ige illustreerisin andmete mudeli kavandamise mĂ”ningaid omadusi nĂ€itega, mida lugesin paar aastat tagasi . NĂ€iteid analĂŒĂŒsides vĂ”rdlesin erinevaid lahendusi sama probleemi jaoks, et aidata kuulajatel mĂ”ista pĂ”hiteemasid.
Hiljuti, "ei tea, mida teha", kĂŒsisin endalt, kui hĂ€sti teoreetilised jĂ€reldused praktikale vastavad (pikad maised puhkepĂ€evad karantiini reĆŸiimis toetavad seda eriti). Just seetĂ”ttu sĂŒndis see artikli idee. Arendaja, kes on NoSQL-iga juba pikka aega tegelenud, ei pruugi siit midagi uut leida (ja seetĂ”ttu vĂ”ib kohe poole artikli poole kerida). Kuid analĂŒĂŒtikutele, kes ei ole veel NoSQL-iga sĂŒvitsi tegelenud, arvan, et see on kasulik, et saada pĂ”hiteadmisi andmemudelite kavandamise eripĂ€radest HBase jaoks.
NĂ€ite analĂŒĂŒs
Minu arvates, enne NoSQL andmebaaside kasutamise alustamist tuleks hoolikalt mĂ”elda ja kaaluda plusse ja miinuseid. Sageli on probleemi vĂ”imalik lahendada ka traditsiooniliste relationaalsete andmebaasidega. Seega on parem mitte kasutada NoSQL-i ilma tĂ”sise pĂ”hjenduseta. Kui siiski on otsustatud kasutada NoSQL andmebaasi, tuleb arvestada, et projekteerimislĂ€henemised on siin veidi erinevad. Eriti vĂ”ivad mĂ”ned neist tunduda harjumatuna neile, kes on varem kasutanud ainult relationaalseid andmebaase (minu tĂ€helepanekute kohaselt). Nii et ârelationaalsesâ maailmas alustame tavaliselt domeeni modelleerimisest ja vajadusel teeme mudeli denormaliseerimise. Me peame kohe arvestama eeldatavate andmetöötlusstsenaariumidega ja algselt denormaliseerima andmed. Lisaks on veel mitu erinevust, millest rÀÀgitakse allpool.
Vaatame jĂ€rgmise âsĂŒnteetiliseâ ĂŒlesande, millega tegeleme edasi:
Kasutajate sÔprade nimekirja salvestamise struktuur tuleb projekteerida mingisuguses abstraktses sotsiaalvÔrgustikus. Lihtsuse huvides eeldame, et kÔik seosed on suunatud (nagu Instagramis, mitte LinkedInis). Struktuur peab vÔimaldama tÔhusalt:
- Vastata kĂŒsimusele, kas kasutaja A loeb kasutaja B sisu (lugemismall)
- Kasutaja A ja kasutaja B vahelisi seoseid lisada/eemaldada juhul, kui kasutaja A tellib/peatutab kasutaja B (andmete muutmise mall)
Lahenduste variandid on loomulikult mitmed. Tavalises relatsioonilises andmebaasis teeksime tĂ”enĂ€oliselt lihtsalt seoste tabeli (vĂ”imalik, et tĂŒpiseeritud, kui nĂ€iteks on vaja salvestada kasutajagruppi: perekond, töö jne, kuhu kuulub antud âsĂ”berâ), ja kiirusoptimeerimise huvides lisaks indekseid/partitsioneerimist. TĂ”enĂ€oliselt nĂ€eks lĂ”pptabel vĂ€lja umbes nii:
user_id
friend_id
Vladimir
Peti
Vladimir
Olya
siin ja edaspidi, et paremini aru saada, kasutan ID-de asemel nimesid
HBase'i puhul teame, et:
- efektiivne otsing, mis ei pÔhjusta tÀielikku tabeli skaneerimist, on vÔimalik ainult vÔtme alusel
- SeetĂ”ttu on tavaliste SQL-pĂ€ringute kirjutamine sellistele andmebaasidele halb mĂ”te; tehniliselt on muidugi vĂ”imalik saata Impala'lt SQL-pĂ€ring koos Join'ide ja muu loogikaga HBase's, aga kui efektiivne see onâŠ
SeetÔttu peame kasutama kasutaja ID-d vÔtmena. Esimene mÔte selle kohta, "kuidas ja kus salvestada sÔprade ID-d?", vÔib olla nende salvestamine veergudesse. See kÔige ilmsem ja "naivne" variant nÀeb vÀlja umbes nii (nimetame seda Variant 1 (default), et viidata hiljem):
RowKey
Veerud
Vladimir
1: Peeter
2: Olya
3: Dasha
Peti
1: Masha
2: Vasya
Igas reas on ĂŒks kasutaja sotsiaalvĂ”rgustikes. Veergudel on nimed: 1, 2, ⊠â sĂ”prade arvu jĂ€rgi, ja veergudes hoitakse sĂ”prade ID-sid. Oluline on mĂ€rkida, et igas reas on erinev arv veerge. Ălaltoodud joonisel on ĂŒhes reas kolm veergu (1, 2 ja 3), teises aga ainult kaks (1 ja 2) â siin kasutasime kahte omadust HBase's, mida ei ole relaationalsetes andmebaasides:
- vĂ”imalust dĂŒnaamiliselt muuta veergude koosseisu (lisame sĂ”bra -> lisame veeru, eemaldame sĂ”bra -> eemaldame veeru)
- erinevates ridades vÔivad olla erinevad veergude koosseisud
Kontrollime meie struktuuri ĂŒlesande nĂ”uetele vastavust:
- Andmete lugemine: et mÔista, kas Vassil on Olya tellitud, peame me vÀlja lugema kogu rida vÔtme RowKey = «Vassil» jÀrgi ja kontrollima veergude vÀÀrtusi, kuni leiame Olya. VÔi kontrollime kÔiki veerge, et «ei kohtaks» Olya ja anname vastuseks vale;
- Andmete muutmine: sĂ”bra lisamine: sellise ĂŒlesande jaoks peame samuti vĂ€lja lugema kogu rida vĂ”tme RowKey = «Vassil» jĂ€rgi, et arvutada tema sĂ”prade koguarv. See koguarv on vajalik, et mÀÀrata veeru number, kuhu tuleb salvestada uue sĂ”bra ID.
- Andmete muutmine: sÔbra kustutamine:
- Peame vÀlja lugema kogu rida vÔtme RowKey = «Vassil» jÀrgi ja kontrollima veerge, et leida see, kuhu on salvestatud kustutatav sÔber;
- SeejĂ€rel peame kustutatud sĂ”bra pĂ€rast «tĂ”ukama» kĂ”ik andmed ĂŒhe veeru vĂ”rra, et vĂ€ltida nende numbrite «katkestusi».
Hinnakem nĂŒĂŒd, kui tĂ”husad on need algoritmid, mida peame «tinglikus rakenduses» rakendama. . MÀÀratleme meie hĂŒpotetiseeritud sotsiaalvĂ”rgustiku suuruseks n. Seega vĂ”ib ĂŒhe kasutaja maksimaalne sĂ”prade arv olla (n-1). Selle (-1) vĂ”ime edaspidi ignoreerida, kuna O-sĂŒmboolika kasutamisel on see ebaoluline.
- Andmete lugemine: on vaja kogu rida vĂ€lja arvutada ja piiri piires lĂ€bi vaadata kĂ”ik selle veerud. Seega on ĂŒlemine hindamine kulude osas umbes O(n)
- Andmete muutmine: sÔbra lisamine: sÔprade arvu mÀÀramiseks on vaja lÀbi vaadata kÔik veerud, pÀrast mida tuleb sisestada uus veerg => O(n)
- Andmete muutmine: sÔbra kustutamine:
- Sarnaselt lisamisega - on lÔppkokkuvÔttes vaja lÀbi vaadata kÔik veerud => O(n)
- Veergede eemaldamisel peame need "tĂ”ukama". Kui seda "otseselt" teostada, vajame lĂ”puks veel kuni (n-1) operatsiooni. Kuid siin ja edaspidi rakendame praktilises osas teistsugust lĂ€henemist, mis viib âvale tĂ”ukamiseniâ fikseeritud arvu operatsioonidega â see tĂ€hendab, et selleks kulub konstantne aeg olenemata n-st. Seda konstantset aega (tĂ€psemalt O(2)) saab vĂ”rrelda O(n) ja selle peale vĂ”ib tĂ€helepanu mitte pöörata. LĂ€henemine on illustreeritud alloleval joonisel: lihtsalt kopeerime andmed "viimasest" veerust sellesse, kust on vaja andmed eemaldada, seejĂ€rel kustutame viimase veeru:

KokkuvÔttes saime kÔigis stsenaariumides asymptootilise arvutuskompleksuse O(n).
Te olete ilmselt juba mĂ€rganud, et me peame peaaegu alati lugema terve rea kogu ulatuses, ja kaks korda kolmest teeme seda ainult selleks, et lĂ€bida kĂ”ik veerud ja arvutada kokku sĂ”prade arvu. SeetĂ”ttu vĂ”iks optimeerimise katse raames lisada veeru âcountâ, kuhu salvestada iga kasutaja sĂ”prade koguarv. Sel juhul ei pea me kogu rida tervikuna lugema, et saada sĂ”prade koguarvu, vaid saame lugeda ainult veeru âcountâ. Peaasi, et ei unustata âcountâ vÀÀrtust andmetega manipuleerimisel uuendada. Nii saavutame tĂ”hustamise. Variant 2 (count):
RowKey
Veerud
Vladimir
1: Peeter
2: Olya
3: Dasha
count: 3
Peti
1: Masha
2: Vasya
count: 2
VÔrreldes esimesega:
- Andmete lugemine: kĂŒsimusele âKas Vasia loeb Oljat?â ei ole midagi muutunud => O(n)
- Andmete muutmine: sĂ”bra lisamine: Oleme lihtsustanud uue sĂ”bra lisamist, kuna nĂŒĂŒd ei pea me lugema kogu rida ja lĂ€bima selle veerge, vaid saame lihtsalt vĂ”tta veeru âcountâ vÀÀrtuse ja seega mÀÀrata kohe veeru numbri uue sĂ”bra lisamiseks. See vĂ€hendab arvutuskompleksust O(1)-ni.
- Andmete muutmine: sĂ”bra kustutamine: SĂ”brade eemaldamisel saame kasutada ka seda veergu, et vĂ€hendada sisendi ja vĂ€ljundi operatsioonide arvu andmete âtĂ”ukamiseksâ ĂŒhe lahtri vĂ”rra vasakule. Kuid veergude lĂ€bivaatamise vajadus eemaldatava leidmiseks jÀÀb siiski alles, seega => O(n)
- Teiselt poolt, nĂŒĂŒd peame andmete uuendamisel iga kord vĂ€rskendama ka veergu âcountâ, kuid selleks kulub konstantne aeg, mida O-sĂŒmboolide raames vĂ”ib ignoreerida
Ăldiselt tundub variant 2 veidi optimaalsem, kuid see on pigem âevolutsioon, mitte revolutsioonâ. Revolutsiooni saavutamiseks vajame Variant 3 (col).
KĂ€invertame kĂ”ik âjalgu ĂŒle peaâ: mÀÀrame veeru nimi kasutaja identifikaatoriks! Mis iganes veerus salvestatakse â ei ole meie jaoks enam oluline, las see olla number 1 (ĂŒldiselt, seal saab hoida nĂ€iteks rĂŒhma âpereliikmed/sĂ”brad jneâ). See lĂ€henemine vĂ”ib ĂŒllatada ettevalmistamata âtavainimestâ, kellel pole varem olnud kogemusi NoSQL-andmebaasidega, kuid just see vĂ”imaldab HBase potentsiaali selles ĂŒlesandes kasutusele vĂ”tta palju efektiivsemalt:
RowKey
Veerud
Vladimir
Petr: 1
Ola: 1
Dasha: 1
Peti
Masha: 1
Vasya: 1
Siin saame kohe mitmeid eeliseid. Need mĂ”ista, analĂŒĂŒsime uut struktuuri ja hindame arvutuskompleksust:
- Andmete lugemine: et vastata kĂŒsimusele, kas Vasja on Olya jĂ€lginud, piisab ĂŒhe veeru «Olya» lugemisest: kui see on olemas, siis vastus on True, kui seda pole, siis False => O(1)
- Andmete muutmine: sÔbra lisamine: SÔbra lisamine: piisab lihtsalt uue veeru «SÔbra ID» lisamisest => O(1)
- Andmete muutmine: sÔbra kustutamine: piisab lihtsalt veeru «SÔbra ID» eemaldamisest => O(1)
Kuna nĂ€eme, on sellise salvestusmudeli oluline eelis see, et kĂ”igis vajalikus stsenaariumis töötame ainult ĂŒhe veeruga, vĂ€ltides kogu rea lugemist andmebaasist ja veelgi enam, kĂ”igi selle rea veergude lĂ€bimist. Sellega vĂ”ikski piirduda, kuidâŠ
Saame muretseda ja minna veelgi kaugemale jĂ”udluse optimeerimise ja andmebaasi juurdepÀÀsul sisend-vĂ€ljundite vĂ€henemise teel. Mis siis, kui salvestada kĂ”ik ĂŒhenduse kohta kĂ€ivad andmed otse rea vĂ”tmes? Ehk tegemist on koostisosavĂ”tmega vormis userID.friendID? Sel juhul ei pea me isegi rea veerge lugema (Variant 4 (rida)):
RowKey
Veerud
Vasja.Petja
Petr: 1
Vasja.Olya
Ola: 1
Vasja.Dasha
Dasha: 1
Petja.Masha
Masha: 1
Petja.Vasja
Vasya: 1
Ilmselt on kĂ”igi andmete manipuleerimise stsenaariumide hindamine sellises struktuuris, nagu ka eelmine variant, O(1). Erinevus variandiga 3 seisneb ĂŒldiselt vaid andmebaasis sisend- ja vĂ€ljundoperatsioonide efektiivsuses.
Ja viimane 'pael'. On lihtne mÀrkida, et variandis 4 on meie rea vÔti muutuv pikkus, mis vÔib mÔjutada jÔudlust (meenutame, et HBase salvestab andmeid baitide kogumina ja read tabelites on sorteeritud vÔtme jÀrgi). Lisaks on meil eraldaja, mida teatud stsenaariumites vÔib olla vaja töödelda. Selle mÔju vÀhendamiseks vÔime kasutada userID ja friendID haƥhe, ning kuna mÔlemad haƥid on konstantsed pikkused, saame need lihtsalt konkateerida, ilma eraldajata. Siis nÀevad andmed tabelis vÀlja sellised.Variant 5(hash)):
RowKey
Veerud
dc084ef00e94aef49be885f9b01f51c01918fa783851db0dc1f72f83d33a5994
Petr: 1
dc084ef00e94aef49be885f9b01f51c0f06b7714b5ba522c3cf51328b66fe28a
Ola: 1
dc084ef00e94aef49be885f9b01f51c00d2c2e5d69df6b238754f650d56c896a
Dasha: 1
1918fa783851db0dc1f72f83d33a59949ee3309645bd2c0775899fca14f311e1
Masha: 1
1918fa783851db0dc1f72f83d33a5994dc084ef00e94aef49be885f9b01f51c0
Vasya: 1
On selge, et sellise struktuuri algoritmiline keerukus meie kĂ€sitletud stsenaariumide puhul on sama, mis variandil 4 â st O(1).
KokkuvĂ”tteks koondame kĂ”ik meie arvutuste keerukuse hinnangud ĂŒhte tabelisse:
SÔbra lisamine
SÔbra kontrollimine
SÔbra eemaldamine
Variant 1 (default)
O(n)
O(n)
O(n)
Variant 2 (count)
O(1)
O(n)
O(n)
Variant 3 (column)
O(1)
O(1)
O(1)
Variant 4 (row)
O(1)
O(1)
O(1)
Variant 5 (hash)
O(1)
O(1)
O(1)
Kuna nĂ€ha on, nĂ€ivad variandid 3-5 olema kĂ”ige eelistatumad ja teoreetiliselt tagavad kĂ”igi vajalike andmehaldusstsenaariumide tĂ€itmise pideva ajaga. Meie ĂŒlesande tingimustes pole selget nĂ”uet, et saaksime kasutaja kĂ”igi sĂ”prade loendi, kuid tegelikus projektitöös oleks meil, headel analĂŒĂŒtikutel, mĂ”istlik "ette nĂ€ha", et selline ĂŒlesanne vĂ”ib tekkida ja "kaitsta end". SeetĂ”ttu on minu eelistus variandi 3 poole. Kuid on tĂ€iesti vĂ”imalik, et reaalses projektis on see pĂ€ring juba lahendatud muude vahenditega, seega on parem vĂ€ltida lĂ”plikke jĂ€reldusi, kui pole ĂŒldist arusaama kogu probleemist.
Eksperimendi ettevalmistamine
Ălaltoodud teoreetilisi arutlusi on soovitatav praktikas kontrollida - see oligi pika nĂ€dalavahetuse mĂ”tte pĂ”hjuseks. Selleks on vajalik hinnata meie "tingimusliku rakenduse" töökiirus kĂ”igis kirjeldatud andmebaasi kasutuse stsenaariumides ning samuti selle aja kasvu sotsiaalse vĂ”rgu (n) suuruse suurenemisega. Sihtparameeter, mis meid huvitab ja mida me katse kĂ€igus mÔÔdame, on "tingimusliku rakenduse" kulutatud aeg ĂŒhe "ettevĂ”tte tehingu" tĂ€itmiseks. "EttevĂ”tte tehing" tĂ€hendab ĂŒhte jĂ€rgmistest:
- Ăhe uue sĂ”bra lisamine
- Kontrollimine, kas kasutaja A on kasutaja B sÔber
- Ăhe sĂ”bra kustutamine
Seega, arvestades algses ĂŒlesandes esitatud nĂ”udeid, joonistub kinnitamise stsenaarium vĂ€lja jĂ€rgmiselt:
- Andmete salvestamine. Genereeri juhuslikult lĂ€htevĂ”rk suurusega n. Suurema lĂ€henemise saavutamiseks "reaalsele maailmale" on iga kasutaja sĂ”prade arv samuti juhuslik vÀÀrtus. MÀÀra aeg, mille jooksul meie âtingimuslik rakendusâ salvestab HBase kĂ”ik genereeritud andmed. SeejĂ€rel jagage saadud aeg lisatud sĂ”prade koguarvuga â nii saame keskmise aja ĂŒhe âĂ€ritehinguâ kohta.
- Andmete lugemine. Iga kasutaja jaoks koosta nimekiri âisikutestâ, kelle kohta tuleb vĂ€lja selgitada, kas kasutaja jĂ€lgib neid vĂ”i mitte. Nimekirja pikkus = ligikaudu kasutaja sĂ”prade arv, kusjuures poole kontrollitavate sĂ”prade puhul peab vastus olema âJahâ ja teise poole puhul â âEiâ. Kontrollimine toimub sellises jĂ€rjekorras, et vastused âJahâ ja âEiâ vahelduvad (st igal teisel juhul peame lĂ€bi vaatama kĂ”ik veerud ridades variantide 1 ja 2 jaoks). Ăldine kontrollimise aeg jagatakse seejĂ€rel kontrollitavate sĂ”prade arvuga, et saada keskmine kontrollimise aeg ĂŒhe subjekti kohta.
- Andmete kustutamine. Eemaldage kasutajalt kĂ”ik sĂ”brad. Eemaldamise jĂ€rjekord on juhuslik (st âsegameâ algse loendi, mida kasutati andmete salvestamiseks). Kokku kontrollimise aeg jagatakse siis eemaldatavate sĂ”prade arvuga, et saada keskmine aeg ĂŒhe kontrolli kohta.
Skeeme tuleb testida iga 5 andmemudeli variandi jaoks ja erinevate sotsiaalvĂ”rgustike suuruste jĂ€rgi, et nĂ€ha, kuidas aeg muutub koos selle kasvuga. Ăhe nĂŒhikuga peab vĂ”rgu sees ja kontrollimiseks kasutatav kasutajate nimekiri loomulikult olema sama kĂ”igi 5 variandi jaoks.
Parema arusaamise saamiseks toome allpool nĂ€ite genereeritud andmetest n= 5. Kirjutatud âgeneraatorâ annab vĂ€ljundina kolm ID-de sĂ”nastikku:
- esimene â sisestamiseks
- teine â kontrollimiseks
- kolmas â kustutamiseks
{0: [1], 1: [4, 5, 3, 2, 1], 2: [1, 2], 3: [2, 4, 1, 5, 3], 4: [2, 1]} # kokku 15 sÔpra
{0: [1, 10800], 1: [5, 10800, 2, 10801, 4, 10802], 2: [1, 10800], 3: [3, 10800, 1, 10801, 5, 10802], 4: [2, 10800]} # kokku 18 kontrollitavat subjekti
{0: [1], 1: [1, 3, 2, 5, 4], 2: [1, 2], 3: [4, 1, 2, 3, 5], 4: [1, 2]} # kokku 15 sÔpra
Kuidas mÀrkida, kÔik ID-d, mis on suuremad kui 10 000 kontrollimise sÔnastikus - need on just need, mis kindlasti annavad vale vastuse. SÔbra lisamine, kontrollimine ja eemaldamine toimub alati sÔnastikus nÀidatud jÀrjekorras.
Eksperiment viidi lĂ€bi sĂŒlearvutil, millel oli Windows 10, kus ĂŒhes Docker'i konteineris töötas HBase andmebaas ja teises - Python koos Jupyter Notebook'iga. Docker'ile on eraldatud 2 CPU tuuma ja 2 GB RAM-i. Kogu loogika, sealhulgas emulatsioon âtinglikust rakendusestâ ja âriistvaraâ testandmete genereerimise ning aja mÔÔtmise jaoks, oli kirjutatud Pythonis. HBase'i jaoks kasutati raamatukogu , MD5 hashide (variant 5) arvutamiseks - hashlib.
Arvestades konkreetse sĂŒlearvuti arvutusvĂ”imsust, valiti eksperimentaalselt kĂ€ivitamine n = 10, 30, âŠ. 170 - kui kogu tsĂŒkli testimise (kĂ”ik stsenaariumid kĂ”igi variantide jaoks igas n-s) koguaeg oli veel enam-vĂ€hem mĂ”istlik ja mahtus ĂŒhe teejoomise aega (keskmiselt 15 minutit).
Siin on oluline mĂ€rkida, et antud eksperimendis hindame esmalt mitte absoluutseid jĂ”udlusnumbreid. Isegi erinevate kahe variandi suhteline vĂ”rdlemine ei pruugi kindlasti olla tĂ€iesti korrektne. Meid huvitab praegu eelkĂ”ige aja muutumise iseloom n sĂ”ltuvalt, kuna arvesse vĂ”ttes eespool mainitud 'testimise seade' konfiguratsiooni on ajahinnangute saamine, mis on 'puhastatud' juhuslike ja teiste tegurite mĂ”just, vĂ€ga keeruline (ja sellist ĂŒlesannet ei olnudki esitatud).
Eksperimendi tulemus
Esimene test â kuidas muutub aeg, mis kulub sĂ”prade nimekirja tĂ€itmiseks. Tulemus â alloleval graafikul.

Variandid 3-5 nÀitavad ootuspÀraselt praktiliselt konstantset 'Àritegevuse' aega, mis ei sÔltu vÔrgu suuruse kasvamisest ja nÀhtamatust jÔudlusvahedest.
Variant 2 shows a constant but slightly worse performance, being nearly 2 times lower compared to variants 3-5. This is encouraging as it aligns with theory â in this variant, the number of input/output operations to/from HBase is exactly twice as high. This could serve as indirect evidence that our test setup provides decent accuracy.
Variant 1 is, as expected, the slowest one and demonstrates a linear increase in time taken for adding one another, proportional to the size of the network.
Now let's look at the results of the second test.

Valikud 3-5 kĂ€ituvad taas ootuspĂ€raselt â konstantne aeg, mis ei sĂ”ltu vĂ”rgu suurusest. Valikud 1 ja 2 nĂ€itavad lineaarset ajakasvu vĂ”rgu suuruse suurenedes ja sarnast jĂ”udlust. Tuleb mĂ€rkida, et variant 2 osutub veidi aeglasemaks â tĂ”enĂ€oliselt seetĂ”ttu, et tuleb lugeda ja töödelda tĂ€iendavat âcountâ veergu, mis suuruse n kasvades muutub mĂ€rgatavamaks. Kuid ma ei tee siiski jĂ€reldusi, kuna selle vĂ”rdluse tĂ€psus on suhteliselt madal. Lisaks muutuvad need suhted (milline valik, 1 vĂ”i 2, on kiirem) kĂ€ivitamiselt kĂ€ivitamisele (samal ajal sĂ€ilitades sĂ”ltuvuse loomuse ja "minnes ninapidi koos").
Viimane diagramm â kustutamise testimise tulemus.

Siin pole samuti ĂŒllatusi. Valikud 3-5 teostavad kustutamise konstantse ajaga.
Mis on huvitav, variantide 4 ja 5, erinevalt eelnevatest stsenaariumitest, nĂ€itavad veidi kehvemat jĂ”udlust kui variant 3. TĂ”enĂ€oliselt on rea kustutamine kulukam kui veeru kustutamine, mis on ĂŒldiselt loogiline.
Valikud 1 ja 2 nÀitavad oodatult lineaarset ajakasvu. Sellegipoolest on valik 2 pidevalt aeglasem kui valik 1 - tÀnu tÀiendavatele sisendi-vÀlendi operatsioonidele 'kolonni count' hooldamiseks.
KokkuvÔtted katse tulemustest:
- Valikud 3-5 nÀitavad suuremaid tÔhususe nÀitajaid, kuna nad kasutavad HBase'i eeliseid; sellegipoolest erineb nende tootlikkus omavahel konstantse vÀÀrtuse ulatuses ja ei sÔltu vÔrgu suurusest.
- Erinevust variantide 4 ja 5 vahel ei registreeritud. Kuid see ei tÀhenda, et variant 5 ei oleks kasutamiseks sobiv. On tÀiesti vÔimalik, et katse stsenaarium, arvestades testimise seinale m3ompid, ei vÔimaldanud seda avastada.
- Ajakasvu iseloom, mis on vajalik 'Ă€ritegevustega' andmetega töötamiseks, on ĂŒldiselt kinnitanud varem saadud teoreetilisi jĂ€reldusi kĂ”ikide variantide osas.
Epilog
Tehtud katseid ei tohiks tĂ”lgendada absoluutsena. On palju tegureid, mida ei arvestatud ja mis moonutasid tulemusi (eriti selgelt on need kĂ”ikumised nĂ€htavad graafikutes vĂ€ikese vĂ”rgu suuruse korral). NĂ€iteks thrift'i töö kiirus, mida kasutatakse happybase'is, loogika rakendamine, mille ma olin kirjutanud Pythonis (ei julge öelda, et kood oli kirjutatud optimaalselt ja tĂ”husalt kasutas kĂ”iki komponente), vĂ”ib-olla HBase'i salvestamise eripĂ€ra, Windows 10 taustategevus minu sĂŒlearvutis jne. Ăldiselt vĂ”ib öelda, et kĂ”ik teoreetilised jĂ€reldused on katsetega osutunud kehtivaks. VĂ”i vĂ€hemalt ei Ă”nnestunud neid sellise âersameelne vastuâ ĂŒmber lĂŒkata.
KokkuvĂ”tteks â soovitused neile, kes alles hakkavad andmemudeleid HBase'is projekteerima: abstraktsioneerige oma eelmist kogemust relatsiooniliste andmebaasidega ja pidage meeles âkĂ€skyâ:
- Projekteerimisel lĂ€hme ĂŒlesandest ja andmete manipuleerimise mallidest, mitte objektide mudelist.
- TĂ”hus juurdepÀÀs (ilma full table scanita) â ainult vĂ”tme kaudu.
- Denormaliseerimine
- Erinevad read vÔivad sisaldada erinevaid veerge
- Veergude dĂŒnaamiline koostis
Allikas: habr.com

