Karakteristikat e projektimit të modeleve të dhënave për NoSQL

Hyrje

Karakteristikat e projektimit të modeleve të dhënave për NoSQL «Duhet të vraposh me të gjitha forcat, vetëm për të mbetur në vend,
dhe për të shkuar diku, duhet të vraposh të paktën dy herë më shpejt!»
(c) Alicia në vendin e mrekullive

Disa kohë më parë më kërkuan të lexoj një leksion analistëve të kompanisë sonë mbi temat e projektimit të modeleve të dhënave, sepse duke qëndruar për një kohë të gjatë në projekte (ndonjëherë për disa vite) ne humbasim për atë që po ndodh rreth nesh në botën e teknologjive IT. Në kompaninë tonë (ndodhi kështu) në shumë projekte nuk përdoren bazat e dhënave NoSQL (të paktën deri tani), prandaj në leksionin tim i kushtova disa vëmendje atyre në shembullin HBase dhe përpiqesha ta orientoj materialin për ata që kurrë nuk kanë punuar me to. Në veçanti, ilustrova disa karakteristika të projektimit të modelit të dhënave në një shembull që disa vite më parë e lexova në artikullin «Introduction to HBase Schema Design» nga Amandeep Khurana. Duke analizuar shembujt, krahasova disa variante të zgjidhjes së të njëjtës problem, për të komunikuar më mirë idetë kryesore te dëgjuesit.

Së fundmi, ndërsa isha duke u mërzitur, më erdhi në mendje pyetja (fundjavat e gjata të majit në karantinë ndihmojnë në këtë drejtim), sa teoritë do të korrespondojnë me praktikat? Kështu lindi ideja e këtij artikulli. Një zhvillues, i cili ka punuar për një kohë të gjatë me NoSQL, mund të mos marrë ndonjë gjë të re nga ai (prandaj mund të kalojë gjysmë artikulli menjëherë). Por për analistët, të cilët nuk kanë punuar ngushtë me NoSQL, besoj se do të jetë e dobishme për të marrë një kuptim bazik të karakteristikave të projektimit të modeleve të dhënash për HBase.

Analizimi i shembujve

Sipas mendimit tim, para se të filloni përdorimin e bazave të dhënash NoSQL, duhet të mendoni mirë dhe të peshojmë "për" dhe "kundër". Shpesh, një detyrë mund të zgjidhet edhe me sistemet tradicionale relacionale të menaxhimit të të dhënave. Prandaj, është më mirë të mos përdorni NoSQL pa baza të rëndësishme. Nëse vendosni gjithsesi të përdorni një bazë të dhënash NoSQL, duhet të keni parasysh se qasjet ndaj projektimit këtu janë paksa të ndryshme. Sidomos disa prej tyre mund të jenë të pazakonta për ata që kanë punuar vetëm me sistemet relacionale të menaxhimit të të dhënave (sipas vëzhgimeve të mia). Kështu, në botën "relacionale" ne zakonisht fillojmë nga modelimi i fushës së objektit dhe më pas, kur është e nevojshme, kryejmë de-normalizimin e modelit. Në NoSQL, ne duhet të marrim parasysh menjëherë skenarët e parashikuar për punën me të dhënat , dhe fillimisht të de-normalizojmë të dhënat. Përveç kësaj, ka një sërë dallimesh të tjera, për të cilat do të shkruhet më poshtë.

Le të shqyrtojmë detyrën e mëposhtme "sintetike", me të cilën do të punojmë më tej:

Duhet ndërtuar struktura e ruajtjes së listës së miqve të përdoruesve në një rrjet social abstrakt. Për ta thjeshtuar, do të supozojmë se të gjitha lidhjet janë të drejtuara (si në Instagram, e jo në LinkedIn). Strukturën duhet ta lejojë të ndihmojë efikasitetin:

  • TĂ« pĂ«rgjigjet nĂ« pyetjen, a e lexon pĂ«rdoruesi A pĂ«rdoruesin B (shablloni i leximit)
  • TĂ« lejojĂ« shtimin/fshirjen e lidhjeve nĂ« rastin e subscribimit/ndalimit tĂ« pĂ«rdoruesit A nga pĂ«rdoruesi B (shablloni i ndryshimit tĂ« tĂ« dhĂ«nave)

Sigurisht, ka shumë mënyra për zgjidhjen e problemit. Në një DB relacional normale, ne ndoshta do të bënim vetëm një tabelë lidhjesh (ndoshta të tipizuar, nëse, për shembull, kërkohet të ruajmë grupin e përdoruesve: familja, puna etj., në të cilin përfshihet ky "mik"), dhe për optimizimin e shpejtësisë së aksesit do të shtonim indekse/particionim. Tabelën përfundimtare do të duket më pak kështu:

user_id
friend_id

Vasja
Petja

Vasja
Olja

këtu dhe më tej për qartësi dhe kuptim më të mirë, në vend të ID-së do të përdor emrat

