NoSQL-ի համար տվյալների մոդելի նախագծման առանձնահատկությունները

Ներածություն

NoSQL-ի համար տվյալների մոդելի նախագծման առանձնահատկությունները «Դուք պետք է հնարավորինս արագ վազեք՝ տեղում մնալու համար,
իսկ ինչ-որ տեղ հասնելու համար պետք է առնվազն երկու անգամ արագ վազել»։
գ) Ալիսը հրաշքների աշխարհում

Որոշ ժամանակ առաջ ինձ խնդրեցին դասախոսություն կարդալ վերլուծաբաններ մեր ընկերությունը տվյալների մոդելների նախագծման թեմայով, քանի որ երկար ժամանակ (երբեմն մի քանի տարի) նախագծերի վրա նստած՝ մենք կորցնում ենք տեսադաշտը, թե ինչ է կատարվում մեր շուրջը ՏՏ տեխնոլոգիաների աշխարհում: Մեր ընկերությունում (ուղղակի այդպես է պատահում) շատ նախագծեր չեն օգտագործում NoSQL տվյալների բազաներ (գոնե առայժմ), այնպես որ իմ դասախոսության ժամանակ ես առանձին ուշադրություն դարձրի դրանց վրա՝ օգտագործելով HBase-ի օրինակը և փորձեցի նյութի ներկայացումը կողմնորոշել դրանց վրա։ ովքեր երբեք չեն օգտագործել դրանք, աշխատել են: Մասնավորապես, ես նկարազարդեցի տվյալների մոդելի նախագծման որոշ առանձնահատկություններ՝ օգտագործելով մի օրինակ, որը կարդացել եմ մի քանի տարի առաջ Amandeep Khurana-ի «HB ase Schema Design-ի ներածություն» հոդվածում. Օրինակներ վերլուծելիս ես համեմատեցի նույն խնդրի լուծման մի քանի տարբերակներ՝ հիմնական մտքերը հանդիսատեսին ավելի լավ փոխանցելու համար։

Վերջերս «անգործությունից» ես ինքս ինձ հարց տվեցի (կարանտինում մայիսյան երկար հանգստյան օրերը հատկապես նպաստում են դրան), թե տեսական հաշվարկները որքանո՞վ կհամապատասխանեն պրակտիկային։ Փաստորեն, այս հոդվածի գաղափարը ծնվեց. Մի քանի օր NoSQL-ի հետ աշխատող ծրագրավորողը կարող է դրանից նոր բան չսովորել (և հետևաբար կարող է անմիջապես բաց թողնել հոդվածի կեսը): Բայց համար վերլուծաբաններՆրանց համար, ովքեր դեռ սերտորեն չեն աշխատել NoSQL-ի հետ, կարծում եմ, որ դա օգտակար կլինի HBase-ի համար տվյալների մոդելների նախագծման առանձնահատկությունների վերաբերյալ հիմնական պատկերացում կազմելու համար:

Օրինակի վերլուծություն

Իմ կարծիքով, նախքան NoSQL տվյալների բազաները սկսելը, պետք է լավ մտածել և կշռադատել դրական և բացասական կողմերը: Հաճախ խնդիրը, ամենայն հավանականությամբ, կարող է լուծվել՝ օգտագործելով ավանդական հարաբերական DBMS-ներ: Հետեւաբար, ավելի լավ է առանց էական պատճառների չօգտագործել NoSQL: Եթե ​​այնուամենայնիվ որոշել եք օգտագործել NoSQL տվյալների բազան, ապա պետք է հաշվի առնել, որ դիզայնի մոտեցումներն այստեղ որոշակիորեն տարբեր են։ Հատկապես դրանցից մի քանիսը կարող են անսովոր լինել նրանց համար, ովքեր նախկինում զբաղվել են միայն հարաբերական DBMS-ներով (ըստ իմ դիտարկումների): Այսպիսով, «հարաբերական» աշխարհում մենք սովորաբար սկսում ենք մոդելավորել խնդրի տիրույթը և միայն այն ժամանակ, եթե անհրաժեշտ է, ապանորմալացնել մոդելը: NoSQL-ում մենք պետք է անմիջապես հաշվի առնի տվյալների հետ աշխատելու ակնկալվող սցենարները և սկզբում ապանորմալացնել տվյալները: Բացի այդ, կան մի շարք այլ տարբերություններ, որոնք կքննարկվեն ստորև:

Դիտարկենք հետևյալ «սինթետիկ» խնդիրը, որի հետ մենք կշարունակենք աշխատել.

