NoSQL:n tietomallin suunnittelun ominaisuudet

Esittely

NoSQL:n tietomallin suunnittelun ominaisuudet "Sinun täytyy juosta niin nopeasti kuin pystyt vain pysyäksesi paikallaan,
ja päästäksesi jonnekin, sinun täytyy juosta vähintään kaksi kertaa nopeammin!”
(c) Liisa ihmemaassa

Jokin aika sitten minua pyydettiin luennoimaan analyytikot yrityksemme tietomallien suunnittelun aiheeseen, koska istuvat projekteissa pitkään (joskus useita vuosia) unohdamme sen, mitä ympärillämme IT-teknologioiden maailmassa tapahtuu. Yrityksessämme (niin vain sattuu) monet projektit eivät käytä NoSQL-tietokantoja (ainakaan toistaiseksi), joten luennollani kiinnitin niihin erikseen huomiota HBasen esimerkin avulla ja yritin suunnata materiaalin esittelyä niihin. jotka eivät ole koskaan käyttäneet niitä, ovat toimineet. Erityisesti havainnollistin joitain tietomallisuunnittelun piirteitä useita vuosia sitten lukemallani esimerkillä Amandeep Khuranan artikkelissa "Johdatus HB ase Schema Designiin".. Analysoidessani esimerkkejä vertailin useita vaihtoehtoja saman ongelman ratkaisemiseksi, jotta pääajatukset välittyvät paremmin yleisölle.

Äskettäin "tekemättä" esitin itselleni kysymyksen (toukokuun pitkä viikonloppu karanteenissa on erityisen suotuisa tälle), kuinka paljon teoreettiset laskelmat vastaavat käytäntöä? Itse asiassa idea tästä artikkelista syntyi. Useita päiviä NoSQL:n kanssa työskennellyt kehittäjä ei välttämättä opi siitä mitään uutta (ja siksi hän voi välittömästi ohittaa puolet artikkelista). Mutta varten analyytikotNiille, jotka eivät ole vielä työskennelleet läheisesti NoSQL:n kanssa, uskon, että se on hyödyllistä saada perusymmärrys HBasen tietomallien suunnittelun ominaisuuksista.

Esimerkkianalyysi

Mielestäni ennen kuin aloitat NoSQL-tietokantojen käytön, sinun on mietittävä huolellisesti ja punnittava etuja ja haittoja. Usein ongelma voidaan todennäköisesti ratkaista käyttämällä perinteisiä relaatiotietokantajärjestelmiä. Siksi on parempi olla käyttämättä NoSQL:ää ilman merkittäviä syitä. Jos kuitenkin päätit käyttää NoSQL-tietokantaa, sinun tulee ottaa huomioon, että suunnittelulähestymistavat ovat hieman erilaisia. Varsinkin jotkut niistä voivat olla epätavallisia niille, jotka ovat aiemmin käsitelleet vain relaatiotietokantajärjestelmiä (omien havaintojeni mukaan). Joten "relaatiomaailmassa" aloitamme yleensä ongelmaalueen mallintamisesta ja vasta sitten denormalisoimme mallin tarvittaessa. NoSQL:ssä me tulee välittömästi ottaa huomioon odotetut skenaariot tietojen kanssa työskennellessä ja denormalisoi tiedot aluksi. Lisäksi on useita muita eroja, joita käsitellään jäljempänä.

Tarkastellaan seuraavaa "synteettistä" ongelmaa, jonka kanssa jatkamme työskentelyä:

Jonkin abstraktin sosiaalisen verkoston käyttäjien ystäväluettelolle on tarpeen suunnitella tallennusrakenne. Yksinkertaistaaksemme oletamme, että kaikki yhteytemme ovat ohjattuja (kuten Instagramissa, ei Linkedinissä). Rakenteen pitäisi mahdollistaa tehokkaasti:

  • Vastaa kysymykseen, lukeeko käyttäjä A käyttäjää B (lukumalli)
  • Salli yhteyksien lisääminen/poistaminen, jos käyttäjä A tilaa/poistaa tilauksen käyttäjältä B (tiedonmuutosmalli)

