Introduktion
«Man mÄste springa för allt man Àr vÀrd för att bara stanna kvar,
och för att komma nÄgonstans mÄste man springa minst dubbelt sÄ snabbt!»
(c) Alice i Underlandet
För ett tag sedan blev jag ombedd att hÄlla en förelÀsning till analytikerna i vÄrt företag om datamodellering, eftersom vi, efter att ha suttit lÀnge pÄ projekt (ibland i flera Är), missar vad som hÀnder runt omkring i vÀrlden av IT-teknologier. I vÄrt företag (sÄ har det blivit) anvÀnds inte NoSQL-databaser pÄ mÄnga projekt (Ätminstone inte Àn), sÄ i min förelÀsning Àgnade jag sÀrskild uppmÀrksamhet Ät dem med HBase som exempel och försökte rikta presentationen till dem som aldrig har arbetat med dem. Jag illustrerade sÀrskilt nÄgra egenskaper av datamodellering med ett exempel som jag lÀste för flera Är sedan . Genom att analysera exemplen jÀmförde jag flera lösningar pÄ samma problem för att bÀttre förmedla de grundlÀggande idéerna till Ähörarna.
Nyligen, «för att ha nÄgot att göra», stÀllde jag mig frÄgan (de lÄnga majhelgerna i karantÀnlÀge gör detta sÀrskilt aktuellt) hur teoretiska slutsatser skulle stÀmma överens med praktiken? SÄ föddes idén till den hÀr artikeln. En utvecklare som har jobbat med NoSQL ett tag kanske inte kommer att fÄ ut nÄgot nytt av den (och kan dÀrför direkt scrolla igenom halva artikeln). Men för analytikerna, som Ànnu inte har arbetat nÀra med NoSQL, tror jag att den kommer att vara anvÀndbar för att fÄ grundlÀggande insikter om datamodellering för HBase.
Analys av exemplet
Enligt min Äsikt bör man tÀnka noga pÄ för- och nackdelar innan man börjar anvÀnda NoSQL-databaser. Ofta kan uppgiften sannolikt lösas Àven med traditionella relationsdatabaser. DÀrför Àr det bÀttre att inte anvÀnda NoSQL utan betydande skÀl. Om man ÀndÄ har beslutat att anvÀnda en NoSQL-databas, bör man beakta att designmetoderna hÀr skiljer sig nÄgot. SÀrskilt vissa av dem kan vara ovanliga för dem som tidigare endast har arbetat med relationsdatabaser (enligt mina observationer). SÄ i den "relationsbaserade" vÀrlden gÄr vi vanligtvis frÄn modellering av ÀmnesomrÄdet och sedan, vid behov, utför vi denormalisering av modellen. I NoSQL mÄste vi omedelbart ta hÀnsyn till de förvÀntade anvÀndningsscenarierna för data och initialt denormalisera data. Dessutom finns det en rad andra skillnader, som kommer att beskrivas nedan.
LÄt oss betrakta följande "syntetiska" uppgift, som vi kommer att arbeta med framöver:
Det Àr nödvÀndigt att designa en lagringsstruktur för en lista över anvÀndares vÀnner i ett visst abstrakt socialt nÀtverk. För att förenkla antar vi att alla relationer Àr riktade (som pÄ Instagram, inte pÄ LinkedIn). Strukturen bör möjliggöra effektivt:
- Att besvara frÄgan om anvÀndare A lÀser anvÀndare B (lÀsningsmönster)
- Möjliggöra att lÀgga till/ta bort relationer vid abonnemang/avprenumeration av anvÀndare A frÄn anvÀndare B (datamönster för förÀndring)
SjÀlvklart finns det mÄnga sÀtt att lösa uppgiften. I en vanlig relationsdatabas skulle vi förmodligen bara gjort en relations-tabell (möjligen typad, om vi till exempel behöver lagra en anvÀndargrupp: familj, arbete etc., som denna "vÀn" tillhör), och för att optimera Ätkomsthastigheten skulle vi ha lagt till index/partitionering. Troligtvis skulle den slutliga tabellen se ungefÀr ut sÄ hÀr:
user_id
friend_id
Vasya
Petya
Vasya
Olya
HÀr och framöver kommer jag för tydlighetens skull att ange namn istÀllet för ID
I fallet med HBase vet vi att:
- effektiv sökning som inte leder till fullstÀndig tabellskanning Àr möjligt exklusivt med nyckel
- Just dĂ€rför Ă€r det en dĂ„lig idĂ© att skriva de vanliga SQL-frĂ„gorna till sĂ„dana databaser; tekniskt sett kan du sjĂ€lvklart skicka en SQL-frĂ„ga med joins och annan logik frĂ„n samma Impala till HBase, men hur effektivt kommer det att varaâŠ
DÀrför mÄste vi anvÀnda anvÀndarens ID som nyckel. En första tanke kring "var och hur lagra vÀnners ID?" kan vara att lagra dem i kolumner. Det mest uppenbara och "naiva" alternativet kan se ut ungefÀr sÄ hÀr (lÄt oss kalla det Alternativ 1 (standard), för att referera till det senare):
RowKey
Kolumner
Vasya
1: Petya
2: Olya
3: Dasha
Petya
1: Masha
2: Vasya
HĂ€r motsvarar varje rad en anvĂ€ndare av nĂ€tverket. Kolumnerna har namn: 1, 2, ⊠â motsvarande antalet vĂ€nner, och i kolumnerna lagras vĂ€nners ID. Det Ă€r viktigt att notera att varje rad kan ha ett olika antal kolumner. I exemplet ovan har en rad tre kolumner (1, 2 och 3), medan den andra har endast tvĂ„ (1 och 2) â hĂ€r anvĂ€nde vi tvĂ„ egenskaper hos HBase som inte finns i relationsdatabaser:
- möjligheten att dynamiskt Àndra sammansÀttningen av kolumner (lÀgger till en vÀn -> lÀgger till en kolumn, tar bort en vÀn -> tar bort en kolumn)
- olika rader kan ha olika sammansÀttningar av kolumner
LÄt oss nu kontrollera vÄr struktur mot kraven i uppgiften:
- LÀsa data: för att förstÄ om Vasya följer Olya mÄste vi lÀsa hela raden med nyckeln RowKey = "Vasya" och gÄ igenom kolumnvÀrdena tills vi "trÀffar" Olya. Eller gÄ igenom vÀrdena för alla kolumner, "inte trÀffa" Olya och returnera False;
- Ăndra data: lĂ€gga till en vĂ€n: för en sĂ„dan uppgift behöver vi ocksĂ„ lĂ€sa hela raden med nyckeln RowKey = "Vasya", för att rĂ€kna det totala antalet av hans vĂ€nner. Detta totala antal vĂ€nner behöver vi för att bestĂ€mma kolumnnumret dĂ€r vi ska skriva ID för den nya vĂ€nnen.
- Ăndra data: ta bort en vĂ€n:
- Det behövs en lÀsning hela raden med nyckeln RowKey = "Vasya" och gÄ igenom kolumnerna för att hitta den som innehÄller den borttagna vÀnnen;
- Sedan mÄste vi efter att ha tagit bort vÀnnen "flytta" alla data en kolumn över, sÄ att vi inte fÄr nÄgra "hÄl" i deras numrering.
LÄt oss nu bedöma hur effektiva de algoritmer som vi mÄste implementera pÄ sidan av "det hypotetiska programmet" blir, genom att anvÀnda LÄt oss definiera storleken pÄ vÄrt hypotetiska sociala nÀtverk som n. Den maximala antalet vÀnner en anvÀndare kan ha Àr (n-1). Denna (-1) kan vi bortse ifrÄn för vÄra syften, eftersom den Àr obetydlig inom ramen för anvÀndning av O-symbolik.
- LÀsa data: det Àr nödvÀndigt att lÀsa hela raden och gÄ igenom alla dess kolumner. SÄledes blir den övre grÀnsen för kostnaden cirka O(n)
- Ăndra data: lĂ€gga till en vĂ€n: för att faststĂ€lla antalet vĂ€nner mĂ„ste vi gĂ„ igenom alla kolumner i raden, varefter vi lĂ€gger till en ny kolumn => O(n)
- Ăndra data: ta bort en vĂ€n:
- PĂ„ liknande sĂ€tt som vid tillĂ€gg â det krĂ€vs att gĂ„ igenom alla kolumner => O(n)
- Efter att ha tagit bort kolumnerna mĂ„ste vi âflyttaâ dem. Om vi genomför detta âdirektâ, krĂ€vs det ytterligare upp till (n-1) operationer. Men hĂ€r och framĂ„t kommer vi att tillĂ€mpa en annan metod i den praktiska delen, som kommer att genomföra en âpseudo-flyttâ pĂ„ ett fast antal operationer â det vill sĂ€ga, det kommer att ta konstant tid oavsett n. Denna konstanta tiden (om vi ska vara exakta, O(2)) kan bortses ifrĂ„n jĂ€mfört med O(n). Metoden illustreras i bilden nedan: vi kopierar helt enkelt data frĂ„n den âsistaâ kolumnen till den dĂ€r vi mĂ„ste ta bort data, varefter vi tar bort den sista kolumnen:

