NoSQL adatmodell tervezésének jellemzői

Bevezetés

NoSQL adatmodell tervezésének jellemzői „Amilyen gyorsan csak tudsz, futnod kell, hogy a helyedben maradj,
és ahhoz, hogy eljuss valahova, legalább kétszer olyan gyorsan kell futnod!”
(c) Alice Csodaországban

Nemrég felkértek, hogy tartsak előadást elemzők cégünk adatmodellek tervezésének témájában, mert hosszú ideig (esetenként több évig) projekteken ülve szem elől tévesztjük, mi történik körülöttünk az informatikai technológiák világában. Cégünknél (előfordult) sok projekt nem használ NoSQL adatbázisokat (legalábbis egyelőre), ezért előadásomban a HBase példáján külön figyelmet fordítottam ezekre, és igyekeztem az anyag bemutatását azokhoz orientálni. akik soha nem használták őket, dolgoztak. Különösen az adatmodell-tervezés néhány jellemzőjét illusztráltam egy néhány évvel ezelőtt olvasott példa segítségével Amandeep Khurana „Bevezetés a HB ase sématervezésbe” című cikkében. A példák elemzésekor több lehetőséget hasonlítottam össze ugyanazon probléma megoldására annak érdekében, hogy a főbb gondolatokat jobban átadjam a hallgatóságnak.

Nemrég „semmiből” tettem fel magamnak a kérdést (a hosszú májusi karanténhétvége ennek különösen kedvez), hogy az elméleti számítások mennyire felelnek meg a gyakorlatnak? Valójában így született meg ennek a cikknek az ötlete. Az a fejlesztő, aki több napja dolgozik a NoSQL-lel, nem biztos, hogy semmi újat tanul belőle (és ezért azonnal kihagyhatja a cikk felét). De érte elemzőkAzok számára, akik még nem dolgoztak szorosan a NoSQL-lel, úgy gondolom, hogy hasznos lesz a HBase adatmodellek tervezésének jellemzőinek alapvető megértéséhez.

Példaelemzés

Véleményem szerint, mielőtt elkezdené használni a NoSQL adatbázisokat, alaposan át kell gondolnia, és mérlegelnie kell az előnyöket és hátrányokat. A probléma gyakran megoldható hagyományos relációs DBMS-ekkel. Ezért jobb, ha nem használja a NoSQL-t jelentős okok nélkül. Ha mégis úgy döntött, hogy NoSQL adatbázist használ, akkor vegye figyelembe, hogy a tervezési megközelítések itt némileg eltérőek. Főleg néhányuk szokatlan azok számára, akik korábban csak relációs DBMS-ekkel foglalkoztak (megfigyeléseim szerint). Tehát a „relációs” világban általában a problématartomány modellezésével kezdjük, és csak ezután, ha szükséges, denormalizáljuk a modellt. A NoSQL-ben mi azonnal figyelembe kell vennie az adatokkal való munkavégzés várható forgatókönyveit és kezdetben denormalizálja az adatokat. Ezen kívül számos egyéb különbség is van, amelyeket az alábbiakban tárgyalunk.

Tekintsük a következő „szintetikus” problémát, amellyel továbbra is dolgozunk:

Meg kell tervezni egy tárolási struktúrát valamely absztrakt közösségi hálózat felhasználóinak ismerőseinek listájához. Az egyszerűsítés kedvéért feltételezzük, hogy minden kapcsolatunk irányított (mint az Instagramon, nem a Linkedinben). A szerkezetnek lehetővé kell tennie hatékonyan:

  • Válaszoljon arra a kérdésre, hogy A felhasználó olvassa-e B felhasználót (olvasási minta)
  • Kapcsolatok hozzáadásának/eltávolításának engedélyezése A felhasználó B felhasználótól való előfizetése/leiratkozása esetén (adatmódosítási sablon)