Ongelman ratkaisemiseksi on tietysti monia vaihtoehtoja. Tavallisessa relaatiotietokannassa tekisimme todennäköisesti yksinkertaisesti suhdetaulukon (mahdollisesti tyypillisesti, jos meidän on esimerkiksi tallennettava käyttäjäryhmä: perhe, työ jne., joka sisältää tämän "ystävän") ja optimoida. pääsynopeus lisäisi indeksejä/osioita. Todennäköisesti finaalipöytä näyttäisi tältä:

USER_ID
ystävän_tunnus

Vasya
Petya

Vasya
Olya

jäljempänä selvyyden ja paremman ymmärryksen vuoksi ilmoitan nimiä henkilötunnusten sijaan

HBasen tapauksessa tiedämme, että:

  • tehokas haku, joka ei johda koko taulukon skannaukseen, on mahdollista yksinomaan avaimella
    • itse asiassa, siksi monille tuttujen SQL-kyselyiden kirjoittaminen tällaisiin tietokantoihin on huono idea; teknisesti toki voi samasta Impalasta lähettää SQL-kyselyn liitoksilla ja muulla logiikalla HBaseen, mutta kuinka tehokasta se on...

Siksi meidän on pakko käyttää käyttäjätunnusta avaimena. Ja ensimmäinen ajatukseni aiheesta "missä ja kuinka säilyttää ystävien henkilöllisyystodistukset?" ehkä idea tallentaa ne sarakkeisiin. Tämä ilmeisin ja "naiiviin" vaihtoehto näyttää suunnilleen tältä (kutsutaanko sitä Vaihtoehto 1 (oletus)lisätietoa varten):

RowKey
kaiuttimet

Vasya
1: Petya
2: Olya
3: Dasha

Petya
1: Masha
2: Vasja

Tässä jokainen rivi vastaa yhtä verkon käyttäjää. Sarakkeilla on nimet: 1, 2, ... - ystävien lukumäärän mukaan, ja sarakkeisiin tallennetaan ystävien tunnukset. On tärkeää huomata, että jokaisella rivillä on eri määrä sarakkeita. Yllä olevan kuvan esimerkissä yhdellä rivillä on kolme saraketta (1, 2 ja 3) ja toisella vain kaksi (1 ja 2) - tässä käytimme itse kahta HBase-ominaisuutta, joita relaatiotietokannoissa ei ole:

  • mahdollisuus muuttaa dynaamisesti sarakkeiden koostumusta (lisää ystävä -> lisää sarake, poista ystävä -> poista sarake)
  • eri riveillä voi olla erilainen sarakerakenne

Tarkistamme, että rakenteemme on tehtävän vaatimusten mukainen:

  • Tietojen lukeminen: ymmärtääksemme, onko Vasya tilannut Olya, meidän on vähennettävä koko rivi näppäimellä RowKey = "Vasya" ja lajittele sarakearvoja, kunnes "tapaamme" Olyassa niissä. Tai toista kaikkien sarakkeiden arvot, "ei täytä" Olyaa ja palauta vastaus Väärä;
  • Tietojen muokkaaminen: kaverin lisääminen: samanlaista tehtävää varten meidän on myös vähennettävä koko rivi käyttämällä näppäintä RowKey = “Vasya” laskeaksesi hänen ystäviensä kokonaismäärän. Tarvitsemme tämän ystävien kokonaismäärän määrittääksemme sarakkeen numeron, johon meidän on kirjoitettava uuden ystävän tunnus.
  • Tietojen muuttaminen: ystävän poistaminen:
    • On vähennettävä koko rivi näppäimellä RowKey = “Vasya” ja lajittele sarakkeet löytääksesi se, johon poistettava ystävä on tallennettu;
    • Seuraavaksi ystävän poistamisen jälkeen meidän on "siirrettävä" kaikki tiedot yhteen sarakkeeseen, jotta emme saa "aukot" niiden numerointiin.