Në rastin e HBase e dimë se:

  • kĂ«rkimi efikas, qĂ« nuk çon nĂ« skanimin e plotĂ« tĂ« tabelĂ«s, Ă«shtĂ« i mundur exkluzivisht sipas çelĂ«sit
    • Prandaj, tĂ« shkruash pyetje SQL qĂ« shumĂ« njerĂ«z i njohin nĂ« baza tĂ« tilla Ă«shtĂ« njĂ« ide e keqe; teknikisht, sigurisht, mund tĂ« dĂ«rgosh njĂ« pyetje SQL me Join dhe logjikĂ« tĂ« tjera nĂ« HBase nga Impala, por sa efikase do tĂ« jetë 

Prandaj, ID e përdoruesit jemi të detyruar ta përdorim si çelës. Një mendim fillestar për "ku dhe si ta ruajmë ID e miqve?" mund të jetë ideja e ruajtjes së tyre në kolona. Ky variant më i dukshëm dhe "naiv" do të dukej kështu (ta quajmë Varianti 1 (default), për t'u referuar më vonë):

RowKey
Kolona

Vasja
1: Petja
2: Olya
3: Dasha

Petja
1: Masha
2: Vasya

KĂ«tu, çdo rresht korrespondon me njĂ« pĂ«rdorues tĂ« vetĂ«m tĂ« rrjetit. Kolonat kanĂ« emra: 1, 2, 
 - sipas numrit tĂ« miqve, dhe nĂ« kolonat ruhen ID e miqve. ËshtĂ« e rĂ«ndĂ«sishme tĂ« theksohet se çdo rresht do tĂ« ketĂ« njĂ« numĂ«r tĂ« ndryshĂ«m kolonash. NĂ« shembullin e mĂ«sipĂ«rm, njĂ« rresht ka tre kolona (1, 2 dhe 3), ndĂ«rsa tjetri - vetĂ«m dy (1 dhe 2) - kĂ«tu ne vetĂ« kemi shfrytĂ«zuar dy karakteristika tĂ« HBase qĂ« nuk i kanĂ« databazat relacionale:

  • mundĂ«sinĂ« pĂ«r tĂ« ndryshuar dinamikisht pĂ«rbĂ«rjen e kolonave (shtojmĂ« njĂ« mik -> shtojmĂ« kolonĂ«, heqim njĂ« mik -> heqim kolonĂ«)
  • nĂ« rreshta tĂ« ndryshĂ«m mund tĂ« ketĂ« pĂ«rbĂ«rje tĂ« ndryshme kolonash

Le të kontrollojmë strukturën tonë për t'u siguruar që përmbush kërkesat e detyrës:

  • Leximi i tĂ« dhĂ«nave: pĂ«r tĂ« kuptuar nĂ«se Vasja Ă«shtĂ« i regjistruar pĂ«r Olyn, do tĂ« duhet tĂ« lexojmĂ« gjithĂ« rreshtin sipĂ«r çelĂ«sit RowKey = «Vasja» dhe tĂ« kalojmĂ« pĂ«rmes vlerave tĂ« kolonave derisa tĂ« «takojmë» Olyn. Ose tĂ« kalojmĂ« pĂ«rmes tĂ« gjithĂ« vlerave tĂ« kolonave, «tĂ« mos takojmë» Olyn dhe tĂ« kthejmĂ« pĂ«rgjigjen False;
  • Ndryshimi i tĂ« dhĂ«nave: shtimi i njĂ« shoku: pĂ«r njĂ« detyrĂ« tĂ« tillĂ« gjithashtu do tĂ« na duhet tĂ« lexojmĂ« gjithĂ« rreshtin sipĂ«r çelĂ«sit RowKey = «Vasja», pĂ«r tĂ« numĂ«ruar gjithsej shokĂ«t e tij. Ky numĂ«r i pĂ«rgjithshĂ«m i shokĂ«ve na nevojitet pĂ«r tĂ« pĂ«rcaktuar numrin e kolonĂ«s ku duhet tĂ« regjistrojmĂ« ID-nĂ« e shokut tĂ« ri.
  • Ndryshimi i tĂ« dhĂ«nave: heqja e njĂ« shoku:
    • Duhet tĂ« lexojmĂ« gjithĂ« rreshtin sipĂ«r çelĂ«sit RowKey = «Vasja» dhe tĂ« kalojmĂ« pĂ«rmes kolonave pĂ«r tĂ« gjetur atĂ« kolonĂ« ku Ă«shtĂ« regjistruar shoku qĂ« po hiqet;
    • MĂ« pas, pas heqjes sĂ« shokut, na duhet tĂ« «shkallĂ«zojmë» tĂ« dhĂ«nat nĂ« njĂ« kolone, pĂ«r tĂ« mos marrĂ« «gaps» nĂ« numĂ«rimin e tyre.

Tani le të vlerësojmë se sa efikase do të jenë algoritmet që duhet të implementojmë në anën e «aplikacionit të supozuar», duke përdorur O-simbolikën. Le të shënojmë madhësinë e rrjetit tonë hipotetik social si n. Atëherë numri maksimal i miqve që një përdorues mund të ketë është (n-1). Këtë (-1) mund ta injorojmë për qëllimet tona, pasi në përputhje me simbolet O, është e parëndësishme.

  • Leximi i tĂ« dhĂ«nave: Ă«shtĂ« e nevojshme tĂ« lexojmĂ« tĂ«rĂ« rreshtin dhe tĂ« shqyrtojmĂ«, nĂ« kufirin, tĂ« gjitha kolonnat e tij. Pra, vlerĂ«simi i sipĂ«rm i shpenzimeve do tĂ« jetĂ« pĂ«rafĂ«rsisht O(n)
  • Ndryshimi i tĂ« dhĂ«nave: shtimi i njĂ« shoku: pĂ«r tĂ« pĂ«rcaktuar numrin e miqve, Ă«shtĂ« e nevojshme tĂ« kalojmĂ« nĂ«pĂ«r tĂ« gjitha kolonnat e rreshtit, pas tĂ« cilave shtojmĂ« njĂ« kolonĂ« tĂ« re => O(n)
  • Ndryshimi i tĂ« dhĂ«nave: heqja e njĂ« shoku:
    • NjĂ«soj si shtimi – Ă«shtĂ« e nevojshme tĂ« kalojmĂ«, nĂ« kufirin, tĂ« gjitha kolonnat => O(n)
    • Pas pastrimit tĂ« kolonave, na nevojitet t'i "zhvendosim" ato. NĂ«se e realizojmĂ« kĂ«tĂ« "drejt", nĂ« limit do tĂ« nevojiten (n-1) operacione tĂ« tjera. Por kĂ«tu dhe mĂ« tej nĂ« pjesĂ«n praktike do tĂ« aplikojmĂ« njĂ« qasje tjetĂ«r, e cila do tĂ« realizojĂ« njĂ« "pseudo-zhvendosje" me njĂ« numĂ«r tĂ« fiksuar operacionesh - pra, do tĂ« harxhojĂ« kohĂ« konstante pa marrĂ« parasysh n. Ky kohĂ« konstant (nĂ«se jemi tĂ« saktĂ«, O(2)) nĂ« krahasim me O(n) mund tĂ« injorohet. Qasja ilustrohet nĂ« figurĂ«n mĂ« poshtĂ«: ne thjesht kopjojmĂ« tĂ« dhĂ«nat nga kolona "fundore" nĂ« atĂ« nga e cila duam tĂ« heqim tĂ« dhĂ«nat, pas sĂ« cilĂ«s e fshijmĂ« kolonĂ«n e fundit:
      Karakteristikat e projektimit të modeleve të dhënave për NoSQL

Si pasojë, në të gjitha skenarët kemi arritur një kompleksitet asimptotik të llogaritjes O(n).
Besoj se tashmë e keni vënë re se na duhet pothuajse gjithmonë të lexojmë tërë rreshtin nga baza e të dhënave, dhe duke qenë se në dy nga tri rastet, e bëjmë këtë vetëm për të kaluar nëpër të gjitha kolonat dhe për të llogaritur numrin e përgjithshëm të miqve. Prandaj, si një përpjekje për optimizim, mund të shtojmë një kolonë "count", në të cilën të ruhet numri total i miqve të çdo përdoruesi të rrjetit. Në këtë rast, ne nuk kemi nevojë të lexojmë tërë rreshtin për të llogaritur numrin total të miqve, por mund të lexojmë vetëm një kolonë "count". E rëndësishme është të mos harrojmë të përditësojmë "count" kur manipulojmë me të dhënat. Kështu, arrijmë një përmirësim Opsioni 2 (count):

RowKey
Kolona

Vasja
1: Petja
2: Olya
3: Dasha
count: 3

Petja
1: Masha
2: Vasya

count: 2

Në krahasim me opsionin e parë:

  • Leximi i tĂ« dhĂ«nave: pĂ«r tĂ« marrĂ« pĂ«rgjigjen pĂ«r pyetjen "A e lexon Vania OlĂ«n?" nuk ka ndryshuar => O(n)
  • Ndryshimi i tĂ« dhĂ«nave: shtimi i njĂ« shoku: Kemi thjeshtuar futjen e njĂ« gjyshi tĂ« ri, pasi tani nuk kemi nevojĂ« tĂ« lexojmĂ« tĂ«rĂ« rreshtin dhe tĂ« kalojmĂ« nĂ«pĂ«r kolonat e tij, por mund tĂ« marrim vetĂ«m vlerĂ«n e kolonĂ«s "count" dhe kĂ«shtu tĂ« pĂ«rcaktojmĂ« menjĂ«herĂ« numrin e kolonĂ«s pĂ«r futjen e gjyshit tĂ« ri. Kjo çon nĂ« njĂ« ulje tĂ« kompleksitetit tĂ« llogaritjes deri nĂ« O(1)
  • Ndryshimi i tĂ« dhĂ«nave: heqja e njĂ« shoku: Kur gjatĂ« fshirjes sĂ« njĂ« shoku, ne gjithashtu mund tĂ« pĂ«rdorim kĂ«tĂ« kolonĂ« pĂ«r tĂ« reduktuar numrin e operacioneve tĂ« hyres pĂ«r tĂ« "shkruar" tĂ« dhĂ«nat njĂ« hap majtas. Por nevoja pĂ«r tĂ« kaluar kolonat pĂ«r tĂ« gjetur atĂ« qĂ« duhet tĂ« fshihet mbetet, kĂ«shtu qĂ« => O(n)
  • Nga ana tjetĂ«r, tani nĂ« azhurnimin e tĂ« dhĂ«nave, na nevojitet tĂ« azhurnojmĂ« gjithashtu kolonĂ«n "count" çdo herĂ«, por kjo merr njĂ« kohĂ« konstante, e cila nĂ« kuadrin e simbolikĂ«s O mund tĂ« injorohet.

Në përgjithësi, opsioni 2 duket pak më optimal, por kjo është më shumë "evolucion në vend të revolucionit". Për të realizuar një "revolucion", na nevojitet Opsioni 3 (col).
TĂ« pĂ«rmbysim gjithçka "me kokĂ« poshtĂ«": caktojmĂ« emrin e kolonĂ«s si identifikuesin e pĂ«rdoruesit.! ÇfarĂ« do tĂ« regjistrohet nĂ« kolonĂ« - pĂ«r ne nuk ka rĂ«ndĂ«si, le tĂ« jetĂ« numri 1 (nĂ« pĂ«rgjithĂ«si, nga e dobishme atje mund tĂ« ruhet, pĂ«r shembull, grupi "familje/miq/etj."). Ky qasje mund tĂ« befasojĂ« njĂ« "tĂ« zakonshĂ«m" tĂ« papĂ«rgatitur, i cili nuk kishte pĂ«rvoja me bazat e tĂ« dhĂ«nave NoSQL, por pikĂ«risht ky qasje lejon tĂ« pĂ«rdoret potenciali i HBase nĂ« kĂ«tĂ« detyrĂ« shumĂ« mĂ« efikas.

RowKey
Kolona

Vasja
Petja: 1
Olja: 1
Dasha: 1

Petja
Masha: 1
Vasja: 1

Këtu ne marrim disa avantazhe të menjëhershme. Për ta kuptuar këtë, le të analizojmë strukturën e re dhe të vlerësojmë kompleksitetin e llogaritjes:

  • Leximi i tĂ« dhĂ«nave: pĂ«r tĂ« pĂ«rgjigjur pyetjes, a ka Vasja qenĂ« i regjistruar pĂ«r Olin, Ă«shtĂ« e mjaftueshme tĂ« lexohet njĂ« kolona "Ola": nĂ«se ekziston, pĂ«rgjigja Ă«shtĂ« e vĂ«rtetĂ«, nĂ«se jo – e falsa => O(1)
  • Ndryshimi i tĂ« dhĂ«nave: shtimi i njĂ« shoku: Shtimi i njĂ« shoku: mjafton vetĂ«m tĂ« shtoni njĂ« kolona tĂ« re "ID e shokut" => O(1)
  • Ndryshimi i tĂ« dhĂ«nave: heqja e njĂ« shoku: mjafton vetĂ«m tĂ« fshini kolona "ID e shokut" => O(1)

Siç e shohim, njĂ« pĂ«rparĂ«si thelbĂ«sore e kĂ«tij modeli ruajtjeje Ă«shtĂ« se nĂ« tĂ« gjitha skenarĂ«t e nevojshĂ«m operojmĂ« vetĂ«m me njĂ« kolona, duke shmangur leximin e tĂ«rĂ« rreshtit nga baza, dhe pĂ«r mĂ« tepĂ«r, kalimin nĂ«pĂ«r tĂ« gjitha kolonat e kĂ«tij rreshti. KĂ«tu mund tĂ« ndalemi, por


Mund tĂ« shqetĂ«sohemi dhe tĂ« shkojmĂ« pak mĂ« tutje nĂ« rrugĂ«n e optimizimit tĂ« performancĂ«s dhe zvogĂ«limit tĂ« operacioneve tĂ« input-output gjatĂ« aksesit nĂ« bazĂ«n e tĂ« dhĂ«nave. ÇfarĂ« ndodh nĂ«se ruajmĂ« tĂ« gjitha informacionet pĂ«r lidhjen direkt nĂ« çelĂ«sin e rreshtit? Pra, tĂ« bĂ«jmĂ« çelĂ«sin me shumĂ« pjesĂ« si userID.friendID? NĂ« kĂ«tĂ« rast ne madje as qĂ« mund tĂ« lexojmĂ« kolonat e rreshtit (Opsioni 4(row)):

RowKey
Kolona

Vasja.Petja
Petja: 1

Vasja.Ola
Olja: 1

Vasja.Dasha
Dasha: 1

Petja.Masha
Masha: 1

Petja.Vasja
Vasja: 1

ËshtĂ« e qartĂ« se vlerĂ«simi i tĂ« gjitha skenarĂ«ve tĂ« manipulimit tĂ« tĂ« dhĂ«nave nĂ« njĂ« strukturĂ« tĂ« tillĂ«, ashtu si edhe nĂ« variantin e mĂ«parshĂ«m, do tĂ« jetĂ« O(1). Diferenca me variantin 3 do tĂ« jetĂ« ekskluzivisht nĂ« efikasitetin e operacioneve tĂ« futjes dhe leximit nĂ« bazĂ«n e tĂ« dhĂ«nave.

Dhe njĂ« ‘fundi’ i fundit. ËshtĂ« e lehtĂ« tĂ« vĂ«rehet se nĂ« variantin 4 vendi i çelĂ«sit tĂ« vargut do tĂ« ketĂ« njĂ« gjatĂ«si tĂ« ndryshueshme, e cila ndoshta mund tĂ« ketĂ« njĂ« ndikim nĂ« performancĂ« (kĂ«tĂ« e kujtojmĂ«, pasi HBase ruan tĂ« dhĂ«nat si njĂ« grup bajtoresh dhe vargjet nĂ« tabela janĂ« tĂ« renditura sipas çelĂ«sit). PĂ«rveç kĂ«saj, kemi njĂ« ndarĂ«s, i cili nĂ« disa skenarĂ« mund tĂ« kĂ«rkojĂ« pĂ«rpunim. PĂ«r tĂ« eleminuar kĂ«tĂ« ndikim, mund tĂ« pĂ«rdoren hash-e nga userID dhe friendID, dhe pasi tĂ« dy hash-et do tĂ« kenĂ« njĂ« gjatĂ«si tĂ« qĂ«ndrueshme, mund t'i konkatenuar ata pa ndarĂ«s. AtĂ«herĂ« tĂ« dhĂ«nat nĂ« tabelĂ« do tĂ« duken kĂ«shtu.Variant 5(hash)):

RowKey
Kolona

dc084ef00e94aef49be885f9b01f51c01918fa783851db0dc1f72f83d33a5994
Petja: 1

dc084ef00e94aef49be885f9b01f51c0f06b7714b5ba522c3cf51328b66fe28a
Olja: 1

dc084ef00e94aef49be885f9b01f51c00d2c2e5d69df6b238754f650d56c896a
Dasha: 1

1918fa783851db0dc1f72f83d33a59949ee3309645bd2c0775899fca14f311e1
Masha: 1

1918fa783851db0dc1f72f83d33a5994dc084ef00e94aef49be885f9b01f51c0
Vasja: 1

ËshtĂ« e qartĂ« se kompleksiteti algoritmik i punĂ«s me kĂ«tĂ« strukturĂ« pĂ«r skenarĂ«t qĂ« po shqyrtojmĂ«, do tĂ« jetĂ« i njĂ«jtĂ« me variantin 4 – domethĂ«nĂ« O(1).
Pra, le të përmbledhim të gjitha vlerësimet tona të kompleksitetit të llogaritjes në një tabelë:

Shtimi i një shoku
Kontrolli i një shoku
Fshirja e një shoku

Varianti 1 (default)
O(n)
O(n)
O(n)

Varianti 2 (count)
O(1)
O(n)
O(n)

Varianti 3 (column)
O(1)
O(1)
O(1)

Varianti 4 (row)
O(1)
O(1)
O(1)

Varianti 5 (hash)
O(1)
O(1)
O(1)

Siç shihet, variantet 3-5 duken më të preferuarat dhe teorikisht sigurojnë realizimin e të gjithë skenarëve të nevojshëm për manipulimin e të dhënave brenda një kohe konstante. Në kushtet e detyrës tonë nuk ka një kërkesë të qartë për të marrë një listë të gjithë shokëve të përdoruesit, por në aktivitete të vërteta projektimi, ne, si analistë të mirë, është mirë të "parashikojmë" që një detyrë e tillë mund të shfaqet dhe të "vendosim kashtën". Prandaj, preferencat e mia janë në anën e variantit 3. Por ka shumë mundësi që në një projekt të vërtetë, kjo kërkesë mund të jetë zgjidhur me mjete të tjera, prandaj pa një vizion të përgjithshëm të detyrës, më mirë mos të nxjerrim përfundime përfundimtare.

Përgatitja e eksperimentit

DĂ«shirojmĂ« tĂ« verifikojmĂ« teoritĂ« e mĂ«sipĂ«rme nĂ« praktikĂ« – kjo ishte edhe qĂ«llimi i mendimit qĂ« lindi gjatĂ« fundjavĂ«s sĂ« gjatĂ«. PĂ«r kĂ«tĂ« Ă«shtĂ« e nevojshme tĂ« vlerĂ«sojmĂ« shpejtĂ«sinĂ« e funksionimit tĂ« "aplikacionit tonĂ« hipotetik" nĂ« tĂ« gjithĂ« skenarĂ«t e pĂ«rshkruar tĂ« pĂ«rdorimit tĂ« bazĂ«s, si dhe rritjen e kĂ«tij koha me rritjen e madhĂ«sisĂ« sĂ« rrjetit social (n). Parametri i synuar qĂ« na intereson dhe qĂ« do tĂ« masim gjatĂ« eksperimentit Ă«shtĂ« koha qĂ« "aplikacioni hipotetik" shpenzon pĂ«r tĂ« realizuar njĂ« "operacion biznesi". Me "operacion biznesi" kuptojmĂ« njĂ«rin nga sa vijon:

  • Shtimi i njĂ« shoku tĂ« ri
  • Kontrolli nĂ«se pĂ«rdoruesi A Ă«shtĂ« shoku i pĂ«rdoruesit B
  • Hiqja e njĂ« shoku

Pra, duke pasur parasysh kërkesat e përcaktuara në premisën fillestare, skenari i kontrollit vizatohet si vijon:

  • ShĂ«nimi i tĂ« dhĂ«nave. Generoni njĂ« rrjet tĂ« rastĂ«sishĂ«m me madhĂ«si n. PĂ«r njĂ« afĂ«rsi mĂ« tĂ« madhe me "botĂ«n reale", numri i miqve tĂ« çdo pĂ«rdoruesi Ă«shtĂ« gjithashtu njĂ« vlerĂ« e rastĂ«sishme. Matni kohĂ«n qĂ« do tĂ« marrĂ« "aplikacioni ynĂ« hipotetik" pĂ«r tĂ« regjistruar tĂ« dhĂ«nat e gjeneruara nĂ« HBase. MĂ« pas, ndani kohĂ«n e marrĂ« me numrin e pĂ«rgjithshĂ«m tĂ« miqve tĂ« shtuar – kĂ«shtu do tĂ« kemi kohĂ«n mesatare pĂ«r njĂ« "operacion biznesi".
  • Leximi i tĂ« dhĂ«nave. PĂ«r çdo pĂ«rdorues, pĂ«rgatitni njĂ« listĂ« 'identitetesh' pĂ«r tĂ« cilat duhet tĂ« merrni pĂ«rgjigje nĂ«se pĂ«rdoruesi i ndjek ato apo jo. GjatĂ«sia e listĂ«s = afĂ«rsisht numri i miqve tĂ« pĂ«rdoruesit, pĂ«rveç qĂ« pĂ«r gjysmĂ«n e miqve qĂ« kontrollohen, pĂ«rgjigja duhet tĂ« jetĂ« "Po", ndĂ«rsa pĂ«r gjysmĂ«n tjetĂ«r "Jo". Kontrolli bĂ«het nĂ« kĂ«tĂ« rend, nĂ« mĂ«nyrĂ« qĂ« pĂ«rgjigjet "Po" dhe "Jo" tĂ« alternohen (do tĂ« na duhet tĂ« kalojmĂ« tĂ« gjitha kolonat e rreshtit pĂ«r opsionet 1 dhe 2 nĂ« çdo rast tĂ« dytĂ«). Koha totale e kontrolleve mĂ« pas ndahet me numrin e miqve tĂ« kontrolluar pĂ«r tĂ« marrĂ« kohĂ«n mesatare tĂ« kontrollit pĂ«r njĂ« subjekt.
  • Fshirja e tĂ« dhĂ«nave. TĂ« hiqni tĂ« gjithĂ« miqtĂ« nga pĂ«rdoruesi. NĂ« pĂ«rputhje me kĂ«tĂ«, rendi i eliminimit Ă«shtĂ« rastĂ«sor (do tĂ« 'shkrijmĂ«' listĂ«n fillestare qĂ« Ă«shtĂ« pĂ«rdorur pĂ«r regjistrimin e tĂ« dhĂ«nave). Koha e pĂ«rgjithshme e verifikimit mĂ« pas ndahet me numrin e miqve qĂ« janĂ« hequr pĂ«r tĂ« marrĂ« kohĂ«n mesatare pĂ«r njĂ« kontroll.

Skenarët duhet të ekzekutohen për çdo nga 5 variantet e modeleve të të dhënave dhe për madhësi të ndryshme të rrjetit social, për të parë se si ndryshon koha me rritjen e tij. Brenda një n lidhjesh në rrjet, lista e përdoruesve për kontroll duhet të jetë, natyrisht, e njëjtë për të 5 variantet.
Për një kuptim më të mirë, më poshtë po sjell një shembull të të dhënave të gjeneruara për n= 5. 'Generatori' i shkruar jep tre fjalorë ID-sh:

  • i pari – pĂ«r futje
  • i dyti – pĂ«r verifikim
  • i treti – pĂ«r eliminim

{0: [1], 1: [4, 5, 3, 2, 1], 2: [1, 2], 3: [2, 4, 1, 5, 3], 4: [2, 1]} # gjithsej 15 miq

{0: [1, 10800], 1: [5, 10800, 2, 10801, 4, 10802], 2: [1, 10800], 3: [3, 10800, 1, 10801, 5, 10802], 4: [2, 10800]} # gjithsej 18 subjekte të kontrolluara

{0: [1], 1: [1, 3, 2, 5, 4], 2: [1, 2], 3: [4, 1, 2, 3, 5], 4: [1, 2]} # gjithsej 15 miq

Siç mund të vëreni, të gjithë ID-të mbi 10,000 në fjalor për verifikim janë ato që me siguri do të japin përgjigje False. Shtimi, verifikimi dhe fshirja e "miqve" kryhen pikërisht në rendin e caktuar në fjalor.

Eksperimenti u realizua nĂ« njĂ« laptop qĂ« drejtonte Windows 10, ku njĂ« enĂ« Docker ishte e angazhuar nĂ« njĂ« bazĂ« tĂ« dhĂ«nash HBase, dhe njĂ« tjetĂ«r — Python me Jupyter Notebook. Docker-i kishte tĂ« rezervuara 2 bĂ«rthama CPU dhe 2 GB RAM. TĂ« gjitha logjikat, si emulimi i funksionimit tĂ« "aplikacionit tĂ« supozuar", ashtu edhe "mbĂ«shtetje" pĂ«r tĂ« gjeneruar tĂ« dhĂ«na testuese dhe pĂ«r tĂ« matur kohĂ«n, ishin shkruar nĂ« Python. PĂ«r punĂ«n me HBase u pĂ«rdor biblioteka happybase, pĂ«r llogaritjen e hash-eve (MD5) pĂ«r variantin 5 — hashlib.

Duke marrĂ« parasysh fuqinĂ« llogaritĂ«se tĂ« laptopit tĂ« caktuar, u zgjodh eksperimenti me n = 10, 30, 
. 170 — kur koha totale e zbatimit tĂ« plotĂ« tĂ« testit (tĂ« gjithĂ« skenarĂ«t pĂ«r tĂ« gjitha variantet pĂ«r tĂ« gjitha n) ishte ende mĂ« shumĂ« e arsyeshme dhe pĂ«rshtatej brenda njĂ« kohe tĂ« çajit (nĂ« mesatare 15 minuta).

Këtu është e nevojshme të bëhet një sqarim, se në këtë eksperiment në radhë të parë po vlerësojmë jo numrat e absolutë të performancës. Edhe krahasimi relatif i dy varianteve të ndryshme mund të mos jetë plotësisht korrekt. Aktualisht na intereson natyra e ndryshimit të kohës në varësi të n, pasi duke marrë parasysh konfigurimin e përmendur më sipër të "stendës testuese", është shumë e vështirë të marrim vlerësime të kohës, "të pastra" nga ndikimi i faktorëve rastësorë dhe të tjerë (as nuk është bërë një detyrë e tillë).

Rezultati i eksperimenti

Testi i parĂ« – si ndryshon koha e nevojshme pĂ«r tĂ« mbushur listĂ«n e miqve. Rezultati – nĂ« grafikĂ«n mĂ« poshtĂ«.
Karakteristikat e projektimit të modeleve të dhënave për NoSQL
Variantet 3-5, siç pritej, tregojnë një kohë praktikisht konstante për "operacionin e biznesit", e cila nuk varet nga rritja e madhësisë së rrjetit dhe ka një ndryshim të padallueshëm në performancë.
Opsioni 2 tregon gjithashtu njĂ« performancĂ« konstante, por disi mĂ« tĂ« dobĂ«t, pothuajse me 2 herĂ« mĂ« pak se opsionet 3-5. Dhe kjo nuk mund tĂ« mos na gĂ«zojĂ«, sepse Ă«shtĂ« nĂ« pĂ«rputhje me teorinĂ« – nĂ« kĂ«tĂ« opsion numri i operacioneve tĂ« hyrjes/daljes nĂ«/nga HBase Ă«shtĂ« pikĂ«risht 2 herĂ« mĂ« i madh. KĂ«to mund tĂ« shĂ«rbejnĂ« si dĂ«shmi indirekte qĂ« qĂ«ndrimi ynĂ« testues nĂ« parim ofron njĂ« saktĂ«si tĂ« mirĂ«.
Opsioni 1 gjithashtu natyrisht rezulton të jetë më i ngadalshëm dhe tregon një rritje lineare të kohës së kaluar për të shtuar njëri-tjetrin në përputhje me madhësinë e rrjetit.
Tani le të shikojmë rezultatet e testit të dytë.
Karakteristikat e projektimit të modeleve të dhënave për NoSQL
Opsionet 3-5 përsëri veprojnë siç pritej - koha konstante, e pavarur nga madhësia e rrjetit. Opsionet 1 dhe 2 demonstrojnë rritje lineare të kohës me rritjen e madhësisë së rrjetit dhe një performancë të ngjashme. Megjithatë, opsioni 2 rezulton të jetë pak më i ngadaltë - duket se për shkak të nevojës për të lexuar dhe përpunuar kolonën shtesë "count", e cila bëhet më e dukshme me rritjen e n. Megjithatë, do të përmbahen nga çdo përfundim, pasi saktësia e këtij krahasimi është relativisht e ulët. Për më tepër, këto marrëdhënie (cilin opsion, 1 apo 2, është më i shpejtë) ndryshonin nga nisja në nisje (duke ruajtur karakterin e varshmërisë dhe "shkuar nën hundë me hundë").

Dhe grafiku përfundimtar - rezultati i testimit të fshirjes.

Karakteristikat e projektimit të modeleve të dhënave për NoSQL

Këtu gjithashtu pa surpriza. Opsionet 3-5 e kryejnë fshirjen me kohë konstante.
ÇfarĂ« Ă«shtĂ« interesante, opsionet 4 dhe 5, ndryshe nga skenarĂ«t e mĂ«parshĂ«m, tregojnĂ« njĂ« performancĂ« pak mĂ« tĂ« dobĂ«t se opsioni 3. Duket se operacioni i fshirjes sĂ« rreshtit Ă«shtĂ« mĂ« i kushtueshĂ«m se operacioni i fshirjes sĂ« kolonĂ«s, gjĂ« qĂ« Ă«shtĂ« logjike nĂ« pĂ«rgjithĂ«si.

Opsionet 1 dhe 2, siç pritej, tregojnë rritje lineare të kohës. Megjithatë, opsioni 2 është konstant më i ngadalshëm se opsioni 1 - për shkak të operacionit shtesë të hyrjes/daljes për "mirëmbajtjen" e kolonës count.

Përfundimet e përgjithshme të eksperimenti:

  • Opsionet 3-5 tregojnĂ« mĂ« shumĂ« efikasitet, pasi shfrytĂ«zojnĂ« avantazhet e HBase; performanca e tyre, pĂ«r kĂ«tĂ« arsye, ndryshon nga njĂ«ra-tjetra me njĂ« konstant dhe nuk varet nga madhĂ«sia e rrjetit.
  • Dallimi ndĂ«rmjet opsioneve 4 dhe 5 nuk u regjistrua. Por kjo nuk do tĂ« thotĂ« se opsioni 5 nuk duhet pĂ«rdorur. ËshtĂ« shumĂ« e mundur qĂ« skenari i eksperimenti, duke marrĂ« parasysh TTHK e murit testues, nuk e lejoi ta identifikonte atĂ«.
  • Karakteri i rritjes sĂ« kohĂ«s sĂ« nevojshme pĂ«r tĂ« kryer "operacionet e biznesit" me tĂ« dhĂ«na, nĂ« pĂ«rgjithĂ«si konfirmoi teoria e mĂ«parshme pĂ«r tĂ« gjitha opsionet.

Epilogu

Eksperimentet e rënda të kryera nuk duhet marrë si të vërteta absolute. Ka shumë faktorë që nuk janë marrë parasysh dhe që kanë sjellë devijime në rezultatet (sidomos këto fluksione janë të dukshme në grafika me madhësi të vogël rrjeti). Për shembull, shpejtësia e punës së thrift, që përdoret nga happybase, vëllimi dhe mënyra e implementimit të logjikës që kam shkruar në Python (nuk pretendoj se kodi është shkruar optimalisht dhe përdor maksimalisht potencialet e të gjitha komponenteve), ndoshta karakteristikat e memorizimit të HBase, aktiviteti në background i Windows 10 në laptopin tim, etj. Në përgjithësi, mund të themi se të gjitha përllogaritjet teorike kanë treguar vlefshmërinë e tyre eksperimentalisht. Ose të paktën nuk mund të demantojmë ato në këtë mënyrë 'në mënyrë të drejtpërdrejtë'.

NĂ« pĂ«rfundim – rekomandime pĂ«r tĂ« gjithĂ« ata qĂ« sapo kanĂ« filluar tĂ« projektojnĂ« modele tĂ« dhĂ«nash nĂ« HBase: distancohuni nga pĂ«rvoja e mĂ«parshme me bazat e tĂ« dhĂ«nave relacional dhe mbani mend 'ura':

  • Kur projektojmĂ«, nisim nga problemi dhe nga modeli i manipulimit tĂ« tĂ« dhĂ«nave, dhe jo nga modeli i fushĂ«s sĂ« subjektit.
  • Qasje efektive (pa skanimin e plotĂ« tĂ« tabelĂ«s) – vetĂ«m me çelĂ«sin.
  • Denormalizimi
  • Rreshta tĂ« ndryshme mund tĂ« pĂ«rmbajnĂ« kolona tĂ« ndryshme
  • Formacioni dinamik i kolonnave

Burimi: habr.com

Bli njĂ« hosting tĂ« besueshĂ«m pĂ«r faqet me mbrojtje DDoS, VPS VDS serverĂ« đŸ”„ Bli njĂ« hosting tĂ« besueshĂ«m pĂ«r faqet me mbrojtje DDoS, VPS VDS serverĂ« | ProHoster