Természetesen számos lehetőség kínálkozik a probléma megoldására. Egy normál relációs adatbázisban nagy valószínűséggel egyszerűen készítenénk egy táblázatot a kapcsolatokról (esetleg tipizálva, ha például tárolnunk kell egy felhasználói csoportot: család, munka stb., amely tartalmazza ezt a „barátot”), és optimalizálni szeretnénk. a hozzáférési sebesség indexeket/particionálást adna hozzá. A döntő asztal valószínűleg így fog kinézni:

user_id
barát_azonosító

Vasya
Petya

Vasya
Оля

a továbbiakban az áttekinthetőség és a jobb megértés érdekében az azonosítók helyett neveket fogok feltüntetni

A HBase esetében tudjuk, hogy:

  • lehetséges a hatékony keresés, amely nem eredményez teljes táblázatvizsgálatot kizárólag kulccsal
    • valójában ezért rossz ötlet sokak számára ismerős SQL-lekérdezéseket írni ilyen adatbázisokba; technikailag persze ugyanabból az Impalából tudsz SQL lekérdezést küldeni Joins-el és egyéb logikával a HBase-nek, de mennyire lesz eredményes...

Ezért kénytelenek vagyunk kulcsként a felhasználói azonosítót használni. És az első gondolatom a „hol és hogyan kell tárolni a barátok azonosítóit?” témában? talán egy ötlet, hogy oszlopokban tároljuk őket. Ez a legkézenfekvőbb és „naivabb” lehetőség valahogy így fog kinézni (nevezzük 1. lehetőség (alapértelmezett)további információért):

RowKey
Hangszórók

Vasya
1: Petya
2: Olya
3: Dasha

Petya
1: Mása
2: Vasya

Itt minden sor egy hálózati felhasználónak felel meg. Az oszlopoknak neve van: 1, 2, ... - az ismerősök számának megfelelően, és az ismerősök azonosítói az oszlopokban tárolódnak. Fontos megjegyezni, hogy minden sor eltérő számú oszlopot tartalmaz. A fenti ábrán látható példában az egyik sorban három oszlop van (1, 2 és 3), a másodikban pedig csak kettő (1 és 2) - itt mi magunk használtunk két olyan HBase tulajdonságot, amelyekkel a relációs adatbázisok nem rendelkeznek:

  • az oszlopok összetételének dinamikus megváltoztatásának képessége (barát hozzáadása -> oszlop hozzáadása, ismerős eltávolítása -> oszlop törlése)
  • a különböző sorok eltérő oszlopösszetételűek lehetnek

Ellenőrizzük, hogy struktúránk megfelel-e a feladat követelményeinek:

  • Adatok olvasása: annak megértéséhez, hogy Vasya előfizetett-e az Olya-ra, ki kell vonnunk az egész sort a RowKey = „Vasya” billentyűvel, és rendezze az oszlopértékeket, amíg „találkozunk” az Olya-val. Vagy ismételje meg az összes oszlop értékeit, „nem felel meg” Olya-nak, és adja vissza a Hamis választ;
  • Adatok szerkesztése: barát hozzáadása: hasonló feladathoz nekünk is ki kell vonnunk az egész sort a RowKey = „Vasya” billentyűvel megszámolja barátai teljes számát. Erre az összes barátszámra van szükségünk ahhoz, hogy meghatározzuk annak az oszlopnak a számát, amelybe fel kell írnunk az új barát azonosítóját.
  • Adatok módosítása: ismerős törlése:
    • Ki kell vonni az egész sort a RowKey = „Vasya” billentyűvel, és rendezze az oszlopokat, hogy megtalálja azt, amelyikben a törölni kívánt barát szerepel;
    • Ezután egy barát törlése után az összes adatot egy oszlopba kell „tolni”, hogy ne legyen „hézag” a számozásukban.