Arvioidaan nyt, kuinka tuottavia nämä algoritmit, jotka meidän on toteutettava "ehdollisen sovelluksen" puolella, ovat O-symboliikka. Merkitään hypoteettisen sosiaalisen verkostomme kokoa n. Tällöin ystävien enimmäismäärä yhdellä käyttäjällä voi olla (n-1). Tämän (-1) voimme edelleen jättää käyttämättä, koska O-symbolien käytön puitteissa sillä ei ole merkitystä.

  • Tietojen lukeminen: on tarpeen vähentää koko rivi ja iteroida kaikkien sen sarakkeiden läpi rajassa. Tämä tarkoittaa, että ylempi kustannusarvio on noin O(n)
  • Tietojen muokkaaminen: kaverin lisääminen: määrittääksesi ystävien määrän, sinun on toistettava rivin kaikki sarakkeet ja lisättävä sitten uusi sarake => O(n)
  • Tietojen muuttaminen: ystävän poistaminen:
    • Samanlainen kuin lisääminen - sinun täytyy käydä läpi kaikki rajan sarakkeet => O(n)
    • Sarakkeiden poistamisen jälkeen meidän on "siirrettävä" ne. Jos otat tämän "otsaan", tarvitset rajoituksessa jopa (n-1) toimintoa. Mutta tässä ja edelleen käytännön osassa käytämme erilaista lähestymistapaa, joka toteuttaa "pseudo-siirtymän" kiinteälle määrälle operaatioita - eli siihen käytetään jatkuvasti aikaa n: stä riippumatta. Tämä vakioaika (tarkemmin O(2)) voidaan jättää huomiotta verrattuna O(n:ään). Lähestymistapa on havainnollistettu alla olevassa kuvassa: kopioimme tiedot "viimeisestä" sarakkeesta siihen, josta haluamme poistaa tiedot, ja poistamme sitten viimeisen sarakkeen:
      NoSQL:n tietomallin suunnittelun ominaisuudet

Kaiken kaikkiaan kaikissa skenaarioissa saimme asymptoottisen laskennallisen monimutkaisuuden O(n).
Olet varmaan jo huomannut, että meidän on melkein aina luettava koko rivi tietokannasta, ja kahdessa tapauksessa kolmesta vain käydäksemme läpi kaikki sarakkeet ja laskeaksemme ystävien kokonaismäärän. Siksi optimointiyrityksenä voit lisätä "count" -sarakkeen, joka tallentaa kunkin verkon käyttäjän ystävien kokonaismäärän. Tässä tapauksessa emme voi lukea koko riviä ystävien kokonaismäärän laskemiseksi, vaan lukea vain yhden "count" -sarakkeen. Tärkeintä on, että älä unohda päivittää "laskentaa" tietoja käsiteltäessä. Että. paranemme Vaihtoehto 2 (luku):

RowKey
kaiuttimet

Vasya
1: Petya
2: Olya
3: Dasha
laskea: 3

Petya
1: Masha
2: Vasja

laskea: 2

Verrattuna ensimmäiseen vaihtoehtoon:

  • Tietojen lukeminen: saada vastaus kysymykseen "Lukeeko Vasya Olyaa?" mikään ei ole muuttunut => O(n)
  • Tietojen muokkaaminen: kaverin lisääminen: Olemme yksinkertaistaneet uuden ystävän lisäämistä, koska nyt meidän ei tarvitse lukea koko riviä ja iteroida sen sarakkeiden yli, vaan saamme vain "count" -sarakkeen arvon jne. määritä välittömästi sarakkeen numero lisätäksesi uuden ystävän. Tämä johtaa laskennan monimutkaisuuden vähenemiseen O(1)
  • Tietojen muuttaminen: ystävän poistaminen: Kun poistat ystävää, voimme myös käyttää tätä saraketta I/O-toimintojen määrän vähentämiseen, kun "siirretään" dataa yhden solun vasemmalle. Mutta tarve iteroida sarakkeiden läpi poistettavan löytämiseksi on edelleen olemassa, joten => ​​O(n)
  • Toisaalta nyt dataa päivitettäessä täytyy päivittää "count" sarake joka kerta, mutta tämä vie jatkuvasti aikaa, mikä voidaan jättää huomiotta O-symbolien puitteissa.

Yleensä vaihtoehto 2 näyttää hieman optimaalisemmalta, mutta se on enemmän kuin "evoluutio vallankumouksen sijaan". Tarvitsemme "vallankumouksen" tekemiseen Vaihtoehto 3 (sarake).
Käännetään kaikki "ylöspäin": nimitämme sarakkeen nimi käyttäjätunnus! Se, mitä itse sarakkeeseen kirjoitetaan, ei ole enää meille tärkeää, olkoon se numero 1 (yleensä sinne voidaan tallentaa hyödyllisiä asioita, esimerkiksi ryhmä "perhe/ystävät/jne."). Tämä lähestymistapa saattaa yllättää valmistautumattoman "maallikon", jolla ei ole aikaisempaa kokemusta NoSQL-tietokantojen kanssa työskentelystä, mutta juuri tämä lähestymistapa antaa sinun käyttää HBasen potentiaalia tässä tehtävässä paljon tehokkaammin:

RowKey
kaiuttimet

Vasya
Petya: 1
Olya: 1
Dasha: 1

Petya
Masha: 1
Vasja: 1

Tässä saamme useita etuja kerralla. Niiden ymmärtämiseksi analysoidaan uutta rakennetta ja arvioidaan laskennallinen monimutkaisuus:

  • Tietojen lukeminen: vastataksesi kysymykseen, onko Vasya Olya-tilaaja, riittää, että luet yhden sarakkeen "Olya": jos se on siellä, vastaus on tosi, jos ei - Väärä => O(1)
  • Tietojen muokkaaminen: kaverin lisääminen: Ystävän lisääminen: lisää vain uusi sarake "Ystävän tunnus" => O(1)
  • Tietojen muuttaminen: ystävän poistaminen: poista vain Friend ID -sarake => O(1)

Kuten näet, tämän tallennusmallin merkittävä etu on se, että kaikissa tarvitsemissamme skenaarioissa toimimme vain yhdellä sarakkeella, jolloin vältetään koko rivin lukeminen tietokannasta ja lisäksi luetellaan kaikki tämän rivin sarakkeet. Voisimme pysähtyä tähän, mutta...

Voit olla ymmälläsi ja mennä hieman pidemmälle suorituskyvyn optimoinnin ja I/O-toimintojen vähentämisen tiellä, kun käytät tietokantaa. Mitä jos tallentaisimme täydelliset suhdetiedot suoraan itse riviavaimeen? Eli tehdään avainyhdistelmä, kuten userID.friendID? Tässä tapauksessa meidän ei tarvitse edes lukea rivin sarakkeita (Vaihtoehto 4 (rivi)):

RowKey
kaiuttimet

Vasya.Petya
Petya: 1

Vasja.Olja
Olya: 1

Vasja. Dasha
Dasha: 1

Petya.Masha
Masha: 1

Petya.Vasya
Vasja: 1

Ilmeisesti kaikkien tietojen manipulointiskenaarioiden arviointi tällaisessa rakenteessa, kuten edellisessä versiossa, on O(1). Ero vaihtoehtoon 3 on yksinomaan tietokannan I/O-toimintojen tehokkuudessa.

No, viimeinen "jousi". On helppo nähdä, että vaihtoehdossa 4 rivinäppäimellä on muuttuva pituus, mikä voi mahdollisesti vaikuttaa suorituskykyyn (tässä muistamme, että HBase tallentaa tiedot tavujoukona ja taulukoiden rivit lajitellaan avaimen mukaan). Lisäksi meillä on erotin, jota on ehkä käsiteltävä joissakin skenaarioissa. Tämän vaikutuksen poistamiseksi voit käyttää tiivistettä käyttäjätunnuksesta ja ystävätunnuksesta, ja koska molemmilla tiivisteillä on vakiopituus, voit yksinkertaisesti ketjuttaa ne ilman erotinta. Silloin taulukon tiedot näyttävät tältä (Vaihtoehto 5 (hash)):

RowKey
kaiuttimet

dc084ef00e94aef49be885f9b01f51c01918fa783851db0dc1f72f83d33a5994
Petya: 1

dc084ef00e94aef49be885f9b01f51c0f06b7714b5ba522c3cf51328b66fe28a
Olya: 1

dc084ef00e94aef49be885f9b01f51c00d2c2e5d69df6b238754f650d56c896a
Dasha: 1

1918fa783851db0dc1f72f83d33a59949ee3309645bd2c0775899fca14f311e1
Masha: 1

1918fa783851db0dc1f72f83d33a5994dc084ef00e94aef49be885f9b01f51c0
Vasja: 1

Ilmeisesti tällaisen rakenteen kanssa työskentelyn algoritminen monimutkaisuus tarkastelemissamme skenaarioissa on sama kuin vaihtoehdossa 4 - eli O(1).
Tehdään yhteenvetona kaikki laskennallisen monimutkaisuuden arviomme yhteen taulukkoon:

Ystävän lisääminen
Tarkastetaan ystävää
Ystävän poistaminen