Ինչ-որ վերացական սոցիալական ցանցի օգտատերերի ընկերների ցուցակի համար անհրաժեշտ է նախագծել պահեստավորման կառուցվածք։ Պարզեցնելու համար մենք կենթադրենք, որ մեր բոլոր կապերը ուղղորդված են (ինչպես Instagram-ում, ոչ թե Linkedin-ում): Կառուցվածքը պետք է թույլ տա արդյունավետորեն.

  • Պատասխանեք այն հարցին, թե արդյո՞ք A օգտվողը կարդում է B օգտվողը (կարդալու օրինակ)
  • Թույլատրել կապեր ավելացնել/հեռացնել A օգտատիրոջ բաժանորդագրության/չեղարկման դեպքում B օգտատերից (տվյալների փոփոխման ձևանմուշ)

Իհարկե, խնդրի լուծման տարբերակները շատ են։ Սովորական հարաբերական տվյալների բազայում մենք, ամենայն հավանականությամբ, պարզապես կկազմենք հարաբերությունների աղյուսակ (հնարավոր է, եթե, օրինակ, մենք պետք է պահպանենք օգտվողների խումբ՝ ընտանիք, աշխատանք և այլն, որը ներառում է այս «ընկերը») և օպտիմալացնել: մուտքի արագությունը կավելացնի ինդեքսներ/բաժանումներ: Ամենայն հավանականությամբ, վերջնական աղյուսակը կունենա հետևյալ տեսքը.

USER_ID
friend_id

Vasya
Պետրոս

Vasya
Օլյա

այսուհետ պարզության և ավելի լավ հասկանալու համար ID-ների փոխարեն կնշեմ անուններ

HBase-ի դեպքում մենք գիտենք, որ.

  • հնարավոր է արդյունավետ որոնում, որը չի հանգեցնում ամբողջական աղյուսակի սկանավորման բացառապես բանալիով
    • իրականում, այդ իսկ պատճառով նման տվյալների բազաներին շատերին ծանոթ SQL հարցումներ գրելը վատ գաղափար է. տեխնիկապես, իհարկե, կարող ես SQL հարցում ուղարկել Joins-ով և այլ տրամաբանությամբ նույն Impala-ից HBase-ին, բայց որքանո՞վ դա արդյունավետ կլինի...

Հետեւաբար, մենք ստիպված ենք օգտագործել օգտվողի ID-ն որպես բանալի: Եվ իմ առաջին միտքը «որտեղ և ինչպես պահել ընկերների ID-ները» թեմայով: միգուցե դրանք սյունակներում պահելու գաղափար է: Այս ամենաակնհայտ և «միամիտ» տարբերակը նման տեսք կունենա (եկեք այն անվանենք Տարբերակ 1 (կանխադրված)հետագա հղումների համար):

RowKey
Բարձրախոսներ

Vasya
1: Պետյա
2: Օլյա
3: Դաշա

Պետրոս
1: Մաշա
2: Վասյա

Այստեղ յուրաքանչյուր տող համապատասխանում է մեկ ցանցի օգտագործողին: Սյունակներն ունեն անուններ՝ 1, 2, ... - ըստ ընկերների քանակի, իսկ ընկերների ID-ները պահվում են սյունակներում։ Կարևոր է նշել, որ յուրաքանչյուր տող կունենա տարբեր թվով սյունակներ: Վերևի նկարի օրինակում մեկ տող ունի երեք սյունակ (1, 2 և 3), իսկ երկրորդը ունի միայն երկու (1 և 2) - այստեղ մենք ինքներս օգտագործեցինք HBase-ի երկու հատկություն, որոնք հարաբերական տվյալների բազաները չունեն.

  • սյունակների կազմը դինամիկ փոխելու ունակություն (ավելացնել ընկեր -> ավելացնել սյունակ, հեռացնել ընկերոջը -> ջնջել սյունակը)
  • տարբեր տողեր կարող են ունենալ տարբեր սյունակների կազմեր