Most mérjük fel, mennyire lesznek termelékenyek ezek az algoritmusok, amelyeket a „feltételes alkalmazás” oldalon kell megvalósítanunk. O-szimbolika. Jelöljük hipotetikus közösségi hálózatunk méretét n-nel. Ekkor egy felhasználó barátjainak maximális száma (n-1). Ezt a (-1) szempontot a továbbiakban figyelmen kívül hagyhatjuk, mivel az O-szimbólumok használatának keretein belül ez lényegtelen.

  • Adatok olvasása: ki kell vonni a teljes sort és végig kell iterálni az összes oszlopát a korlátban. Ez azt jelenti, hogy a költségek felső becslése körülbelül O(n)
  • Adatok szerkesztése: barát hozzáadása: a barátok számának meghatározásához végig kell ismételni a sor összes oszlopát, majd be kell szúrni egy új oszlopot => O(n)
  • Adatok módosítása: ismerős törlése:
    • Hasonló a hozzáadáshoz - át kell mennie a korlát összes oszlopán => O(n)
    • Az oszlopok eltávolítása után „át kell mozgatnunk” őket. Ha ezt a „fejjel” megvalósítja, akkor a limiten belül legfeljebb (n-1) műveletre lesz szüksége. De itt és a továbbiakban a gyakorlati részben egy másik megközelítést fogunk alkalmazni, amely meghatározott számú művelethez „pszeudoeltolást” valósít meg - vagyis állandó időt fog rá fordítani, függetlenül az n-től. Ez az állandó idő (pontosabban O(2)) elhanyagolható O(n)-hez képest. A megközelítést az alábbi ábra szemlélteti: egyszerűen átmásoljuk az adatokat az „utolsó” oszlopból abba, ahonnan törölni szeretnénk, majd töröljük az utolsó oszlopot:
      NoSQL adatmodell tervezésének jellemzői

Összességében minden forgatókönyvben O(n) aszimptotikus számítási komplexitást kaptunk.
Valószínűleg már észrevetted, hogy szinte mindig a teljes sort kell kiolvasnunk az adatbázisból, és háromból két esetben csak azért, hogy végigmegyünk az összes oszlopon, és kiszámoljuk az összes barátok számát. Ezért optimalizálási kísérletként hozzáadhat egy „számlálás” oszlopot, amely az egyes hálózati felhasználók összes barátjának számát tárolja. Ebben az esetben nem tudjuk elolvasni a teljes sort a barátok teljes számának kiszámításához, hanem csak egy „számláló” oszlopot olvashatunk. A legfontosabb dolog az, hogy ne felejtse el frissíteni a „számlálást” az adatok manipulálásakor. Hogy. javulunk 2. lehetőség (szám):

RowKey
Hangszórók

Vasya
1: Petya
2: Olya
3: Dasha
szám: 3

Petya
1: Mása
2: Vasya

szám: 2

Az első lehetőséghez képest:

  • Adatok olvasása: választ kapni arra a kérdésre, hogy „Olya olvas Vasya?” semmi sem változott => O(n)
  • Adatok szerkesztése: barát hozzáadása: Leegyszerűsítettük az új barát beszúrását, mivel most nem kell a teljes sort elolvasnunk és az oszlopain át iterálni, hanem csak a „count” oszlop értékét tudjuk megkapni stb. azonnal határozza meg az oszlop számát új barát beszúrásához. Ez a számítási bonyolultság O(1)-re csökkenéséhez vezet.
  • Adatok módosítása: ismerős törlése: Barát törlésekor ezt az oszlopot is használhatjuk az I/O műveletek számának csökkentésére, amikor az adatokat egy cellával balra toljuk. De továbbra is meg kell ismételni az oszlopokat, hogy megtaláljuk azt, amelyet törölni kell, tehát => ​​O(n)
  • Másrészt most az adatok frissítésénél minden alkalommal frissíteni kell a „számlálás” oszlopot, de ez állandó időt vesz igénybe, ami az O-szimbólumok keretein belül elhanyagolható