Vaihtoehto 1 (oletus)
O (n)
O (n)
O (n)

Vaihtoehto 2 (laskenta)
O (1)
O (n)
O (n)

Vaihtoehto 3 (sarake)
O (1)
O (1)
O (1)

Vaihtoehto 4 (rivi)
O (1)
O (1)
O (1)

Vaihtoehto 5 (hash)
O (1)
O (1)
O (1)

Kuten näette, vaihtoehdot 3-5 näyttävät olevan edullisimmat ja varmistavat teoriassa kaikkien tarvittavien tietojen käsittelyskenaarioiden suorittamisen jatkuvassa ajassa. Tehtävämme olosuhteissa ei ole nimenomaista vaatimusta hankkia luettelo käyttäjän kaikista ystävistä, mutta todellisessa projektitoiminnassa meidän, hyvien analyytikoiden, olisi hyvä "ennakoida", että tällainen tehtävä saattaa syntyä ja "levitä olki." Siksi sympatiani ovat vaihtoehdon 3 puolella. Mutta on melko todennäköistä, että todellisessa projektissa tämä pyyntö olisi jo voitu ratkaista muilla keinoin, joten ilman yleistä näkemystä koko ongelmasta on parempi olla tekemättä lopulliset johtopäätökset.

Kokeen valmistelu

Haluaisin testata yllä olevia teoreettisia perusteluja käytännössä - tämä oli pitkän viikonlopun aikana syntyneen idean tavoite. Tätä varten on tarpeen arvioida "ehdollisen sovelluksemme" toimintanopeus kaikissa kuvatuissa tietokannan käyttöskenaarioissa sekä tämän ajan pidentyminen sosiaalisen verkoston (n) kasvaessa. Kohdeparametri, joka kiinnostaa meitä ja jota mittaamme kokeilun aikana, on aika, jonka "ehdollinen sovellus" käyttää yhden "liiketoiminnan" suorittamiseen. "Liiketapahtumalla" tarkoitamme jotakin seuraavista:

  • Yhden uuden ystävän lisääminen
  • Tarkistetaan, onko käyttäjä A käyttäjän B ystävä
  • Yhden ystävän poistaminen

Näin ollen, kun otetaan huomioon alkuperäisessä lausunnossa hahmotellut vaatimukset, varmennusskenaario muodostuu seuraavasti:

  • Tietojen tallennus. Luo satunnaisesti alkuverkko, jonka koko on n. Jotta päästään lähemmäksi "todellista maailmaa", kunkin käyttäjän ystävien määrä on myös satunnaismuuttuja. Mittaa aika, jonka "ehdollinen sovellus" kirjoittaa kaikki luodut tiedot HBaseen. Jaa sitten saatu aika lisättyjen ystävien kokonaismäärällä - näin saadaan keskimääräinen aika yhdelle "liiketoiminnalle"
  • Tietojen lukeminen. Luo jokaiselle käyttäjälle luettelo "persoonallisuuksista", joille sinun on saatava vastaus, onko käyttäjä tilannut ne vai ei. Listan pituus = suunnilleen käyttäjän ystävien lukumäärä, ja puolet tarkastetuista ystävistä vastaa "Kyllä" ja toiselle puolelle - "Ei". Tarkistus suoritetaan siinä järjestyksessä, että vastaukset "Kyllä" ja "Ei" vuorottelevat (eli joka toisessa tapauksessa joudumme käymään läpi kaikki rivin sarakkeet vaihtoehdoille 1 ja 2). Kokonaisseulonta-aika jaetaan sitten testattujen ystävien lukumäärällä, jotta saadaan keskimääräinen seulonta-aika kohdetta kohden.
  • Tietojen poisto. Poista kaikki ystävät käyttäjästä. Lisäksi poistojärjestys on satunnainen (eli "sekoitamme" alkuperäisen listan, jota käytetään tietojen tallentamiseen). Tarkastuksen kokonaisaika jaetaan sitten poistettujen ystävien lukumäärällä, jolloin saadaan keskimääräinen aika per sekki.