Եկեք ստուգենք մեր կառուցվածքը առաջադրանքի պահանջներին համապատասխանելու համար.

  • Տվյալների ընթերցումՈրպեսզի հասկանանք, թե արդյոք Վասյան բաժանորդագրված է Օլյային, մենք պետք է հանենք ամբողջ գիծը RowKey = «Վասյա» ստեղնով և դասավորել սյունակի արժեքները, մինչև որ դրանցում «հանդիպենք» Օլյային: Կամ կրկնեք բոլոր սյունակների արժեքները, «չհանդիպեք» Օլյային և վերադարձրեք պատասխանը False;
  • Տվյալների խմբագրում. ընկերոջ ավելացումՆմանատիպ առաջադրանքի համար պետք է նաև հանել ամբողջ գիծը օգտագործելով RowKey = «Vasya» ստեղնը՝ իր ընկերների ընդհանուր թիվը հաշվարկելու համար: Մեզ անհրաժեշտ է ընկերների այս ընդհանուր թիվը՝ որոշելու այն սյունակի թիվը, որտեղ մենք պետք է գրենք նոր ընկերոջ ID-ն:
  • Տվյալների փոփոխություն. ընկերոջ ջնջում:
    • Պահանջվում է հանել ամբողջ գիծը RowKey = «Վասյա» ստեղնով և դասավորեք սյունակները, որպեսզի գտնեք այն մեկը, որտեղ գրանցված է ջնջվող ընկերը.
    • Հաջորդը, ընկերոջը ջնջելուց հետո մենք պետք է «տեղափոխենք» բոլոր տվյալները մեկ սյունակում, որպեսզի դրանց համարակալման մեջ «բացեր» չստանանք:

Այժմ գնահատենք, թե որքան արդյունավետ կլինեն այս ալգորիթմները, որոնք մեզ անհրաժեշտ կլինի իրականացնել «պայմանական կիրառման» կողմից՝ օգտագործելով. Օ-սիմվոլիզմ. Մեր հիպոթետիկ սոցիալական ցանցի չափը նշենք որպես n: Այնուհետև մեկ օգտվողի ընկերների առավելագույն քանակը (n-1): Մենք կարող ենք հետագայում անտեսել սա (-1) մեր նպատակների համար, քանի որ O-խորհրդանիշների օգտագործման շրջանակներում դա անկարևոր է:

  • Տվյալների ընթերցումԱնհրաժեշտ է հանել ամբողջ տողը և կրկնել սահմանի մեջ գտնվող նրա բոլոր սյունակներով: Սա նշանակում է, որ ծախսերի վերին գնահատումը կլինի մոտավորապես O(n)
  • Տվյալների խմբագրում. ընկերոջ ավելացումԸնկերների թիվը որոշելու համար անհրաժեշտ է կրկնել տողի բոլոր սյունակները, այնուհետև տեղադրել նոր սյունակ => O(n)
  • Տվյալների փոփոխություն. ընկերոջ ջնջում:
    • Ավելացմանը նման. դուք պետք է անցնեք բոլոր սյունակները սահմանում => O(n)
    • Սյունակները հեռացնելուց հետո մենք պետք է «տեղափոխենք» դրանք։ Եթե ​​դուք իրականացնում եք այս «գլուխը», ապա սահմանաչափում ձեզ անհրաժեշտ կլինեն մինչև (n-1) գործողություններ: Բայց այստեղ և հետագա գործնական մասում մենք կօգտագործենք այլ մոտեցում, որը կիրականացնի «կեղծ հերթափոխ» ֆիքսված թվով գործողությունների համար, այսինքն՝ դրա վրա կծախսվի մշտական ​​ժամանակ՝ անկախ n-ից։ Այս հաստատուն ժամանակը (O(2) ճիշտ է) կարելի է անտեսել O(n-ի համեմատ): Մոտեցումը պատկերված է ստորև նկարում. մենք պարզապես պատճենում ենք տվյալները «վերջին» սյունակից այն սյունակում, որտեղից ցանկանում ենք ջնջել տվյալները, այնուհետև ջնջում ենք վերջին սյունակը.
      NoSQL-ի համար տվյալների մոդելի նախագծման առանձնահատկությունները

Ընդհանուր առմամբ, բոլոր սցենարներում մենք ստացել ենք O(n) ասիմպտոտիկ հաշվարկային բարդություն:
Հավանաբար արդեն նկատել եք, որ մենք գրեթե միշտ պետք է կարդանք ամբողջ տողը տվյալների բազայից, իսկ երեքից երկու դեպքում՝ պարզապես բոլոր սյունակները անցնելու և ընկերների ընդհանուր թիվը հաշվարկելու համար։ Հետևաբար, որպես օպտիմալացման փորձ, կարող եք ավելացնել «հաշվարկ» սյունակ, որը պահպանում է ցանցի յուրաքանչյուր օգտագործողի ընկերների ընդհանուր թիվը: Այս դեպքում մենք չենք կարող կարդալ ամբողջ տողը ընկերների ընդհանուր թիվը հաշվարկելու համար, այլ կարդալ միայն մեկ «հաշվում» սյունակ: Հիմնական բանը տվյալների մանիպուլյացիայի ժամանակ չմոռանալ թարմացնել «հաշվիչը»: Դա. մենք բարելավվում ենք Տարբերակ 2 (հաշվարկ).

RowKey
Բարձրախոսներ

Vasya
1: Պետյա
2: Օլյա
3: Դաշա
հաշվարկ: 3