Sammanfattningsvis har vi i alla scenarier fÄtt en asymptotisk berÀkningskomplexitet O(n).
Du har kanske redan lagt mĂ€rke till att vi nĂ€stan alltid mĂ„ste lĂ€sa hela raden frĂ„n databasen, och i tvĂ„ av tre fall bara för att gĂ„ igenom alla kolumner och rĂ€kna det totala antalet vĂ€nner. DĂ€rför, som ett försök till optimering, kan vi lĂ€gga till en kolumn âcountâ dĂ€r det totala antalet vĂ€nner för varje anvĂ€ndare i nĂ€tverket lagras. PĂ„ det hĂ€r sĂ€ttet behöver vi inte lĂ€sa hela raden för att rĂ€kna det totala antalet vĂ€nner, utan kan lĂ€sa endast en kolumn âcountâ. Det viktigaste Ă€r att inte glömma att uppdatera âcountâ nĂ€r vi manipulerar med data. SĂ„ledes fĂ„r vi en förbĂ€ttrad Alternativ 2 (count):
RowKey
Kolumner
Vasya
1: Petya
2: Olya
3: Dasha
count: 3
Petya
1: Masha
2: Vasya
count: 2
JÀmfört med det första alternativet:
- LĂ€sa data: för att fĂ„ svaret pĂ„ frĂ„gan âLĂ€ser Vasja Olya?â har inget förĂ€ndrats => O(n)
- Ăndra data: lĂ€gga till en vĂ€n: Vi har förenklat införandet av en ny vĂ€n, eftersom vi nu inte behöver gĂ„ igenom hela raden och iterera över dess kolumner, utan kan fĂ„ vĂ€rdet frĂ„n kolumnen "count" och dĂ€rmed direkt bestĂ€mma vilken kolumn som ska anvĂ€ndas för att införa en ny vĂ€n. Detta minskar den berĂ€kningsmĂ€ssiga komplexiteten till O(1)
- Ăndra data: ta bort en vĂ€n: NĂ€r vi tar bort en vĂ€n kan vi ocksĂ„ anvĂ€nda denna kolumn för att minska antalet in- och utdataoperationer vid "skiftningen" av data en cell Ă„t vĂ€nster. Men behovet av att iterera genom kolumnerna för att hitta den som ska tas bort kvarstĂ„r, sĂ„ => O(n)
- à andra sidan mÄste vi nu vid uppdatering av data varje gÄng ocksÄ uppdatera kolumnen "count", men detta tar konstant tid, vilket i O-notering kan försummas
Ăverlag framstĂ„r alternativ 2 som nĂ„got mer optimalt, men det Ă€r snarare en "evolution Ă€n en revolution". För att genomföra en "revolution" behöver vi Alternativ 3 (col).
LÄt oss vÀnda allt "upp och ner": vi namnger kolumnen med anvÀndarens identifierare! Vad som kommer att skrivas i sjÀlva kolumnen spelar ingen roll för oss, lÄt det vara siffran 1 (allmÀnt kan vi lagra exempelvis gruppen "familj/vÀnner/osv."). Denna metod kan överraska den ovana "medborgaren", som inte haft erfarenhet av NoSQL-databaser, men just den gör det möjligt att utnyttja potentialen hos HBase i detta uppdrag mycket mer effektivt:
RowKey
Kolumner
Vasya
Petya: 1
Olya: 1
Dasha: 1
Petya
Masha: 1
Vasya: 1
HÀr fÄr vi omedelbart flera fördelar. För att förstÄ dem, lÄt oss analysera den nya strukturen och bedöma den berÀkningsmÀssiga komplexiteten:
- LĂ€sa data: för att svara pĂ„ frĂ„gan om Vasya har prenumererat pĂ„ Olya, rĂ€cker det att lĂ€sa en kolumn "Olya": om den finns, Ă€r svaret True, om inte â False => O(1)
- Ăndra data: lĂ€gga till en vĂ€n: TillsĂ€ttning av en vĂ€n: det rĂ€cker med att bara lĂ€gga till en ny kolumn "vĂ€ns ID" => O(1)
- Ăndra data: ta bort en vĂ€n: det rĂ€cker med att bara ta bort kolumnen "vĂ€ns ID" => O(1)
Som vi ser Ă€r en betydande fördel med denna lagringsmodell att vi i alla vĂ„ra nödvĂ€ndiga scenarier endast arbetar med en kolumn, vilket undviker att lĂ€sa hela raden frĂ„n databasen och förstĂ„s att iterera genom alla kolumner i denna rad. Det skulle kunna vara slutet pĂ„ detta, menâŠ
Man kan fundera pÄ att gÄ lÀngre i att optimera prestanda och minska in- och utdataoperationer nÀr det gÀller databasen. Vad sÀgs om att lagra fullstÀndig informationskoppling direkt i nyckeln för raden? Det vill sÀga göra nyckeln sammansatt i formen userID.friendID? I sÄ fall kan vi inte ens behöva lÀsa kolumnerna i raden.Alternativ 4(row)):
RowKey
Kolumner
Vasya.Petya
Petya: 1
Vasya.Olya
Olya: 1
Vasya.Dasha
Dasha: 1
Petya.Masha
Masha: 1
Petya.Vasya
Vasya: 1
Det Àr uppenbart att bedömningen av alla scenarier för datamanipulation i en sÄdan struktur, precis som i den tidigare varianten, ocksÄ kommer att vara O(1). Skillnaden med alternativ 3 kommer att ligga uteslutande i effektiviteten för in- och utdataoperationer i databasen.
Och den sista "slipsen". Det Àr enkelt att se att i alternativ 4 kommer nyckeln för raden att ha en variabel lÀngd, vilket eventuellt kan pÄverka prestandan (hÀr pÄminner vi oss om att HBase lagrar data som en uppsÀttning byte och rader i tabeller sorteras efter nyckel). Dessutom har vi en avskiljare som i vissa scenarier kan behöva bearbetas. För att utesluta denna pÄverkan kan vi anvÀnda hashvÀrden frÄn userID och friendID, och eftersom bÄda hashvÀrdena kommer att ha konstant lÀngd kan vi helt enkelt konkatenera dem utan avskiljare. DÄ kommer datan i tabellen att se ut sÄ hÀr:Alternativ 5(hash)):
RowKey
Kolumner
dc084ef00e94aef49be885f9b01f51c01918fa783851db0dc1f72f83d33a5994
Petya: 1
dc084ef00e94aef49be885f9b01f51c0f06b7714b5ba522c3cf51328b66fe28a
Olya: 1
dc084ef00e94aef49be885f9b01f51c00d2c2e5d69df6b238754f650d56c896a
Dasha: 1
1918fa783851db0dc1f72f83d33a59949ee3309645bd2c0775899fca14f311e1
Masha: 1
1918fa783851db0dc1f72f83d33a5994dc084ef00e94aef49be885f9b01f51c0
Vasya: 1
Det Ă€r uppenbart att den algoritmiska komplexiteten för att arbeta med en sĂ„dan struktur i de scenarier vi övervĂ€ger kommer att vara densamma som för alternativ 4 â det vill sĂ€ga O(1).
Sammanfattningsvis, lÄt oss sammanfatta alla vÄra bedömningar av den berÀkningsmÀssiga komplexiteten i en tabell:
LÀgga till vÀn
Kontrollera vÀn
Ta bort vÀn
Alternativ 1 (standard)
O(n)
O(n)
O(n)
Alternativ 2 (count)
O(1)
O(n)
O(n)
Alternativ 3 (column)
O(1)
O(1)
O(1)
Alternativ 4 (row)
O(1)
O(1)
O(1)
Alternativ 5 (hash)
O(1)
O(1)
O(1)
Som det framgÄr verkar alternativ 3-5 vara de mest föredragna och teoretiskt sett sÀkerstÀller de att alla nödvÀndiga datamanipulationsscenarier kan utföras pÄ konstant tid. I vÄr uppgift finns det inget explicit krav pÄ att fÄ en lista över alla anvÀndarens vÀnner, men i verkliga projekt skulle det vara bra för oss som analytiker att "förespegla" att en sÄdan uppgift kan uppstÄ och "steka halm", sÄ att sÀga. DÀrför lutar jag Ät alternativ 3. Men det Àr fullt möjligt att detta krav i ett verkligt projekt redan har lösts med andra medel, sÄ utan en övergripande förstÄelse av hela uppgiften bör man inte dra nÄgra definitiva slutsatser.
Förberedelse av experimentet
De ovanstĂ„ende teoretiska resonemangen skulle vi vilja pröva i praktiken â och det var mĂ„let med den idĂ© som uppstod under de lĂ„nga helgerna. För detta behöver vi bedöma hastigheten pĂ„ vĂ„rt "hypotetiska program" i alla de beskrivna anvĂ€ndarscenarierna samt hur denna tid ökar med storleken pĂ„ det sociala nĂ€tverket (n). Den mĂ„lparameter vi Ă€r intresserade av och som vi kommer att mĂ€ta under experimentet Ă€r den tid som det "hypotetiska programmet" lĂ€gger pĂ„ att utföra en "affĂ€rsoperation". Med "affĂ€rsoperation" menar vi en av följande:
- LÀgga till en ny vÀn
- Kontrollera om anvÀndare A Àr vÀn med anvÀndare B
- Ta bort en vÀn
SÄledes, med hÀnsyn till de krav som angivits i den ursprungliga uppgiften, framtrÀder följande scenario för kontroll:
- Skriva data. Generera slumpmĂ€ssigt ett ursprungligt nĂ€tverk av storlek n. För att nĂ€rma oss "verkliga vĂ€rlden" Ă€r antalet vĂ€nner per anvĂ€ndare ocksĂ„ en slumpmĂ€ssig variabel. MĂ€t tiden som vĂ„rt "hypotetiska program" tar för att skriva alla genererade data i HBase. Dela sedan den uppmĂ€tta tiden med det totala antalet tillagda vĂ€nner â sĂ„ fĂ„r vi den genomsnittliga tiden för en "affĂ€rsoperation".
- LÀsa data. För varje anvÀndare skapa en lista över
- Borttagning av data. Ta bort alla vÀnskapsförbindelser för anvÀndaren. Borttagningsordningen ska vara slumpmÀssig (det vill sÀga
Scenarierna mÄste köras för varje av de fem modellerna för data och för olika storlekar av sociala nÀtverk, för att se hur tiden förÀndras med dess tillvÀxt. Inom varje n-lÀnk i nÀtverket och listan över anvÀndare för kontroll mÄste, naturligtvis, vara desamma för alla fem varianter.
För bÀttre förstÄelse, nedan ger jag ett exempel pÄ genererade data för n= 5. Den skrivna "generatorn" ger ut tre ordböcker med ID:n:
- den första - för insÀttning
- den andra - för kontroll
- den tredje - för borttagning
{0: [1], 1: [4, 5, 3, 2, 1], 2: [1, 2], 3: [2, 4, 1, 5, 3], 4: [2, 1]} # totalt 15 vÀnner
{0: [1, 10800], 1: [5, 10800, 2, 10801, 4, 10802], 2: [1, 10800], 3: [3, 10800, 1, 10801, 5, 10802], 4: [2, 10800]} # totalt 18 kontrollerade subjekt
{0: [1], 1: [1, 3, 2, 5, 4], 2: [1, 2], 3: [4, 1, 2, 3, 5], 4: [1, 2]} # totalt 15 vÀnner
Som man kan se, alla ID:n större Àn 10 000 i ordboken för kontroll Àr just de som med sÀkerhet kommer att ge svaret False. InsÀttning, kontroll och borttagning av "vÀnner" genomförs precis i den ordning som anges i ordboken.
Experimentet genomfördes pĂ„ en bĂ€rbar dator som kör Windows 10, dĂ€r en Docker-container körde en HBase-databas, medan en annan körde Python med Jupyter Notebook. Docker tilldelades 2 CPU-kĂ€rnor och 2 GB RAM. All logik, bĂ„de emuleringen av "det hypotetiska programmet" och "infrastrukturen" för att generera testdata och mĂ€ta tid skrevs i Python. För att arbeta med HBase anvĂ€ndes biblioteket , för att berĂ€kna hashvĂ€rden (MD5) för alternativ 5 â hashlib
Med hĂ€nsyn till den specifika bĂ€rbar datorns berĂ€kningskraft valdes experimentellt starten för n = 10, 30, âŠ. 170 â nĂ€r den totala tiden för hela testcykeln (alla scenarier för alla alternativ för alla n) fortfarande var mer eller mindre rimlig och fick plats under en kopp te (i genomsnitt 15 minuter).
HĂ€r mĂ„ste jag pĂ„peka att vi i detta experiment frĂ€mst bedömer inte absoluta prestationstal. Ăven en relativ jĂ€mförelse mellan de tvĂ„ olika alternativen kan vara nĂ„got otillförlitlig. Just nu Ă€r vi intresserade av hur tiden förĂ€ndras beroende pĂ„ n, eftersom det med hĂ€nsyn till den ovan nĂ€mnda konfigurationen av "testbĂ€nken" Ă€r mycket svĂ„rt att fĂ„ tidsuppskattningar som Ă€r "rensade" frĂ„n pĂ„verkan av slumpmĂ€ssiga och andra faktorer (och ett sĂ„dant mĂ„l har inte stĂ€llts).
Experimentresultatet
Det första testet â hur tiden som anvĂ€nds för att fylla i vĂ€nlistan förĂ€ndras. Resultatet â i diagrammet nedan.

Alternativen 3-5 visar som förvÀntat praktiskt konstant tid för "affÀrsoperationen", som inte beror pÄ nÀtverksstorlekens tillvÀxt och ingen mÀrkbar skillnad i prestanda.
Alternativ 2 visar ocksĂ„ konstant, men nĂ„got sĂ€mre prestanda, nĂ€stan exakt 2 gĂ„nger jĂ€mfört med alternativen 3-5. Detta Ă€r glĂ€djande, eftersom det stĂ€mmer överens med teorin â i detta alternativ Ă€r antalet in- och utdataoperationer till/frĂ„n HBase faktiskt 2 gĂ„nger fler. Detta kan fungera som indirekt bevis pĂ„ att vĂ„r testbĂ€nk i grunden ger en hyfsad noggrannhet.
Alternativ 1 visar sig ocksÄ vara det lÄngsammaste och demonstrerar en linjÀr ökning av tiden som krÀvs för att lÀgga till en vÀn i takt med nÀtverksstorleken.
LÄt oss nu titta pÄ resultaten frÄn det andra testet.

Alternativen 3-5 uppför sig förutsĂ€gbart â konstant tid som inte beror pĂ„ nĂ€tverksstorleken. Alternativen 1 och 2 visar en linjĂ€r ökning av tiden nĂ€r nĂ€tverksstorleken ökar och liknande prestanda. Alternativ 2 Ă€r dock nĂ„got lĂ„ngsammare â uppenbarligen pĂ„ grund av behovet av att lĂ€sa och bearbeta den extra kolumnen "count", vilket blir mer mĂ€rkbart nĂ€r n ökar. Men jag avstĂ„r Ă€ndĂ„ frĂ„n att dra nĂ„gra slutsatser, eftersom noggrannheten i denna jĂ€mförelse Ă€r relativt lĂ„g. Dessutom varierade dessa relationer (vilket alternativ, 1 eller 2, Ă€r snabbare) frĂ„n körning till körning (medan de upprĂ€tthöll karaktĂ€ren av beroendeförhĂ„llandet och "gick nĂ€sa vid nĂ€sa").
Och den sista grafen â resultatet av borttagningstestet.

HÀr Àr det Äterigen utan överraskningar. Alternativen 3-5 utför borttagning pÄ konstant tid.
Fascinerande nog visar alternativ 4 och 5, till skillnad frÄn de tidigare scenarierna, nÄgot sÀmre prestanda Àn alternativ 3. Uppenbarligen Àr borttagning av en rad mer kostsam Àn borttagning av en kolumn, vilket Àr logiskt.
Alternativen 1 och 2 visar förutsĂ€gbart en linjĂ€r ökning av tiden. Dessutom Ă€r alternativ 2 konsekvent lĂ„ngsammare Ă€n alternativ 1 â pĂ„ grund av den extra in- och utmatningsoperationen för "underhĂ„ll" av kolumnen count.
AllmÀnna slutsatser frÄn experimentet:
- Alternativen 3-5 visar högre effektivitet eftersom de utnyttjar fördelarna med HBase; deras prestanda skiljer sig Ät med en konstant och beror inte pÄ nÀtverksstorleken.
- Skillnaden mellan alternativen 4 och 5 registrerades inte. Men det betyder inte att alternativ 5 inte bör anvÀndas. Det Àr fullt möjligt att det experimentella scenariot, med hÀnsyn till testbÀnkes specifikationer, inte möjliggjorde att den skulle identifieras.
- KaraktÀren av tidstillvÀxten för "affÀrsoperationer" med data bekrÀftade i stort sett tidigare teoretiska slutsatser för alla alternativ.
Epilog
Genomförda grova experiment bör inte betraktas som absolut sanning. Det finns flera faktorer som inte har beaktats och som förvrĂ€nger resultaten (sĂ€rskilt tydligt synligt i graferna vid smĂ„ nĂ€tverksstorlekar). Till exempel hastigheten pĂ„ thrift som anvĂ€nds av happybase, mĂ€ngden och sĂ€ttet för implementationen av logiken som jag hade skrivit i Python (jag pĂ„stĂ„r inte att koden var skriven optimalt och nyttjade alla komponenters kapabiliteter effektivt), eventuella egenskaper av HBase-cache, bakgrundsaktiviteter pĂ„ Windows 10 pĂ„ min bĂ€rbara dator osv. Ăvergripande kan man hĂ€vda att alla teoretiska utlĂ€ggningar experimentellt visade sin giltighet. Eller Ă„tminstone gick det inte att motbevisa dem med ett sĂ„dant "rakt angrepp".
Till sist - rekommendationer till alla som just börjat designa datamodeller i HBase: abstrahera utifrÄn tidigare erfarenheter med relationsdatabaser och kom ihÄg "budorden":
- NÀr vi designar, utgÄr vi frÄn uppgiften och mönster för datamanipulation, inte frÄn modellen för ÀmnesomrÄdet.
- Effektiv Ă„tkomst (utan fullstĂ€ndig tabellskanning) â endast via nyckel.
- Deniormalisering.
- Olika rader kan innehÄlla olika kolumner.
- Dynamiskt kolumninnehÄll.
KĂ€lla: habr.com