Skenaariot on suoritettava kullekin viidestä tietomallivaihtoehdosta ja eri kokoisille sosiaalisille verkostoille, jotta näet, kuinka aika muuttuu sen kasvaessa. Yhden n:n sisällä verkon yhteyksien ja tarkistettavien käyttäjäluettelon on luonnollisesti oltava samat kaikille viidelle vaihtoehdolle.
Ymmärtämisen helpottamiseksi alla on esimerkki luoduista tiedoista n = 5. Kirjoitettu "generaattori" tuottaa kolme ID-sanakirjaa tulosteena:

  • ensimmäinen on lisättäväksi
  • toinen on tarkistusta varten
  • kolmas – poistettavaksi

{0: [1], 1: [4, 5, 3, 2, 1], 2: [1, 2], 3: [2, 4, 1, 5, 3], 4: [2, 1]} # всего 15 друзей

{0: [1, 10800], 1: [5, 10800, 2, 10801, 4, 10802], 2: [1, 10800], 3: [3, 10800, 1, 10801, 5, 10802], 4: [2, 10800]} # всего 18 проверяемых субъектов

{0: [1], 1: [1, 3, 2, 5, 4], 2: [1, 2], 3: [4, 1, 2, 3, 5], 4: [1, 2]} # всего 15 друзей

Kuten näet, kaikki tarkistettavan sanakirjan yli 10 000 tunnukset ovat juuri niitä, jotka antavat varmasti vastauksen Väärin. "Ystävien" lisääminen, tarkistaminen ja poistaminen suoritetaan täsmälleen sanakirjassa määritetyssä järjestyksessä.

Kokeilu suoritettiin kannettavalla tietokoneella, jossa oli Windows 10, jossa HBase oli käynnissä yhdessä Docker-säiliössä ja Python ja Jupyter Notebook toisessa. Dockerille myönnettiin 2 CPU-ydintä ja 2 Gt RAM-muistia. Kaikki logiikka, kuten "ehdollisen sovelluksen" emulointi ja "putkisto" testitietojen tuottamiseksi ja ajan mittaamiseksi, kirjoitettiin Pythonissa. Kirjastoa käytettiin työskentelyyn HBasen kanssa onnellinen tukikohta, laskea tiivisteet (MD5) vaihtoehdolle 5 - hashlib

Ottaen huomioon tietyn kannettavan tietokoneen laskentateho, valittiin kokeellisesti käynnistys arvoille n = 10, 30, …. 170 – kun koko testaussyklin kokonaiskäyttöaika (kaikki skenaariot kaikille vaihtoehdoille kaikille n:lle) oli vieläkin enemmän tai vähemmän kohtuullinen ja sopiva yhden teekutsun aikana (keskimäärin 15 minuuttia).

Tässä on huomautettava, että tässä kokeessa emme ensisijaisesti arvioi absoluuttisia suorituskykylukuja. Edes kahden eri vaihtoehdon suhteellinen vertailu ei välttämättä ole täysin oikea. Nyt olemme kiinnostuneita n:stä riippuvan ajan muutoksen luonteesta, koska ottaen huomioon yllä oleva "testitelineen" konfiguraatio, on erittäin vaikea saada aikaestimaattia, jotka "puhdistetaan" satunnaisten ja muiden tekijöiden vaikutuksesta ( eikä sellaista tehtävää asetettu).

Kokeilutulos

Ensimmäinen testi on, kuinka ystävälistan täyttämiseen käytetty aika muuttuu. Tulos on alla olevassa kaaviossa.
NoSQL:n tietomallin suunnittelun ominaisuudet
Vaihtoehdot 3-5 näyttävät odotetusti lähes vakion "liiketapahtuman" ajan, joka ei riipu verkon koon kasvusta ja erosta suorituskyvyssä.
Vaihtoehto 2 näyttää myös jatkuvan, mutta hieman huonomman suorituskyvyn, lähes tasan 2 kertaa verrattuna vaihtoehtoihin 3-5. Ja tämä ei voi muuta kuin iloita, koska se korreloi teorian kanssa - tässä versiossa I/O-operaatioiden määrä HBaseen/HBaseen on tasan 2 kertaa suurempi. Tämä voi toimia epäsuorana todisteena siitä, että testipenkkimme tarjoaa periaatteessa hyvän tarkkuuden.
Vaihtoehto 1 osoittautuu myös odotetusti hitaimmaksi ja osoittaa lineaarista lisäystä toistensa lisäämiseen käytetyssä ajassa verkon kokoon.
Katsotaan nyt toisen testin tuloksia.
NoSQL:n tietomallin suunnittelun ominaisuudet
Vaihtoehdot 3-5 toimivat jälleen odotetusti - vakioaika verkon koosta riippumatta. Vaihtoehdot 1 ja 2 osoittavat lineaarisen ajan pidentymisen verkon koon kasvaessa ja vastaavan suorituskyvyn. Lisäksi vaihtoehto 2 osoittautuu hieman hitaammaksi - ilmeisesti johtuen tarpeesta tarkistaa ja käsitellä ylimääräinen "count"-sarake, joka tulee näkyvämmäksi n:n kasvaessa. Mutta pidättäydyn silti tekemästä johtopäätöksiä, koska tämän vertailun tarkkuus on suhteellisen alhainen. Lisäksi nämä suhteet (kumpi vaihtoehto, 1 vai 2 on nopeampi) muuttuivat juoksusta juoksuun (säilyttäen samalla riippuvuuden luonteen ja "kaulaan ja niskaan kulkemisen").