Általánosságban elmondható, hogy a 2. lehetőség egy kicsit optimálisabbnak tűnik, de inkább „forradalom helyett evolúció”-hoz hasonlít. Ahhoz, hogy „forradalmat” csináljunk, szükségünk lesz 3. lehetőség (oszlop).
Fordítsunk mindent „fejjel lefelé”: kiosztunk oszlopnév felhasználói azonosító! Magában a rovatban az már nem fontos számunkra, legyen az 1-es szám (általában hasznos dolgokat lehet ott tárolni, pl. a „család/barátok/stb.” csoport). Ez a megközelítés meglepheti a felkészületlen „laikusokat”, akiknek nincs korábbi NoSQL-adatbázisokkal való munkatapasztalata, de éppen ez a megközelítés teszi lehetővé, hogy a HBase-ben rejlő lehetőségeket ebben a feladatban sokkal hatékonyabban tudja kihasználni:

RowKey
Hangszórók

Vasya
Petya: 1
Olya: 1
Dasha: 1

Petya
Mása: 1
Vasya: 1

Itt több előnyt is kapunk egyszerre. Ezek megértéséhez elemezzük az új struktúrát és becsüljük meg a számítási bonyolultságot:

  • Adatok olvasása: annak a kérdésnek a megválaszolásához, hogy a Vasya előfizetett-e az Olya-ra, elég elolvasni egy „Olya” oszlopot: ha ott van, akkor a válasz igaz, ha nem – hamis => O(1)
  • Adatok szerkesztése: barát hozzáadása: Ismerős hozzáadása: csak adjon hozzá egy új oszlopot „Friend ID” => O(1)
  • Adatok módosítása: ismerős törlése: csak távolítsa el a Friend ID oszlopot => O(1)

Amint látható, ennek a tárolási modellnek az a jelentős előnye, hogy minden szükséges forgatókönyvben csak egy oszloppal dolgozunk, elkerülve a teljes sor kiolvasását az adatbázisból, és ráadásul ennek a sornak az összes oszlopát. Itt megállhatnánk, de...

Meglepődhet, és egy kicsit tovább léphet a teljesítmény optimalizálásának és az I/O műveletek csökkentésének útján az adatbázis elérésekor. Mi lenne, ha a teljes kapcsolati információt közvetlenül a sorkulcsban tárolnánk? Ez azt jelenti, hogy a kulcsot olyan összetettvé tegye, mint a userID.friendID? Ebben az esetben egyáltalán nem kell elolvasnunk a sor oszlopait (4. lehetőség (sor)):

RowKey
Hangszórók

Vasya.Petya
Petya: 1

Vasya.Olya
Olya: 1

Vasya.Dasha
Dasha: 1

Petya.Masha
Mása: 1

Petya.Vasya
Vasya: 1

Nyilvánvaló, hogy az összes adatmanipulációs forgatókönyv értékelése ilyen struktúrában, akárcsak az előző verzióban, O(1) lesz. A különbség a 3. lehetőséghez képest kizárólag az adatbázis I/O műveleteinek hatékonyságában lesz.

Nos, az utolsó „íj”. Könnyen belátható, hogy a 4. opcióban a sorkulcs változó hosszúságú lesz, ami esetleg befolyásolhatja a teljesítményt (itt ne feledjük, hogy a HBase bájtok halmazaként tárolja az adatokat, és a táblázatok sorai kulcs szerint vannak rendezve). Ezenkívül van egy elválasztónk, amelyet bizonyos esetekben kezelni kell. Ennek a hatásnak a kiküszöbölésére használhatja a userID és a friendID hash-eit, és mivel mindkét hash állandó hosszúságú lesz, egyszerűen összefűzheti őket elválasztó nélkül. Ekkor a táblázat adatai így fognak kinézni (5. lehetőség (hash)):

RowKey
Hangszórók

dc084ef00e94aef49be885f9b01f51c01918fa783851db0dc1f72f83d33a5994
Petya: 1

dc084ef00e94aef49be885f9b01f51c0f06b7714b5ba522c3cf51328b66fe28a
Olya: 1

dc084ef00e94aef49be885f9b01f51c00d2c2e5d69df6b238754f650d56c896a
Dasha: 1