Պետրոս
1: Մաշա
2: Վասյա

հաշվարկ: 2

Առաջին տարբերակի համեմատ.

  • Տվյալների ընթերցում«Վասյան կարդում է Օլյա» հարցին պատասխան ստանալու համար: ոչինչ չի փոխվել => O(n)
  • Տվյալների խմբագրում. ընկերոջ ավելացումՄենք պարզեցրել ենք նոր ընկերոջ տեղադրումը, քանի որ այժմ մեզ պետք չէ կարդալ ամբողջ տողը և կրկնել դրա սյունակների վրա, այլ կարող ենք ստանալ միայն «հաշվել» սյունակի արժեքը և այլն: անմիջապես որոշեք սյունակի համարը նոր ընկեր մտցնելու համար: Սա հանգեցնում է հաշվողական բարդության նվազեցմանը մինչև O(1)
  • Տվյալների փոփոխություն. ընկերոջ ջնջումԸնկերոջը ջնջելիս մենք կարող ենք նաև օգտագործել այս սյունակը` նվազեցնելու I/O գործողությունների քանակը, երբ տվյալները մեկ բջիջ «տեղափոխում ենք» դեպի ձախ: Բայց սյունակների միջով կրկնելու անհրաժեշտությունը՝ գտնելու այն մեկը, որը պետք է ջնջվի, դեռ մնում է, այնպես որ => O(n)
  • Մյուս կողմից, այժմ տվյալների թարմացման ժամանակ մենք պետք է ամեն անգամ թարմացնենք «հաշվել» սյունակը, բայց դա մշտական ​​ժամանակ է պահանջում, որը կարելի է անտեսել O-խորհրդանիշների շրջանակներում:

Ընդհանուր առմամբ, 2-րդ տարբերակը մի փոքր ավելի օպտիմալ է թվում, բայց այն ավելի շատ նման է «էվոլյուցիա՝ հեղափոխության փոխարեն»: «Հեղափոխություն» անելու համար մեզ անհրաժեշտ կլինի Տարբերակ 3 (սյունակ).
Եկեք ամեն ինչ «շուռ տանք». մենք կհանձնարարենք սյունակի անունը օգտվողի ID! Այն, ինչ գրվելու է ինքնին սյունակում, մեզ համար այլևս կարևոր չէ, թող լինի թիվ 1-ը (ընդհանուր առմամբ, այնտեղ կարելի է օգտակար բաներ պահել, օրինակ՝ «ընտանիք/ընկերներ/և այլն» խումբը): Այս մոտեցումը կարող է զարմացնել անպատրաստ «աշխարհիկին», ով չունի NoSQL տվյալների բազաների հետ աշխատելու նախկին փորձ, բայց հենց այս մոտեցումն է թույլ տալիս շատ ավելի արդյունավետ օգտագործել HBase-ի ներուժը այս առաջադրանքում.

RowKey
Բարձրախոսներ

Vasya
Պետյա: 1
Օլյա: 1
Դաշա: 1

Պետրոս
Մաշա: 1
Վասյա: 1

Այստեղ մենք միանգամից մի քանի առավելություն ենք ստանում. Դրանք հասկանալու համար եկեք վերլուծենք նոր կառուցվածքը և գնահատենք հաշվողական բարդությունը.

  • Տվյալների ընթերցումՀարցին պատասխանելու համար, թե արդյոք Վասյան բաժանորդագրված է Օլյա, բավական է կարդալ մեկ «Օլյա» սյունակ. եթե կա, ապա պատասխանը ճիշտ է, եթե ոչ՝ Սխալ => O(1)
  • Տվյալների խմբագրում. ընկերոջ ավելացումԸնկերոջ ավելացում. պարզապես ավելացրեք նոր սյունակ «Friend ID» => O(1)
  • Տվյալների փոփոխություն. ընկերոջ ջնջումՊարզապես հեռացրեք Friend ID սյունակը => O(1)

Ինչպես տեսնում եք, պահեստավորման այս մոդելի զգալի առավելությունն այն է, որ մեզ անհրաժեշտ բոլոր սցենարներում մենք գործում ենք միայն մեկ սյունակով՝ խուսափելով տվյալների բազայից ամբողջ տողը կարդալուց և, առավել ևս, թվարկելով այս տողի բոլոր սյունակները: Մենք կարող էինք այնտեղ կանգ առնել, բայց...

Դուք կարող եք շփոթված լինել և մի փոքր ավելի առաջ գնալ կատարողականի օպտիմալացման և մուտքային/ելք գործողությունների կրճատման ճանապարհով, երբ մուտք գործեք տվյալների բազա: Ի՞նչ կլիներ, եթե մենք պահեինք հարաբերությունների ամբողջական տեղեկատվությունը անմիջապես տողի ստեղնում: Այսինքն՝ բանալու կոմպոզիտը դարձնե՞լ userID.friendID: Այս դեպքում մենք նույնիսկ կարիք չունենք կարդալ տողի սյունակները (Տարբերակ 4 (շարք)):

RowKey
Բարձրախոսներ

Վասյա.Պետյա
Պետյա: 1

Վասյա.Օլյա
Օլյա: 1

Վասյա.Դաշա
Դաշա: 1

Պետյա.Մաշա
Մաշա: 1

Պետյա.Վասյա
Վասյա: 1

Ակնհայտ է, որ նման կառուցվածքում տվյալների մանիպուլյացիայի բոլոր սցենարների գնահատումը, ինչպես նախորդ տարբերակում, կլինի O(1): Տարբերությունը 3 տարբերակի հետ կլինի բացառապես տվյալների բազայում I/O գործողությունների արդյունավետության մեջ:

Դե, վերջին «աղեղը». Հեշտ է տեսնել, որ 4-րդ տարբերակում տողի ստեղնը կունենա փոփոխական երկարություն, որը կարող է ազդել աշխատանքի վրա (այստեղ մենք հիշում ենք, որ HBase-ը պահում է տվյալները որպես բայթերի մի շարք, իսկ աղյուսակների տողերը դասավորված են ըստ բանալիների): Բացի այդ, մենք ունենք տարանջատիչ, որը կարող է անհրաժեշտ լինել որոշ սցենարների դեպքում: Այս ազդեցությունը վերացնելու համար դուք կարող եք օգտագործել հեշերը userID-ից և friendID-ից, և քանի որ երկու հեշերն էլ կունենան հաստատուն երկարություն, դուք կարող եք դրանք պարզապես միացնել առանց բաժանարարի: Այնուհետև աղյուսակի տվյալները այսպիսի տեսք կունենան (Տարբերակ 5 (հեշ)):

RowKey
Բարձրախոսներ

dc084ef00e94aef49be885f9b01f51c01918fa783851db0dc1f72f83d33a5994
Պետյա: 1

dc084ef00e94aef49be885f9b01f51c0f06b7714b5ba522c3cf51328b66fe28a
Օլյա: 1

dc084ef00e94aef49be885f9b01f51c00d2c2e5d69df6b238754f650d56c896a
Դաշա: 1

1918fa783851db0dc1f72f83d33a59949ee3309645bd2c0775899fca14f311e1
Մաշա: 1

1918fa783851db0dc1f72f83d33a5994dc084ef00e94aef49be885f9b01f51c0
Վասյա: 1

Ակնհայտ է, որ նման կառույցի հետ աշխատելու ալգորիթմական բարդությունը մեր դիտարկած սցենարներում կլինի նույնը, ինչ 4-րդ տարբերակում, այսինքն՝ O(1):
Ընդհանուր առմամբ, եկեք ամփոփենք հաշվողական բարդության մեր բոլոր գնահատումները մեկ աղյուսակում.

Ընկերոջ ավելացում
Ստուգում է ընկերոջը
Ընկերոջը հեռացնելը

Տարբերակ 1 (կանխադրված)
O (n)
O (n)
O (n)

Տարբերակ 2 (հաշվարկ)
Ո (1)
O (n)
O (n)

Տարբերակ 3 (սյունակ)
Ո (1)
Ո (1)
Ո (1)

Տարբերակ 4 (շարք)
Ո (1)
Ո (1)
Ո (1)

Տարբերակ 5 (հեշ)
Ո (1)
Ո (1)
Ո (1)

Ինչպես տեսնում եք, 3-5 տարբերակները, թվում է, առավել նախընտրելի են և տեսականորեն ապահովում են տվյալների մշակման բոլոր անհրաժեշտ սցենարների կատարումը մշտական ​​ժամանակում: Մեր առաջադրանքի պայմաններում օգտատիրոջ բոլոր ընկերների ցուցակը ձեռք բերելու հստակ պահանջ չկա, բայց իրական նախագծային գործունեության մեջ լավ կլինի, որ մենք՝ որպես լավ վերլուծաբաններ, «կանխատեսենք», որ նման խնդիր կարող է առաջանալ և «Ծղոտ տարածիր». Հետևաբար, իմ համակրանքը 3-րդ տարբերակի կողմն է: Բայց շատ հավանական է, որ իրական նախագծում այս խնդրանքն արդեն կարող էր լուծվել այլ միջոցներով, հետևաբար, առանց ամբողջ խնդրի ընդհանուր տեսլականի, ավելի լավ է չանել. վերջնական եզրակացություններ.

Փորձի պատրաստում

Ես կցանկանայի գործնականում փորձարկել վերը նշված տեսական փաստարկները՝ սա էր երկար հանգստյան օրերին ծագած գաղափարի նպատակը։ Դա անելու համար անհրաժեշտ է գնահատել մեր «պայմանական հավելվածի» գործառնական արագությունը տվյալների բազայի օգտագործման բոլոր նկարագրված սցենարներում, ինչպես նաև այս ժամանակի ավելացումը սոցիալական ցանցի (n) չափի մեծացման հետ միասին: Թիրախային պարամետրը, որը մեզ հետաքրքրում է, և որը մենք չափելու ենք փորձի ընթացքում, «պայմանական հավելվածի» ծախսած ժամանակն է մեկ «բիզնես գործողություն» կատարելու համար: «Բիզնես գործարք» ասելով մենք հասկանում ենք հետևյալներից մեկը.

  • Մեկ նոր ընկերոջ ավելացում
  • Ստուգում, թե արդյոք A օգտվողը B օգտվողի ընկերն է
  • Մեկ ընկերոջ հեռացում

Այսպիսով, հաշվի առնելով սկզբնական հայտարարության մեջ նշված պահանջները, ստուգման սցենարն առաջանում է հետևյալ կերպ.

  • Տվյալների գրանցում. Պատահականորեն ստեղծեք n չափի նախնական ցանց: «Իրական աշխարհին» ավելի մոտենալու համար յուրաքանչյուր օգտատեր ունեցող ընկերների թիվը նույնպես պատահական փոփոխական է: Չափեք այն ժամանակը, որի ընթացքում մեր «պայմանական հավելվածը» գրում է բոլոր ստեղծված տվյալները HBase-ում: Այնուհետև ստացված ժամանակը բաժանեք ավելացված ընկերների ընդհանուր թվի վրա. ահա թե ինչպես ենք ստանում մեկ «բիզնեսի» միջին ժամանակը:
  • Տվյալների ընթերցում. Յուրաքանչյուր օգտագործողի համար ստեղծեք «անձնավորությունների» ցուցակ, որոնց համար պետք է պատասխան ստանաք՝ օգտատերը բաժանորդագրված է նրանց, թե ոչ: Ցուցակի երկարությունը = մոտավորապես օգտատիրոջ ընկերների թիվը, և ստուգված ընկերների կեսի համար պատասխանը պետք է լինի «Այո», իսկ մյուս կեսի համար՝ «Ոչ»: Ստուգումն իրականացվում է այնպես, որ «Այո» և «Ոչ» պատասխանները փոխարինվեն (այսինքն, յուրաքանչյուր երկրորդ դեպքում մենք ստիպված կլինենք անցնել տողի բոլոր սյունակները 1-ին և 2-րդ տարբերակների համար): Այնուհետև ցուցադրման ընդհանուր ժամանակը բաժանվում է փորձարկված ընկերների թվի վրա՝ յուրաքանչյուր առարկայի ցուցադրման միջին ժամանակը ստանալու համար:
  • Տվյալների ջնջում. Հեռացրեք բոլոր ընկերներին օգտվողից: Ավելին, ջնջման կարգը պատահական է (այսինքն, մենք «խառնում ենք» սկզբնական ցուցակը, որն օգտագործվում է տվյալների գրանցման համար): Ստուգման ընդհանուր ժամանակը այնուհետև բաժանվում է հեռացված ընկերների թվով, որպեսզի ստացվի մեկ ստուգման միջին ժամանակը:

Սցենարները պետք է գործարկվեն տվյալների մոդելի 5 տարբերակներից յուրաքանչյուրի և սոցիալական ցանցի տարբեր չափերի համար՝ տեսնելու, թե ինչպես է փոխվում ժամանակը, քանի որ այն աճում է: Մեկ n-ի սահմաններում ցանցում կապերը և ստուգվող օգտվողների ցանկը, իհարկե, պետք է նույնը լինեն բոլոր 5 տարբերակների համար:
Ավելի լավ հասկանալու համար ստորև բերված է n= 5-ի համար ստեղծված տվյալների օրինակ: Գրավոր «գեներատորը» որպես արդյունք արտադրում է երեք ID բառարան.

  • առաջինը տեղադրման համար է
  • երկրորդը ստուգելու համար է
  • երրորդ - ջնջման համար

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

Ինչպես տեսնում եք, ստուգման համար բառարանում 10-ից ավելի բոլոր ID-ները հենց նրանք են, որոնք, անշուշտ, կտան կեղծ պատասխանը: «Ընկերների» տեղադրումը, ստուգումը և ջնջումը կատարվում են հենց բառարանում նշված հաջորդականությամբ:

Փորձն իրականացվել է Windows 10 օպերացիոն համակարգով աշխատող նոութբուքի վրա, որտեղ HBase-ն աշխատում էր Docker-ի մի կոնտեյներով, իսկ մյուսում աշխատում էր Python-ը Jupyter Notebook-ով։ Docker-ին հատկացվել է 2 պրոցեսորի միջուկ և 2 ԳԲ օպերատիվ հիշողություն: Ամբողջ տրամաբանությունը, ինչպես «պայմանական հավելվածի» և «խողովակաշարի» նմանակումը թեստային տվյալների և ժամանակի չափման համար, գրվել է Python-ում: Գրադարանը օգտագործվել է HBase-ի հետ աշխատելու համար երջանիկ բազա, հաշվարկել հեշերը (MD5) 5 տարբերակի համար՝ հեշլիբ

Հաշվի առնելով որոշակի նոութբուքի հաշվողական հզորությունը, փորձնականորեն ընտրվել է մեկնարկը n = 10, 30, … համար: 170 – երբ փորձարկման ամբողջական ցիկլի ընդհանուր գործառնական ժամանակը (բոլոր n-ի բոլոր տարբերակների համար բոլոր սցենարները) նույնիսկ քիչ թե շատ ողջամիտ էր և հարմար մեկ թեյի խնջույքի ժամանակ (միջինը 15 րոպե):

Այստեղ հարկ է նշել, որ այս փորձի ժամանակ մենք հիմնականում չենք գնահատում կատարողականի բացարձակ թվերը։ Նույնիսկ տարբեր երկու տարբերակների համեմատական ​​համեմատությունը կարող է լիովին ճիշտ չլինել: Այժմ մեզ հետաքրքրում է n-ից կախված ժամանակի փոփոխության բնույթը, քանի որ հաշվի առնելով «փորձարկման կանգառի» վերը նշված կոնֆիգուրացիան, շատ դժվար է ձեռք բերել ժամանակի գնահատումներ՝ «մաքրված» պատահական և այլ գործոնների ազդեցությունից ( և նման խնդիր դրված չէր):

Փորձի արդյունք

Առաջին թեստն այն է, թե ինչպես է փոխվում ընկերների ցուցակը լրացնելու համար ծախսված ժամանակը: Արդյունքը ստորև ներկայացված է գրաֆիկում:
NoSQL-ի համար տվյալների մոդելի նախագծման առանձնահատկությունները
3-5 տարբերակները, ինչպես և սպասվում էր, ցույց են տալիս գրեթե հաստատուն «բիզնես գործարքի» ժամանակը, որը կախված չէ ցանցի չափի աճից և կատարողականի աննկատելի տարբերությունից:
Տարբերակ 2-ը նույնպես ցույց է տալիս մշտական, բայց մի փոքր ավելի վատ կատարողականություն, գրեթե ուղիղ 2 անգամ 3-5 տարբերակների համեմատ: Եվ սա չի կարող չուրախացնել, քանի որ այն փոխկապակցված է տեսության հետ. այս տարբերակում մուտքի/ելքի գործողությունների թիվը HBase-ից ուղիղ 2 անգամ ավելի է: Սա կարող է ծառայել որպես անուղղակի ապացույց, որ մեր փորձարկման նստարանը, սկզբունքորեն, լավ ճշգրտություն է ապահովում:
Տարբերակ 1-ը նույնպես, ինչպես և սպասվում էր, պարզվում է, որ ամենադանդաղն է և ցույց է տալիս ցանցի չափին միմյանց ավելացնելու վրա ծախսվող ժամանակի գծային աճ:
Այժմ նայենք երկրորդ թեստի արդյունքներին։
NoSQL-ի համար տվյալների մոդելի նախագծման առանձնահատկությունները
3-5 տարբերակները կրկին իրենց պահում են այնպես, ինչպես սպասվում էր՝ մշտական ​​ժամանակ՝ անկախ ցանցի չափից: 1-ին և 2-րդ տարբերակները ցույց են տալիս ժամանակի գծային աճ, քանի որ ցանցի չափը մեծանում է և նմանատիպ կատարում: Ավելին, 2-րդ տարբերակը մի փոքր ավելի դանդաղ է ստացվում՝ ըստ երևույթին լրացուցիչ «հաշվի» սյունակը սրբագրելու և մշակելու անհրաժեշտության պատճառով, որն ավելի նկատելի է դառնում, քանի որ n-ը մեծանում է: Բայց ես դեռ ձեռնպահ կմնամ որևէ եզրակացություն անելուց, քանի որ այս համեմատության ճշգրտությունը համեմատաբար ցածր է։ Բացի այդ, այս գործակիցները (որ տարբերակը՝ 1 կամ 2, ավելի արագ է) փոխվել վազքից մինչև վազք (միաժամանակ պահպանելով կախվածության բնույթը և «վիզ ու վիզ գնալը»):

Դե, վերջին գրաֆիկը հեռացման փորձարկման արդյունք է:

NoSQL-ի համար տվյալների մոդելի նախագծման առանձնահատկությունները

Կրկին, այստեղ անակնկալներ չկան: 3-5 տարբերակները կատարում են հեռացում մշտական ​​ժամանակում:
Ավելին, հետաքրքիր է, որ 4-րդ և 5-րդ տարբերակները, ի տարբերություն նախորդ սցենարների, ցույց են տալիս նկատելիորեն մի փոքր ավելի վատ կատարողականություն, քան 3-րդ տարբերակը: Ըստ երևույթին, տողերի ջնջման գործողությունն ավելի թանկ է, քան սյունակի ջնջման գործողությունը, որն ընդհանուր առմամբ տրամաբանական է:

1-ին և 2-րդ տարբերակները, ինչպես և սպասվում էր, ցույց են տալիս ժամանակի գծային աճ: Միևնույն ժամանակ, 2-րդ տարբերակը հետևողականորեն ավելի դանդաղ է, քան 1-ին տարբերակը՝ հաշվիչ սյունակը «պահպանելու» լրացուցիչ I/O գործողության շնորհիվ:

Փորձի ընդհանուր եզրակացությունները.

  • 3-5 տարբերակները ցույց են տալիս ավելի մեծ արդյունավետություն, քանի որ նրանք օգտվում են HBase-ից; Ավելին, դրանց կատարումը միմյանց նկատմամբ տարբերվում է հաստատունով և կախված չէ ցանցի չափից:
  • 4-րդ և 5-րդ տարբերակների տարբերությունը չի արձանագրվել։ Բայց դա չի նշանակում, որ 5-րդ տարբերակը չպետք է օգտագործվի։ Հավանական է, որ օգտագործված փորձարարական սցենարը, հաշվի առնելով փորձարկման նստարանի կատարողականի բնութագրերը, թույլ չի տվել հայտնաբերել այն:
  • Տվյալներով «բիզնես գործառնություններ» կատարելու համար պահանջվող ժամանակի աճի բնույթն ընդհանուր առմամբ հաստատում էր բոլոր տարբերակների համար նախկինում ստացված տեսական հաշվարկները:

Վերջաբան

Կատարված կոպիտ փորձերը չպետք է ընկալվեն որպես բացարձակ ճշմարտություն։ Կան բազմաթիվ գործոններ, որոնք հաշվի չեն առնվել և խեղաթյուրել են արդյունքները (այս տատանումները հատկապես տեսանելի են ցանցի փոքր չափերով գրաֆիկներում)։ Օրինակ՝ խնայողության արագությունը, որն օգտագործում է happybase-ը, Python-ում իմ գրած տրամաբանության իրականացման ծավալն ու մեթոդը (չեմ կարող պնդել, որ կոդը գրվել է օպտիմալ և արդյունավետ՝ օգտագործել բոլոր բաղադրիչների հնարավորությունները), երևի. HBase քեշավորման առանձնահատկությունները, Windows 10-ի ֆոնային ակտիվությունը իմ նոութբուքի վրա և այլն: Ընդհանուր առմամբ, կարելի է ենթադրել, որ բոլոր տեսական հաշվարկները փորձնականորեն ապացուցել են իրենց վավերականությունը։ Դե, կամ գոնե այդպիսի «գլխով հարվածով» հերքել հնարավոր չէր։

Եզրափակելով՝ առաջարկություններ բոլորի համար, ովքեր նոր են սկսում HBase-ում տվյալների մոդելներ նախագծել. վերցեք հարաբերական տվյալների բազաների հետ աշխատելու նախորդ փորձից և հիշեք «պատվիրանները».

  • Նախագծելիս մենք ելնում ենք տվյալների մանիպուլյացիայի առաջադրանքից և օրինաչափություններից, այլ ոչ թե տիրույթի մոդելից
  • Արդյունավետ մուտք (առանց սեղանի ամբողջական սկանավորման) – միայն բանալիով
  • Ապանորմալացում
  • Տարբեր տողերը կարող են պարունակել տարբեր սյունակներ
  • Բարձրախոսների դինամիկ կազմը

Source: www.habr.com

Добавить комментарий