No, viimeinen kaavio on poistotestin tulos.

NoSQL:n tietomallin suunnittelun ominaisuudet

Jälleen, ei yllätyksiä täällä. Vaihtoehdot 3-5 suorittavat poiston vakioajassa.
Lisäksi on mielenkiintoista, että vaihtoehdot 4 ja 5, toisin kuin aikaisemmat skenaariot, osoittavat huomattavasti heikompaa suorituskykyä kuin vaihtoehto 3. Ilmeisesti rivien poisto on kalliimpi kuin sarakkeen poistotoiminto, mikä on yleensä loogista.

Vaihtoehdot 1 ja 2 osoittavat odotetusti lineaarista ajan pidentymistä. Samanaikaisesti vaihtoehto 2 on jatkuvasti hitaampi kuin vaihtoehto 1 - johtuen lisä-I/O-toiminnosta, joka "ylläpitää" laskentasarakkeen.

Kokeen yleiset johtopäätökset:

  • Vaihtoehdot 3-5 osoittavat suurempaa tehokkuutta, koska ne hyödyntävät HBasea; Lisäksi niiden suorituskyky eroaa keskenään vakion verran eikä riipu verkon koosta.
  • Vaihtoehtojen 4 ja 5 välistä eroa ei kirjattu. Tämä ei kuitenkaan tarkoita, että vaihtoehtoa 5 ei pitäisi käyttää. On todennäköistä, että käytetty kokeellinen skenaario, ottaen huomioon testipenkin suorituskykyominaisuudet, ei mahdollistanut sen havaitsemista.
  • "Liiketoiminnan" suorittamiseen tarvittavan ajan pidentymisen luonne tiedoilla vahvisti yleisesti aiemmin saadut teoreettiset laskelmat kaikille vaihtoehdoille.

Epilogi

Tehtyjä karkeita kokeita ei pidä ottaa absoluuttisena totuutena. On monia tekijöitä, joita ei otettu huomioon ja jotka vääristävät tuloksia (nämä vaihtelut näkyvät erityisesti pienen verkon koon kaavioissa). Esimerkiksi happybasen käyttämä säästäväisyys, Pythonissa kirjoittamani logiikan määrä ja toteutustapa (en voi väittää, että koodi on kirjoitettu optimaalisesti ja tehokkaasti käyttänyt kaikkien komponenttien ominaisuuksia), ehkä HBase-välimuistin ominaisuudet, Windows 10:n taustatoiminnot kannettavassa tietokoneessani jne. Yleisesti voidaan olettaa, että kaikki teoreettiset laskelmat ovat kokeellisesti osoittaneet niiden pätevyyden. No, tai niitä ei ainakaan ollut mahdollista kumota sellaisella "otsahyökkäyksellä".

Yhteenvetona, suosituksia kaikille, jotka ovat vasta aloittamassa tietomallien suunnittelua HBaseen: abstrakti aiemmasta kokemuksesta relaatiotietokantojen parissa ja muista "käskyt":

  • Suunnittelussa lähdemme tiedonkäsittelyn tehtävästä ja kaavoista, emme toimialuemallista
  • Tehokas pääsy (ilman täyttä pöytäskannausta) – vain avaimella
  • Denormalisointi
  • Eri rivit voivat sisältää erilaisia ​​sarakkeita
  • Kaiuttimien dynaaminen kokoonpano

Lähde: will.com

Lisää kommentti