1918fa783851db0dc1f72f83d33a59949ee3309645bd2c0775899fca14f311e1
Mása: 1

1918fa783851db0dc1f72f83d33a5994dc084ef00e94aef49be885f9b01f51c0
Vasya: 1

Nyilvánvaló, hogy az általunk fontolóra vett forgatókönyvekben az ilyen struktúrával való munka algoritmikus bonyolultsága megegyezik a 4. lehetőségével – azaz O(1).
Összességében foglaljuk össze a számítási összetettségre vonatkozó összes becslésünket egy táblázatban:

Ismerős hozzáadása
Egy barát ellenőrzése
Ismerős eltávolítása

1. lehetőség (alapértelmezett)
O (n)
O (n)
O (n)

2. lehetőség (számlálás)
O (1)
O (n)
O (n)

3. lehetőség (oszlop)
O (1)
O (1)
O (1)

4. lehetőség (sor)
O (1)
O (1)
O (1)

5. lehetőség (hash)
O (1)
O (1)
O (1)

Amint látja, a 3-5. lehetőség tűnik a legelőnyösebbnek, és elméletileg biztosítja az összes szükséges adatkezelési forgatókönyv állandó időben történő végrehajtását. Feladatunk feltételei között nincs kifejezett követelmény a felhasználó összes barátjának beszerzése, de valós projekttevékenységeknél jó elemzőknek jó lenne „előre számolni” egy ilyen feladat felmerülésével, – szalmát szórj. Ezért együttérzésem a 3. lehetőség mellett van. De nagyon valószínű, hogy egy valós projektben ez a kérés már más módon is megoldható lett volna, ezért az egész probléma általános elképzelése nélkül jobb, ha nem teszünk végső következtetések.

A kísérlet előkészítése

A fenti elméleti érveket szeretném a gyakorlatban is tesztelni - ez volt a célja a hosszú hétvégén felmerült ötletnek. Ehhez értékelni kell a „feltételes alkalmazásunk” működési sebességét az adatbázis használatára vonatkozó összes leírt forgatókönyvben, valamint ennek az időnek a növekedését a közösségi hálózat méretének növekedésével (n). A minket érdeklő célparaméter, amelyet a kísérlet során mérni fogunk, az az idő, amelyet a „feltételes alkalmazás” egy „üzleti művelet” elvégzésére fordít. „Üzleti tranzakció” alatt a következők egyikét értjük:

  • Egy új barát hozzáadása
  • Annak ellenőrzése, hogy A felhasználó barátja-e B felhasználónak
  • Egy barát eltávolítása

Így a kezdeti nyilatkozatban vázolt követelményeket figyelembe véve az ellenőrzési forgatókönyv a következőképpen alakul:

  • Adatrögzítés. Véletlenszerűen generáljon egy n méretű kezdeti hálózatot. Hogy közelebb kerüljünk a „valós világhoz”, az egyes felhasználók barátainak száma is egy véletlen változó. Mérje meg azt az időt, ameddig a „feltételes alkalmazásunk” az összes generált adatot a HBase-be írja. Ezután osszuk el a kapott időt a hozzáadott barátok számával – így kapjuk meg egy „üzleti művelet” átlagos idejét.
  • Adatok olvasása. Minden felhasználóhoz hozzon létre egy listát azokról a „személyiségekről”, amelyekre választ kell kapnia, hogy a felhasználó feliratkozott-e rájuk vagy sem. A lista hossza = hozzávetőlegesen a felhasználó ismerőseinek száma, és a bejelölt barátok fele esetében a válasz „igen”, a másik felére pedig „nem” legyen. Az ellenőrzést olyan sorrendben hajtjuk végre, hogy az „Igen” és a „Nem” válaszok váltakoznak (vagyis minden második esetben végig kell mennünk az 1. és 2. lehetőséghez tartozó sor összes oszlopán). A teljes szűrési időt ezután elosztjuk a tesztelt barátok számával, hogy megkapjuk az alanyonkénti átlagos szűrési időt.
  • Adatok törlése. Távolítsa el az összes barátot a felhasználóból. Ráadásul a törlési sorrend véletlenszerű (vagyis az adatok rögzítésére használt eredeti listát „megkeverjük”). A teljes ellenőrzési időt ezután elosztjuk az eltávolított barátok számával, hogy megkapjuk az ellenőrzésenkénti átlagos időt.

