Ներածություն Redis-ի հոսքերին

Ներածություն Redis-ի հոսքերին

Redis-ը (Remote Dictionary Server) – դա բաց կոդով NoSQL դասի տվյալների բազաների կառավարման ռեզիդենտ համակարգ է (անգլ. in-memory database, IMDB), որն աշխատում է «բանալի-արժեք»(key-value) տիպի տվյալների կառուցվածքների հետ: Օգտագործվում է ինչպես տվյալների բազաների, այնպես էլ քեշավորման իրագործման և հաղորդագրությունների բրոքերի դերում: Redis-ը մեծ տարածում ունի ծրագրավորողների շրջանում իր գերարագության և տարբեր տեսակի տվյալների կառուցվածքների սպասարկման շնորհիվ, ինչպիսիք են տողերը, հեշերը, ցուցակները, հավաքածուները, գրաֆիկական նկարները, հոսքերը(stream) և այլն:

Ավելին, Redis-ն ունի բազմաթիվ ներկառուցված հնարավորություններ, ինչի պատճառով այս համակարգը այդքան պահանջված է. ներկառուցված կրկնօրինակումը-ռեպլիկացիան, Lua սցենարները, LRU-ի ջնջման ալգորիթմը, տրանզակցիաները և այլն: Հոդվածում մենք կխոսենք հոսքերի մասին, որը Redis-ի տվյալների կառուցվածքների տեսակներից մեկն է: Մենք կարող ենք հոսքերն օգտագործել՝ միկրոսերվիսի և նրա սպառողի(անգլ.՝ consumer, ռուս.՝ потребитель) միջև հաղորդագրությունների փոխանակման ծառայության համար:

Կարճ ասած, տվյալների այս կառուցվածքը մենք կարող ենք օգտագործել որպես հաղորդագրությունների բրոքեր, որի միջոցով միկրոսերվիսները կկարողանան փոխգործակցել: Այսպիսով…

Ի՞նչ են իրենցից ներկայացնում Redis-ի հոսքերը

Եթե փորձենք ամենապարզ ձևով սահմանել՝ հոսքերը դրանք Redis-ի տվյալների կառուցվածքներ են, որոնք հասանելի են միայն ավելացման համար: Այն ունի որոշակի նմանություն տվյալների մեկ այլ տիպի՝ ցուցակների(list) հետ, սակայն ավելի օգտակար և բարդ է: Հոսքային փոփոխականի մեջ տվյալներ/հաղորդագրություններ ավելացնելուն պես դրանք հասանելի են դառնում սպառողների համար: ԱՐԳԵԼԱՓԱԿՈՂ/ԲԼՈԿԱՎՈՐՈՂ API-ի շնորհիվ մենք կարող ենք ստիպել սպառողներին նոր հաղորդագրություններին սպասել: Այսպիսի տվյալների ստրուկտուրան տարբերվում է բարձր արագագործությամբ և իրագործման պարզությամբ: Սպառողները կարող են միավորվել սպառողների խմբերում, ինչը հնարավորություն կտա հաղորդագրությունների տարբեր ենթաբազմություն ուղարկել տարբեր սպառողների:

Կիրառման օրինակ

Ենթադրենք՝ ունենք երկու միկրոսերվիս, MS-1 և MS-2: Նրանց միջև փոխազդեցության կամ տվյալների սինխրոն փոխանակման անհրաժեշտություն կա: Նման սցենարի դեպքում առաջին պլան է գալիս հաղորդագրությունների փոխանակման ծառայությունը: Redis-ի հոսքերը դիրքավորվում են MS-1-ի և MS-2-ի միջև և հանդես են գալիս որպես հաղորդագրությունների բրոքեր/միջնորդ: Նրանք Redis-ի համապատասխան հոսքային փոփոխականների միջոցով հաղորդագրություններ/տվյալներ են փոխանցում MS-1-ից MS-2, և հակառակը:

Պարզության համար ենթադրենք նաև, որ MS-1-ն ինչ-որ տվյալներ է ավելացնում հոսքին, իսկ MS-2-ն անընդհատ լսում է նրան: Այս պարագայում, MS-1-ի կողմից հոսքին տվյալներ ավելացնուն պես, MS-2-ը կստանա դրանք:

Հիմնական գործողություններ

Հոսքի մեջ տվյալն ուղղակի տող չէ, այլ մեկ կամ մի քանի զույգ դաշտերի արժեքներից բաղկացած տող: Առանձնացվում են երկու հիմնական տիպի գործողություններ՝ հոսքի մեջ տվյալների ավելացում և հոսքից տվյալների ստացում:

Տվյալների ավելացում

Գրանցման հիմնական հրամանն այս դեպքում հանդիսանում է XADD-ը, որը նշված հոսքին նոր գրանցում/տվյալ է ավելացնում:

> XADD profile-information * name alex age 27 hair black

Sample Output
-------------------------------------------
1627885225420-0

Վերը նշված հրամանը հոսքի մեջ (profile information) բանալիով նոր գրանցում է ավելացնում: Այս հրամանն ավելի լավ հասկանալու համար փորձենք փոքր ինչ մանրամասնել:

  • XADD-ը հրաման է, որը Redis-ին ցուցում է, որ անհրաժեշտ է նոր գրանցում ավելացնել ըստ նշված բանալու:
  • Պրոֆիլի ինֆորմացիան (profile-information) - հոսքում մեր բանալի անունն է:
  • * սիմվոլը ցուցում է Redis-ին յուրաքանչյուր նոր գրանցման համար մոնոտոն աճող ID ստեղծելուն: Մենք նաև կարող ենք բացահայտ նշել ID-ն, բայց նման պրակտիկա շատ հազվադեպ է կիրառվում, ավելորդ անճշտություններից խուսափելու համար: Սերվերի կողմից ավտոմատ գեներացվող ID-ն լիարժեք բավարարում է բոլոր դեպքերի համար:
  • Հրամանի մնացած մասը բանալի-արժեք զույգն է, հոսքային գրառման հիմնական բաղադրիչը:
  • Հրամանի կատարման արդյունքում ելքում ստանում ենք 1627885225420-0, որն էլ հենց ID-ն է, ինչին կանդրադառնանք ստորև:

Մենք կարող ենք օգտագործել XLEN հրամանը՝ հոսքի մեջ առկա էլեմենտների քանակը ստանալու համար.

> XLEN profile-information

Sample Output
-------------------------------------------
(integer) 1
  • profile-information-ը մեր հոսքի բանալի անունն է:

Տվյալների ստացում

Եվ այսպես, արդեն իսկ տվյալ ավելացնելու փորձ ունենալով հանդերձ, հասկանանք, թէ ինչպես կարող ենք հոսքից տվյալներ ստանալ: Այս խնդրի լուծման երեք հիմնական օպերացիա կա, որոնք հերթականությամբ քննարկենք:

Հարցում ըստ դիապազոնի(միջակայքի, տիրույթի). XRANGE և XREVRANGE.

Բայց նախքան շարունակել ըստ դիապազոնի հարցումն ուսումնասիրելը, անհրաժեշտ է ավելի մոտիկից ծանոթանալ իդենտիֆիկատորի հետ (ID): XADD հրամանի արդյունքում վերադարձված իդենտիֆիկատորը, որն ունի 1627796743670–0 տեսքը, ներկայացված է հետևյալ ֆորմատով.

<millisecondsTime>-<sequenceNumber>
(<Ժամանակը միլիվայրկյաններով>-<Հերթական համար>)

Ժամանակը միլիվայրկյաններով  —  սա տեղական ժամանակն է Redis-ի լոկալ հանգույցում, իսկ հերթական համարն օգտագործվում է գրառումներն իրարից տարանջատելու համար, հաշվի առնելով, որ մեկից ավելի գրառում կարող են ստեղծվել միևնույն պահին և ունենալ միևնույն արժեքն ըստ միլիվարկյաների: Redis-ն ապահովում է այս արժեքների մոնոտոն աճման կարգով բաշխումը:

ID-ների առաջին մասը որպես կանոն(եթե այն գեներացվել է ավտոմատ) ժամանակի դրոշմ է, ուստի մենք հնարավորություն ունենք հարցումներ կատարել ժամանակի(ID-ների) տիրույթների հիման վրա: Ըստ դիապազոնի հարցում անելու համար անհրաժեշտ է նշել երկու իդենտիֆիկատոր՝ սկզբնականն ու վերջնականը՝ համապատասխանորեն: Ուշադրություն դարձրեք, որ ըստ միջակայքի հարցման արժեքները հանդիսանում է ներառվող: Սա նշանակոմ է, որ վերադարձվող տիրույթը կներառի սկզբնական կամ վերջնական արժեքով իդենտիֆիկատորներ ունեցող էլեմենտները ևս:

> XRANGE profile-information - +

Sample Output
-------------------------------------------
1) 1) 1627885225420-0
   2) 1) "name"
      2) "alex"
      3) "age"
      4) "27"
      5) "hair"
      6) "black"

Վերծանենք հրամանն ու ելքը.

  • XRANGE-ը ըստ դիապազոնի հարցման հրամանն է:
  • profile-information)-ը հոսքի բանալի անունն է:
  • (   և +) հատուկ իդենտիֆիկատորները նշանակում են տվյալ հոսքում հաանելի փոքրագույն և մեծագույն իդենտիֆիկատորները, այսինքն այն բազմության սահմանային արժեքները, որի մեջ կատարվելու է հարցումը:
  • Մենք կարող ենք նաև -ի և +-ի փոխարեն նշել ցանկացած հասանելի իդենտիֆիկատոր, որով կնշենք անհրաժեշտ դիապազոնի սկզբնական և վերջնական կետերը:

Ըստ ժամանակային միջակայքի հարցում

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

> XRANGE profile-information 1627796743670 1627799297560

Մենք կարող ենք COUNT հրաման նշել հարցման վերջում: Այդ կերպ մենք կստանանք միջակայքում ներառված առաջին N օբյեկտները:

> XRANGE profile-information - + COUNT 2

XREVRANGE-ն աշխատում է նույն կերպ, ինչպես XRANGE-ը, պարզապես հակառակ հերթակարգով:

> XREVRANGE profile-information + - COUNT 2

Ֆունկցիան կվերադարձնի դիապազոնում գտնված վերջին N էլեմենտները:

Նոր էլեմենտների ստացումը XREAD-ի միջոցով

Մենք կարող ենք բաժանորդագրվել նոր ստեղծվող էլեմենտների համար, որոնք կուղղվեն դեպի հոսք: Այս կոնցեպտը նման է Pub/Sub-ի աշխատանքի սկզբունքին, բայց այստեղ կա նշանակալի տարբերություններ:

Հիմնական նմանությունը նրանում է, որ հոսքին կարող է ունենալ մի քանի օգտագործող, և նոր ստեղծված ամեն մի էլեմենտ կառաքվի դրանցից յուրաքանչյուր հաղորդագրություն սպասողին: Սա որոշակիորեն նման է նաև ճյուղավորման տեխնոլոգիային, որպիսին և հանդիսանում է Pub/Sub-ը:

Իսկ հիմնական տարբերությունն էլ կայանում է նրանում, որ ի տարբերություն Pub/Sub-ի, որն աշխատում է Click-and-forget(սղմեց և մոռացավ) սկզբունքով, այն է, հաղորդագրությունների ճյուղավորումից հետո դրանք ջնջվում են Redis-ից, հոսքերի դեպքում ամեն ինչ այլ է: Նրանք պահպանում են հաղորդագրությունը՝ համապատասխան իդենտիֆիկատորի հետ միասին: Բացի հոսքերի ապահովումից, օգտագործողների խմբերը վերահսկողության այնպիսի մակարդակ են տրամադրում, որը հասանելի չէ Pub/Sub-ի կամ արգելափակման ցուցակների(lock lists) դեպքում:

XREAD -ը հոսք մտնող նոր հաղորդագրությունները լսելու հրամանն է:

> XREAD COUNT 1 STREAMS profile-information 0
  • COUNT-ը ոչ պարտադիր հրաման է՝ ելքային գրառումները սահմանափակելու համար: COUNT-ից հետո արժեքը ցույց է տալիս, թե քանի գրառում ենք ուզում կարդալ հոսքից:
  • STREAMS – պարտադիր նշում, որից հետո ցույց ենք տալիս հոսքի բանալի անունը:
  • Վերջին արժեքը (0) – հանդիսանում է իդենտիֆիկատոր: Այն ցույց է տալիս այն իդենտիֆկատորի համարը, որը ենթադրվում է որ արդեն իսկ պահպանված է հոսքի մեջ, և ակնկալվում է ստանալ դրան հաջորդող՝ նոր ստեղծվող գրառումները: Քանի որ մենք արդեն իսկ գիտենք, որ ավտոմատ գեներացված իդենտիֆիկատորները մոնոտոն աճում են, ուստի նոր իդենտիֆիկատորները կլինեն ավելի մեծ, քան մեր նշված արժեքն է: Մեր դեպքում 0-ն նշանակում է, որ մենք ցանկանում ենք, որ հոսքի սկզբնական հաղորդագրությունն ունենա 0-0-ից մեծ իդենտիֆիկատոր:

Մենք հեշտությամբ կարող ենք վերածել XREAD-ը բլոկավորող հրամանի:

> XREAD BLOCK 0 STREAMS profile-information $
  • BLOCK հրամանը 0 թայմաութի արժեքով նշանակում է, որ այս հրամանը կստուգի թե հնարավոր է արդյո՞ք անհապաղ մշակել հարցումը: Եթե այն կարողանա մշակել հարցումը՝ կկատարի մշակումը, հակառակ պարագայում հարցումը կարգելափակվի՝ մինչ տվյալների մուտքը:
  • $ – սա հատուկ ID է, որը ներկայացնում է հոսքերում արդեն իսկ պահված առավելագույն ID-ն, այնպես որ մենք կստանանք միայն նոր հաղորդագրություններ:
  • Մենք նաև նշել ենք COUNT կարգավորումը, որպեսզի սահմանափակենք ելքային արժեքները: Իրականում, XREAD-ին ունի ընդամենը երկու կարգավորման հնարավորություն՝ դրանք BLOCK-ն ու COUNT-ն են:

Սպառողների խմբեր

Մենք հասնում ենք հոդվածի ամենահետաքրքիր մասին. XREAD-ն առաջարկում է ճյուղավորման տեխնոլոգիայի առավելությունները: Հիմա անդրադառնանք մեկ այլ դեպքի. Ենթադրենք, մենք ունենք բազմաթիվ սպառողներ և ցանկանում ենք նրանց միջև տարածել հաղորդագրությունների ենթախումբ: Մենք նույն հաղորդագրությունը չենք փոխանցի տարբեր սպառողներին։ Ենթադրենք, մենք ունենք երկու սպառող՝ C1 և C2 և 7 հաղորդագրություն, որոնց ID-ներն են 1, 2, 3, 4, 5, 6, 7: Մենք ցանկանում ենք այս հաղորդագրությունները բաշխել C1 և C2 միջև հետևյալ կերպ.

1 -> C1
2 -> C2
3 -> C1
4 -> C2
5 -> C1
6 -> C2
7 -> C1

Հավանաբար դուք նկատեցիք, որ մենք ոչ թե միևնույն հաղորդագրությունն ուղարկում եք բոլոր սպառողներին, այլ տարբեր հաղորդագրություններ ուղարկվում են տարբեր սպառողների: Այս դեպքում մեզ օգնում են սպառողների խմբերը։

Սպառողների խմբի ստեղծումը

Ենթադրենք, մենք արդեն իսկ ունենք profile-information բանալի անունով հոսք: Այս դեպքում հետևյալ հրամանը կստեղծի սպառողների խումբ.

> XGROUP CREATE profile-information mygroup $
  • Մենք արդեն գիտեք, որ $-ը հատուկ իդենտիֆիկատոր է, որը ներկայացնում է հոսքերում հասանելի վերջին առավելագույն ID-ն: Սպառողների խումբը պետք է իմանա, թե որտեղից սկսած պետք է հետևի իր սպառողի հաղորդագրություններին: $ փոխանցելով միայն այս խմբի ստեղծումից հետո նոր հաղորդագրությունները կհետևվեն: Եթե ​​$-ի փոխարեն փոխանցենք 0, ապա այս խումբը կօգտագործի բոլոր հաղորդագրությունները հոսքի սկզբից: Մենք կարող ենք տրամադրել ցանկացած վավեր իդենտիֆիկատոր, որը ցույց է տալիս մեկնարկային կետը, որտեղից խումբը կստանա հաղորդագրությունը:
  • mygroup – խմբի անվանումը:
  • profile-information – գոյություն ունեցող հոսքի բանալի անունը:
  • Եթե ​​հոսքը գոյություն չունի, XGROUP-ը կօգնի ստեղծել այն՝ փոխանցելով ենթահրաման վերջին MKSTREAM -ին:
> XGROUP CREATE newstream mygroup $ MKSTREAM

Խմբից սպառման գործընթացը

Redis-ը տրամադրում է գրեթե նմանատիպ հրաման, որը կոչվում է XREADGROUP՝ BLOCK կարգավորիչով (այս դիրեկտիվի բացակայությունը հրամանը կդարձնի ասինխրոն): Առկա է նաև GROUP կարգավորիչը՝ երկու արգումենտով. սպառողների խմբի անունը և այն սպառողի անունը, որը փորձում է կարդալ տեղեկատվությունը:

> XREADGROUP BLOCK 0 GROUP mygroup John COUNT 1 STREAMS profile-information >
  • Հրամանը հիմնականում նկարագրական է: Այն ասում է, որ անհրաժեշտ է “John” անունով օգտագործողի անունից կարդալ տվյալները profile information հոսքից՝ օգտագործելով mygroup սպառողների խումբը: Յուրաքանչյուր սպառող պետք է նշի իր անունը, որը կծառայի որպես խմբի ներսում նրա տարբերիչ իդենտիֆիկատոր:
  • & gt;-ը ևս մեկ հատուկ իդենտիֆիկատոր, որն աշխատում է միայն սպառողների խմբերի համատեքստում: Դա նշանակում է, որ տվյալ պահին հաղորդագրությունները դեռևս չեն հասցվել այլ սպառողների:

Առաջիկայում մենք կշարունակենք Redis-ի հոսքերի ներածությունը՝ երկրորդ մասով, որտեղ կդիտարկենք ձախողված գործողությունների վերականգնումը, ավտոմատ հարցումները, հարցումների և առաքումների հաշվիչները, ռեպլիկացիայի և անվտանգությանը վերաբերող հարցեր:

Սկզբնաղբյուր՝ Introduction to Redis Streams