A forgatókönyveket le kell futtatni mind az 5 adatmodell-lehetőséghez és a közösségi hálózat különböző méretűekhez, hogy lássuk, hogyan változik az idő növekedésével. Egy n-en belül a hálózati kapcsolatoknak és az ellenőrizendő felhasználók listájának természetesen mind az 5 lehetőségnél azonosnak kell lenniük.
A jobb megértés érdekében az alábbiakban egy példa látható n= 5 esetén generált adatokra. Az írott „generátor” három azonosító szótárt állít elő kimenetként:

  • az első a beillesztésre szolgál
  • a második az ellenőrzésre szolgál
  • harmadik – törlésre

{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 друзей

Amint látja, az ellenőrzésre szánt szótárban minden 10 000-nél nagyobb azonosító pontosan azok, amelyek biztosan hamis választ adnak. A „barátok” beszúrása, ellenőrzése és törlése pontosan a szótárban megadott sorrendben történik.

A kísérletet Windows 10 operációs rendszert futtató laptopon végezték, ahol az egyik Docker-tárolóban a HBase, a másikban pedig a Jupyter Notebook-os Python futott. A Docker 2 CPU magot és 2 GB RAM-ot kapott. Az összes logika, mind a „feltételes alkalmazás” emulációja, mind a tesztadatok generálására és az idő mérésére szolgáló „csővezeték” Pythonban íródott. A könyvtárat a HBase-sel való együttműködésre használták boldogbázis, a hash-ek (MD5) kiszámításához az 5. opcióhoz - hashlib

Egy adott laptop számítási teljesítményét figyelembe véve kísérletileg egy n = 10, 30, … indítást választottak ki. 170 – amikor a teljes tesztelési ciklus teljes működési ideje (minden forgatókönyv az összes opcióhoz az összes n-hez) még többé-kevésbé ésszerű volt, és belefért egy teázás során (átlagosan 15 perc).

Itt szükséges megjegyezni, hogy ebben a kísérletben nem elsősorban az abszolút teljesítményadatokat értékeljük. Még a két különböző lehetőség viszonylagos összehasonlítása sem lehet teljesen helyes. Most az n-től függő időváltozás természete érdekel bennünket, mivel a „próbaállvány” fenti konfigurációját figyelembe véve nagyon nehéz olyan időbecsléseket szerezni, amelyek „megtisztulnak” a véletlenszerű és egyéb tényezők hatásától ( és ilyen feladatot nem tűztek ki).

Kísérleti eredmény

Az első teszt az, hogy hogyan változik a barátlista kitöltésére fordított idő. Az eredmény az alábbi grafikonon látható.
NoSQL adatmodell tervezésének jellemzői
A 3-5. opciók a várakozásoknak megfelelően szinte állandó „üzleti tranzakció” időt mutatnak, ami nem függ a hálózat méretének növekedésétől és a teljesítményben megkülönböztethetetlen különbségtől.
A 2. lehetőség is állandó, de valamivel rosszabb teljesítményt mutat, szinte pontosan kétszeresét a 2-3. lehetőséghez képest. És ez nem lehet más, mint az öröm, mivel ez korrelál az elmélettel - ebben a verzióban a HBase-be/ből induló I/O műveletek száma pontosan 5-szerese. Ez közvetett bizonyítékul szolgálhat arra, hogy tesztpadunk elvileg jó pontosságot biztosít.
Az 1. lehetőség is, ahogy az várható volt, a leglassabbnak bizonyul, és lineárisan növekszik az egymáshoz való csatlakozással töltött idő alatt a hálózat méretéhez.
Nézzük most a második teszt eredményeit.
NoSQL adatmodell tervezésének jellemzői
A 3-5. opciók ismét a várt módon működnek – állandó idő, függetlenül a hálózat méretétől. Az 1. és 2. lehetőség lineáris időnövekedést mutat a hálózat méretének növekedésével és hasonló teljesítményt. Sőt, a 2. lehetőség egy kicsit lassabbnak bizonyul – nyilvánvalóan a további „számlálás” oszlop lektorálása és feldolgozása miatt, amely egyre észrevehetőbbé válik, ahogy n növekszik. De továbbra is tartózkodom a következtetések levonásától, mivel ennek az összehasonlításnak a pontossága viszonylag alacsony. Ezen túlmenően, ezek az arányok (melyik opció, az 1-es vagy a 2-es a gyorsabb) futásról futásra változott (a függőség természetének és a „nyak-nyakkolás” jellegének megőrzése mellett).

Nos, az utolsó grafikon az eltávolítási teszt eredménye.

NoSQL adatmodell tervezésének jellemzői

Itt megint nincs meglepetés. A 3-5. opciók az eltávolítást állandó időben hajtják végre.
Ráadásul érdekes módon a 4. és 5. opció az előző forgatókönyvekkel ellentétben észrevehetően valamivel rosszabb teljesítményt mutat, mint a 3. lehetőség. Úgy tűnik, a sortörlési művelet drágább, mint az oszloptörlési művelet, ami általában logikus.

Az 1. és 2. lehetőség a várakozásoknak megfelelően lineáris időnövekedést mutat. Ugyanakkor a 2. lehetőség folyamatosan lassabb, mint az 1. lehetőség – a számlálóoszlop „karbantartását” szolgáló további I/O művelet miatt.

A kísérlet általános következtetései:

  • A 3-5. opciók nagyobb hatékonyságot mutatnak, mivel kihasználják a HBase előnyeit; Sőt, teljesítményük egy konstansban különbözik egymáshoz képest, és nem függ a hálózat méretétől.
  • A 4. és 5. lehetőség közötti különbséget nem rögzítették. Ez azonban nem jelenti azt, hogy az 5. lehetőséget ne használjuk. Valószínű, hogy az alkalmazott kísérleti forgatókönyv, figyelembe véve a próbapad teljesítményjellemzőit, nem tette lehetővé annak kimutatását.
  • Az adatokkal történő „üzleti műveletek” elvégzéséhez szükséges időnövekedés jellege általánosságban megerősítette a korábban kapott elméleti számításokat minden lehetőség esetében.

Epilógus

Az elvégzett durva kísérleteket nem szabad abszolút igazságként venni. Sok olyan tényező van, amelyet nem vettek figyelembe, és torzították az eredményeket (ezek az ingadozások különösen jól láthatóak a kis hálózatméretű grafikonokon). Például a takarékosság sebessége, amit a happybase használ, a Pythonban leírt logika mennyisége és megvalósítási módja (nem állíthatom, hogy a kód optimálisan és hatékonyan lett megírva az összes összetevő képességeit kihasználva), talán a HBase gyorsítótár funkciói, a Windows 10 háttértevékenysége a laptopomon stb. Általában feltételezhetjük, hogy minden elméleti számítás kísérletileg igazolta érvényességét. Nos, vagy legalábbis nem lehetett ilyen „fejes rohammal” cáfolni őket.

Összefoglalva, ajánlások mindenkinek, aki csak most kezdi meg az adatmodellek tervezését a HBase-ben: vegye figyelembe a relációs adatbázisokkal végzett korábbi tapasztalatokat, és ne feledje a „parancsokat”:

  • A tervezés során az adatmanipuláció feladatából és mintáiból indulunk ki, nem pedig a tartománymodellből
  • Hatékony hozzáférés (teljes táblázat szkennelés nélkül) – csak kulccsal
  • Denormalizáció
  • A különböző sorok különböző oszlopokat tartalmazhatnak
  • Hangszórók dinamikus összetétele

Forrás: will.com

Hozzászólás