
Խափանումների նկատմամբ հանդուրժողականությունը և բարձր մատչելիությունը մեծ թեմաներ են, ուստի մենք առանձին հոդվածներ կնվիրենք RabbitMQ-ին և Kafka-ին։ Այս հոդվածը RabbitMQ-ի մասին է, իսկ հաջորդը՝ Kafka-ի մասին՝ համեմատած RabbitMQ-ի հետ։ Սա երկար հոդված է, այնպես որ հարմարվեք։
Եկեք նայենք սխալների նկատմամբ հանդուրժողականության, հետևողականության և բարձր մատչելիության (ԲՄ) ռազմավարություններին, ինչպես նաև յուրաքանչյուր ռազմավարության մեջ ներառված փոխզիջումներին։ RabbitMQ-ն կարող է աշխատել հանգույցների կլաստերի վրա և այնուհետև դասակարգվում է որպես բաշխված համակարգ։ Երբ մենք խոսում ենք բաշխված համակարգերի մասին, մենք հաճախ խոսում ենք հետևողականության և մատչելիության մասին։
Այս հասկացությունները նկարագրում են, թե ինչպես է համակարգը գործում, երբ տեղի է ունենում խափանում։ Ցանցային կապի խափանում, սերվերի խափանում, կոշտ սկավառակի խափանում, սերվերը ժամանակավորապես անհասանելի է աղբահանության, փաթեթների կորստի կամ դանդաղ ցանցային կապի պատճառով։ Այս ամենը կարող է հանգեցնել տվյալների կորստի կամ կոնֆլիկտների։ Պարզվում է, որ գործնականում անհնար է ստեղծել մի համակարգ, որը և՛ լիովին հետևողական է (տվյալների կորուստ, տվյալների անհամապատասխանություններ չկան), և՛ մատչելի (կընդունի ընթերցման և գրելու գործողություններ) բոլոր խափանումների ռեժիմների համար։
Մենք կտեսնենք, որ հետևողականությունն ու մատչելիությունը սպեկտրի տարբեր ծայրերում են, և դուք պետք է ընտրեք, թե որ մեկը օպտիմալացնել։ Լավ նորությունն այն է, որ RabbitMQ-ի հետ այս ընտրությունը հնարավոր է։ Դուք ունեք այս խելացի փոքրիկ լծակները՝ հավասարակշռությունը փոխելու ավելի մեծ համահունչության կամ ավելի մատչելիության ուղղությամբ:
Մենք հատուկ ուշադրություն կդարձնենք, թե որ կարգավորումներն են հանգեցնում տվյալների կորստի՝ կապված գրանցված գրառումների հետ։ Հրատարակիչների, միջնորդների և սպառողների միջև կա պատասխանատվության շղթա։ Երբ հաղորդագրությունը փոխանցվում է բրոքերին, նրա աշխատանքն է չկորցնել այն։ Երբ միջնորդը հաստատում է հաղորդագրության ստացումը հրատարակչին, մենք չենք սպասում, որ այն կկորչի։ Բայց մենք կտեսնենք, որ սա իսկապես կարող է տեղի ունենալ՝ կախված ձեր բրոքերի և հրատարակչի կարգավորումներից։
Միակ հանգույցի կայունության պրիմիտիվներ
Մշտական հերթեր/ուղղորդում
RabbitMQ-ն ունի երկու հերթի տեսակ՝ դիմացկուն և ոչ դիմացկուն։ Բոլոր հերթերը պահվում են Mnesia տվյալների բազայում։ Կայուն հերթերը վերստին հայտարարվում են, երբ հանգույցը մեկնարկում է, և այդպիսով գոյատևում են վերագործարկման, համակարգի վթարի կամ սերվերի խափանման դեպքում (քանի դեռ տվյալները պահպանվում են): Սա նշանակում է, որ քանի դեռ դուք հայտարարում եք փոխանակման և հերթի կայունությունը, հերթագրման/երթուղղման ենթակառուցվածքը կրկին կաշխատի։
Անկայուն հերթերը և երթուղայնացումը հեռացվում են հանգույցի վերագործարկման ժամանակ։
Մշտական հաղորդագրություններ
Այն, որ հերթը երկարակյաց է, չի նշանակում, որ դրա բոլոր հաղորդագրությունները կդիմանան հանգույցի վերագործարկումից հետո։ Միայն հրատարակչի կողմից սահմանված հաղորդագրությունները որպես ախոռ (համառ): Մշտական հաղորդագրությունները լրացուցիչ բեռ են ստեղծում բրոքերի վրա, բայց եթե հաղորդագրությունների կորուստը անընդունելի է, ապա այլ ճանապարհ չկա։

Բրինձ։ 1. Կայունության մատրից
Կլաստերացում հերթի հայելային օգտագործմամբ
Բրոքերի կորստից հետո գոյատևելու համար մեզ անհրաժեշտ է աշխատակիցների ավելորդ քանակ։ Մենք կարող ենք մի քանի RabbitMQ հանգույցներ միավորել կլաստերի մեջ, այնուհետև ավելացնել լրացուցիչ ավելորդություն՝ կրկնապատկելով հերթերը բազմաթիվ հանգույցների միջև։ Այսպիսով, եթե մեկ հանգույց անջատվի, մենք չենք կորցնի տվյալներ և կմնանք հասանելի։
Հերթի հայելային արտացոլում.
- մեկ հիմնական հերթ (master), որը ստանում է բոլոր գրելու և կարդալու հրամանները
- մեկ կամ մի քանի հայելիներ, որոնք ստանում են բոլոր հաղորդագրությունները և մետատվյալները հիմնական հերթից։ Այս հայելիները գոյություն չունեն մասշտաբավորման, այլ զուտ ավելորդության համար։

Բրինձ։ 2. Հերթի հայելային արտացոլում
Հայելային արտացոլումը սահմանվում է համապատասխան քաղաքականությամբ։ Դրանում կարող եք ընտրել կրկնօրինակման գործոնը և նույնիսկ այն հանգույցները, որոնց վրա պետք է տեղադրվի հերթը։ Օրինակներ՝
ha-mode: allha-mode: exactly, ha-params: 2(մեկ վարպետ և մեկ հայելի)ha-mode: nodes, ha-params: rabbit@node1, rabbit@node2
Հրատարակչին ուղղված հաստատումը
Հրատարակչի հաստատումները պարտադիր են հետևողական ձայնագրություն ապահովելու համար։ Առանց դրանց, հաղորդագրությունները կորցնելու ռիսկ կա։ Հաղորդագրությունը սկավառակի վրա գրվելուց հետո հրատարակչին ուղարկվում է հաստատում։ RabbitMQ-ն հաղորդագրությունները սկավառակի վրա գրում է ոչ թե ստացվելուց հետո, այլ պարբերաբար՝ մի քանի հարյուր միլիվայրկյանների ընթացքում։ Երբ հերթը հայելային է, հաստատումն ուղարկվում է միայն այն բանից հետո, երբ բոլոր հայելիները նույնպես գրել են հաղորդագրության իրենց պատճենը սկավառակի վրա։ Սա նշանակում է, որ հաստատումների օգտագործումը ավելացնում է լատենտությունը, բայց եթե տվյալների անվտանգությունը կարևոր է, ապա դրանք անհրաժեշտ են։
Խափանումներին դիմացկուն հերթ
Երբ բրոքերը դադարեցնում է աշխատանքը կամ վթարի է ենթարկվում, այդ հանգույցի բոլոր վարպետները անջատվում են դրա հետ միասին։ Այնուհետև կլաստերը ընտրում է յուրաքանչյուր գլխավորի ամենահին հայելին և այն առաջ է մղում որպես նոր գլխավոր հայելի։

Բրինձ։ 3. Բազմակի հայելային հերթեր և դրանց քաղաքականությունները
Բրոքեր 3-ը անգործ է։ Խնդրում ենք նկատի ունենալ, որ Բրոքեր 2-ի հերթի C հայելին բարձրացվում է մինչև վարպետի։ Նաև նկատի ունեցեք, որ Broker 1-ի վրա ստեղծվել է նոր հայելի C հերթի համար: RabbitMQ-ն միշտ փորձում է պահպանել ձեր քաղաքականություններում նշված կրկնօրինակման գործակիցը:

Բրինձ։ 4. Բրոքեր 3-ը անջատվում է, ինչը հանգեցնում է C հերթի ձախողմանը։
Հաջորդ Բրոքեր 1-ը ընկնում է։ Մեզ մոտ մնացել է միայն մեկ միջնորդ։ Հերթի B հայելին բարձրացվում է վարպետի մակարդակի։

Բրինձ. 5
Մենք վերադարձրել ենք Բրոքեր 1-ը։ Անկախ նրանից, թե որքան լավ են տվյալները դիմացել բրոքերի կորստից և վերականգնումից հետո, բոլոր հայելային հերթի հաղորդագրությունները վերագործարկման ժամանակ ջնջվում են։ Սա կարևոր է հաշվի առնել, քանի որ հետևանքներ կլինեն։ Այս հետևանքներին մենք շուտով կանդրադառնանք։ Այսպիսով, Բրոքեր 1-ը կրկին կլաստերի անդամ է, և կլաստերը փորձում է համապատասխանել քաղաքականությանը և, հետևաբար, ստեղծում է հայելիներ Բրոքեր 1-ի վրա։
Այս դեպքում, Բրոքեր 1-ի կորուստը լիակատար էր, ինչպես նաև տվյալները, ուստի չհայելային B հերթը կորավ ամբողջությամբ։

Բրինձ։ 6. Բրոքեր 1-ը վերադարձել է գործի
Բրոքեր 3-ը կրկին առցանց է, ուստի A և B հերթերը կրկին ստանում են իրենց հայելիները դրա վրա՝ իրենց HA քաղաքականությունները բավարարելու համար։ Բայց հիմա բոլոր հիմնական հերթերը մեկ հանգույցի վրա են։ Սա իդեալական չէ, հանգույցների միջև միատարր բաշխումն ավելի լավ է։ Դժբախտաբար, այստեղ վարպետների վերահավասարակշռման հատուկ տարբերակներ չկան: Այս խնդրին կանդրադառնանք ավելի ուշ, քանի որ նախ պետք է հաշվի առնենք հերթի համաժամեցումը։

Բրինձ։ 7. Բրոքեր 3-ը վերադառնում է ծառայության։ Բոլոր հիմնական հերթերը մեկ հանգույցում։
Այսպիսով, դուք հիմա պետք է պատկերացում կազմեք, թե ինչպես են հայելիները ապահովում ավելորդություն և մեղքի հանդուրժողականություն: Սա ապահովում է մատչելիությունը մեկ հանգույցի խափանման դեպքում և պաշտպանում է տվյալների կորստից։ Բայց մենք դեռ չենք ավարտել, քանի որ իրականում ամեն ինչ շատ ավելի բարդ է։
Համաժամեցում
Երբ դուք ստեղծում եք նոր հայելի, բոլոր նոր հաղորդագրությունները միշտ կկրկնօրինակվեն այդ և մյուս հայելիներում։ Ինչ վերաբերում է գլխավոր հերթում առկա տվյալներին, մենք կարող ենք դրանք կրկնօրինակել նոր հայելու մեջ, որը կդառնա գլխավորի ամբողջական պատճենը։ Մենք կարող ենք նաև ընտրել չկրկնօրինակել առկա հաղորդագրությունները և թույլ տալ, որ հիմնական հերթը և նոր հայելին ժամանակի ընթացքում միաձուլվեն, քանի որ նոր հաղորդագրությունները հասնում են պոչ, իսկ առկա հաղորդագրությունները լքում են հիմնական հերթի գլուխը։
Այս համաժամեցումը կատարվում է ավտոմատ կերպով կամ ձեռքով և կառավարվում է հերթագրման քաղաքականությամբ։ Եկեք նայենք մի օրինակի։
Մենք ունենք երկու հայելային հերթեր։ Հերթ A-ն համաժամեցվում է ավտոմատ կերպով, մինչդեռ հերթ B-ն՝ ձեռքով։ Երկու հերթերում էլ կա տաս հաղորդագրություն։

Բրինձ։ 8. Երկու հերթեր՝ տարբեր համաժամացման ռեժիմներով
Հիմա մենք կորցնում ենք Բրոքեր 3-ին։

Բրինձ։ 9. Բրոքեր 3-ը ընկավ
Բրոքեր 3-ը վերադարձել է գործի։ Կլաստերը ստեղծում է հայելի նոր հանգույցի յուրաքանչյուր հերթի համար և ավտոմատ կերպով համաժամեցնում է նոր A հերթը գլխավորի հետ։ Սակայն, նոր Հերթ B-ի հայելին մնում է դատարկ։ Այսպիսով, մենք ունենք A հերթի լրիվ ավելորդություն և միայն մեկ հայելային արտացոլում B հերթի առկա հաղորդագրությունների համար։

Բրինձ։ 10. Հերթ A-ի նոր հայելին ստանում է բոլոր առկա հաղորդագրությունները, բայց Հերթ B-ի նոր հայելին՝ ոչ։
Երկու հերթերում էլ հասնում է ևս տասը հաղորդագրություն։ Այնուհետև Բրոքեր 2-ը խափանվում է, և Հերթ A-ն վերադառնում է ամենահին հայելուն, որը գտնվում է Բրոքեր 1-ի վրա: Խափանման դեպքում տվյալների կորուստ չկա: B հերթը գլխավոր հիշողության մեջ ունի քսան հաղորդագրություն և միայն տասը՝ հայելու մեջ, քանի որ այս հերթը երբեք չի կրկնօրինակել սկզբնական տասը հաղորդագրությունները։

Բրինձ։ 11. Հերթ A-ն վերադառնում է Բրոքեր 1-ին՝ առանց հաղորդագրությունները կորցնելու։
Երկու հերթերում էլ հասնում է ևս տասը հաղորդագրություն։ Այժմ Բրոքեր 1-ը խափանվում է։ Հերթ A-ն անցնում է հայելուն առանց որևէ խնդրի և առանց հաղորդագրությունների կորստի։ Սակայն, B հերթը խնդիրներ ունի։ Այս փուլում մենք կարող ենք օպտիմալացնել կամ մատչելիությունը, կամ հետևողականությունը։
Եթե մենք ցանկանում ենք օպտիմալացնել մատչելիությունը, ապա քաղաքականությունը հա-խթանել-ձախողման դեպքում պետք է տեղադրվի միշտ. Սա լռելյայն արժեքն է, ուստի դուք պարզապես չեք կարող ընդհանրապես նշել քաղաքականությունը։ Այս դեպքում մենք, ըստ էության, թույլ ենք տալիս ձախողումներ չսինխրոնացված հայելիներում։ Սա կհանգեցնի հաղորդագրությունների կորստի, բայց հերթը կմնա հասանելի ընթերցման և գրելու համար։

Բրինձ։ 12. Հերթ A-ն վերադառնում է Բրոքեր 3-ին՝ առանց հաղորդագրությունները կորցնելու։ B հերթը վերադառնում է միջնորդ 3-ին՝ տասը հաղորդագրությունների կորստով։
Մենք կարող ենք նաև տեղադրել ha-promote-on-failure իմաստի մեջ when-synced. Այս դեպքում, հայելուն վերադառնալու փոխարեն, հերթը կսպասի մինչև Բրոքեր 1-ը իր տվյալներով վերադառնա գործառնական ռեժիմի։ Նրա վերադարձից հետո հիմնական հերթը կրկին գտնվում է Բրոքեր 1-ի վրա՝ առանց տվյալների որևէ կորստի։ Հասանելիությունը զոհաբերվում է տվյալների անվտանգության համար։ Սակայն սա ռիսկային ռեժիմ է, որը կարող է նույնիսկ հանգեցնել տվյալների լիակատար կորստի, որին մենք շուտով կանդրադառնանք։

Բրինձ։ 13. B հերթը մնում է անհասանելի Բրոքեր 1-ին կորցնելուց հետո
Դուք կարող եք հարցնել. «Գուցե ավելի լավ է երբեք չօգտագործել ավտոմատ համաժամեցումը»։ Պատասխանն այն է, որ համաժամեցումը արգելափակող գործողություն է։ Սինխրոնիզացիայի ընթացքում հիմնական հերթը չի կարող կատարել որևէ ընթերցման կամ գրելու գործողություն։
Եկեք նայենք մի օրինակի։ Մենք հիմա շատ երկար հերթեր ունենք։ Ինչպե՞ս կարող են նրանք այդպիսի չափի աճել։ Մի քանի պատճառներով.
- Հերթերը ակտիվորեն չեն օգտագործվում
- Սրանք բարձր արագությամբ հերթեր են, և այս պահին սպառողները դանդաղ են աշխատում։
- Սրանք բարձր արագությամբ հերթեր են, խնդիր է առաջացել, և սպառողները հասցնում են փոխհատուցել։

Բրինձ։ 14. Երկու մեծ հերթեր՝ տարբեր համաժամեցման ռեժիմներով
Հիմա Բրոքեր 3-ը անկում է ապրում։

Բրինձ։ 15. Բրոքեր 3-ը խափանվում է, յուրաքանչյուր հերթում թողնելով մեկ գլխավոր և մեկ հայելի։
Բրոքեր 3-ը կրկին առցանց է, և նոր հայելիներ են ստեղծվում։ Գլխավոր հերթ A-ն սկսում է առկա հաղորդագրությունները կրկնօրինակել նոր հայելու մեջ, և այս ընթացքում հերթը անհասանելի է։ Տվյալները կրկնօրինակելու համար պահանջվում է երկու ժամ, ինչը հանգեցնում է այս հերթի երկու ժամյա անգործության։
Այնուամենայնիվ, B հերթը մնում է հասանելի ամբողջ ժամանակահատվածում։ Նա զոհաբերեց որոշ ավելորդություններ՝ հասանելիության համար։

Բրինձ։ 16. Հերթը մնում է անհասանելի համաժամեցման ընթացքում
Երկու ժամ անց A հերթը նույնպես հասանելի կդառնա և կարող է կրկին սկսել կարդալու և գրելու գործողություններ ընդունել։
Updates
Սինխրոնիզացման ընթացքում այս արգելափակող վարքագիծը դժվարացնում է շատ մեծ հերթերով կլաստերների թարմացումը։ Որոշակի պահի գլխավոր հանգույցը պետք է վերագործարկվի, ինչը նշանակում է կամ անցնել հայելու, կամ անջատել հերթը, մինչ սերվերը թարմացվում է։ Եթե որոշենք տեղափոխել, կկորցնենք հաղորդագրությունները, եթե հայելիները համաժամեցված չեն։ Ըստ լռելյայնի, երբ բրոքերը անջատված է, չսինխրոնացված հայելու անցումը չի կատարվում։ Սա նշանակում է, որ բրոքերի վերադարձից հետո մենք ոչ մի հաղորդագրություն չենք կորցնում, միակ վնասը հերթի անգործունությունն է։ Բրոքերին անջատելիս վարքագծի կանոնները սահմանվում են քաղաքականությամբ ha-promote-on-shutdown. Կարող եք սահմանել երկու արժեքներից մեկը՝
always= չսինխրոնացված հայելիների անցումը միացված էwhen-synced= անցնել միայն համաժամեցված հայելու, հակառակ դեպքում հերթը կդառնա անհասանելի կարդալու և գրելու համար։ Հերթը կվերականգնվի իր տեղը, հենց որ միջնորդը վերադառնա։
Ամեն դեպքում, երկար հերթերի դեպքում դուք պետք է ընտրեք տվյալների կորստի և անհասանելիության միջև։
Երբ մատչելիությունը բարելավում է տվյալների անվտանգությունը
Որոշում կայացնելուց առաջ կա ևս մեկ բարդություն, որը պետք է հաշվի առնել։ Թեև ավտոմատ համաժամեցումն ավելի լավ է ավելորդության համար, ինչպե՞ս է այն ազդում տվյալների անվտանգության վրա: Անշուշտ, ավելի լավ ավելորդության շնորհիվ, RabbitMQ-ն ավելի քիչ հավանականություն ունի կորցնելու առկա հաղորդագրությունները, բայց ի՞նչ կասեք հրատարակիչների նոր հաղորդագրությունների մասին:
Այստեղ դուք պետք է հաշվի առնեք հետևյալը.
- Կարո՞ղ է հրատարակիչը պարզապես սխալ վերադարձնել, և վերին հոսանքի ծառայությունը կամ օգտատերը կարող են ավելի ուշ կրկին փորձել։
- Կարո՞ղ է հրատարակիչը պահել հաղորդագրությունը տեղական կամ տվյալների բազայում՝ ավելի ուշ նորից փորձելու համար:
Եթե հրատարակիչը կարող է միայն մերժել հաղորդագրությունը, ապա իրականում մատչելիության բարելավումը նաև բարելավում է տվյալների անվտանգությունը։
Այսպիսով, անհրաժեշտ է հավասարակշռություն փնտրել, և լուծումը կախված է կոնկրետ իրավիճակից։
Խնդիրներ ha-promote-on-failure=when-synced-ի հետ
Գաղափար հա-խթանել-ձախողման դեպքում= համաժամեցման ժամանակ այն է, որ մենք կանխում ենք չսինխրոնացված հայելու անցումը և այդպիսով խուսափում տվյալների կորստից։ Հերթը մնում է անհասանելի կարդալու կամ գրելու համար։ Դրա փոխարեն մենք փորձում ենք վերականգնել վթարի ենթարկված բրոքերը՝ ամբողջական տվյալներով, որպեսզի այն կարողանա վերսկսել իր գործունեությունը որպես գլխավոր սերվեր՝ առանց տվյալներ կորցնելու։
Բայց (և սա մեծ «բայց» է), եթե բրոքերը կորցրել է իր տվյալները, ապա մենք մեծ խնդիր ունենք. հերթը կորած է։ Բոլոր տվյալները կորած են։ Նույնիսկ եթե դուք ունեք հայելիներ, որոնք հիմնականում հասնում են հիմնական հերթին, այդ հայելիները նույնպես անտեսվում են։
Նույն անունով հանգույցը վերստին ավելացնելու համար մենք հրահանգում ենք կլաստերին մոռանալ կորցրած հանգույցը (օգտագործելով հրամանը) rabbitmqctl forget_cluster_node) և սկսել նոր բրոքեր նույն հոսթանվան ներքո։ Քանի դեռ կլաստերը հիշում է կորած հանգույցը, այն հիշում է նաև հին հերթը և անսինխրոն հայելիները։ Երբ կլաստերին հրահանգվում է մոռանալ կորցրած հանգույցը, այս հերթը նույնպես մոռացվում է։ Հիմա մենք պետք է կրկին հայտարարենք դրա մասին։ Մենք կորցրեցինք բոլոր տվյալները, չնայած որ ունեինք մասնակի տվյալներով հայելիներ։ Ավելի լավ կլինի անցնել ոչ սինխրոն հայելու։
Հետևաբար, ձեռքով համաժամեցումը (և համաժամեցման ձախողումը) համակցված է ha-promote-on-failure=when-syncedիմ կարծիքով, բավականին ռիսկային է։ Փաստաթղթերում ասվում է, որ այս տարբերակը գոյություն ունի տվյալների անվտանգության համար, բայց դա երկկողմանի սուր է։
Վարպետների վերահավասարակշռում
Ինչպես խոստացել էինք, մենք վերադառնում ենք բոլոր վարպետների մեկ կամ մի քանի հանգույցների վրա հավաքվելու խնդրին։ Սա կարող է տեղի ունենալ նույնիսկ կլաստերի անընդհատ թարմացման արդյունքում։ Երեք հանգույցից բաղկացած կլաստերում բոլոր հիմնական հերթերը կկենտրոնանան մեկ կամ երկու հանգույցների վրա։
Վերաբալանսավորող վարպետների վերաբաշխումը կարող է խնդրահարույց լինել երկու պատճառով.
- Վերահաշվարկ կատարելու համար լավ գործիքներ չկան
- Հերթի համաժամեցում
Կա երրորդ կողմ՝ վերահավասարակշռման համար , որը պաշտոնապես չի աջակցվում։ RabbitMQ ձեռնարկում երրորդ կողմի հավելվածների վերաբերյալ «Մոդուլը տրամադրում է որոշ լրացուցիչ կարգավորման և հաշվետվությունների գործիքներ, բայց չի աջակցվում կամ փորձարկվում RabbitMQ թիմի կողմից։ Օգտագործեք ձեր սեփական ռիսկով։»
Կա ևս մեկ հնարք՝ հիմնական հերթը HA քաղաքականությունների միջոցով տեղափոխելու համար։ Ձեռնարկը նշում է սրա համար։ Այն աշխատում է այսպես՝
- Հեռացնում է բոլոր հայելիները՝ օգտագործելով ժամանակավոր քաղաքականություն, որն ավելի բարձր առաջնահերթություն ունի, քան առկա HA քաղաքականությունը։
- Փոխում է HA ժամանակավոր քաղաքականությունը՝ օգտագործելու «հանգույցներ» ռեժիմը՝ նշելով այն հանգույցը, որտեղ պետք է տեղափոխվի գլխավոր հերթը։
- Սինխրոնացնում է հարկադիր տեղափոխման հերթը։
- Տեղափոխման ավարտից հետո ժամանակավոր քաղաքականությունը հեռացվում է։ Սկզբնական HA քաղաքականությունը ուժի մեջ է մտնում, և ստեղծվում է անհրաժեշտ քանակությամբ հայելիներ։
Թերությունն այն է, որ այս մոտեցումը կարող է չաշխատել, եթե ունեք մեծ հերթեր կամ խիստ ավելորդության պահանջներ։
Հիմա եկեք նայենք, թե ինչպես են RabbitMQ կլաստերները աշխատում ցանցային բաժանմունքների հետ։
Կապի խախտում
Բաշխված համակարգի հանգույցները միացված են ցանցային կապերով, և ցանցային կապերը կարող են և կանջատվեն։ Անջատումների հաճախականությունը կախված է տեղական ենթակառուցվածքից կամ ընտրված ամպի հուսալիությունից։ Ամեն դեպքում, բաշխված համակարգերը պետք է կարողանան դրանք կարգավորել։ Մենք կրկին կանգնած ենք մատչելիության և հետևողականության միջև ընտրության առաջ, և կրկին լավ լուրն այն է, որ RabbitMQ-ն ապահովում է երկուսն էլ (պարզապես ոչ միաժամանակ):
RabbitMQ-ի հետ մենք ունենք երկու հիմնական տարբերակ՝
- Թույլատրել ուղեղի պառակտումը։ Սա ապահովում է մատչելիությունը, բայց կարող է հանգեցնել տվյալների կորստի։
- Անջատեք տրամաբանական տարանջատումը։ Կարող է հանգեցնել կարճաժամկետ հասանելիության կորստի՝ կախված նրանից, թե ինչպես են հաճախորդները միանում կլաստերին։ Այն կարող է նաև հանգեցնել երկու հանգույցից բաղկացած կլաստերում լիակատար անհասանելիության։
Բայց ի՞նչ է տրամաբանական բաժանումը։ Սա այն դեպքն է, երբ կլաստերը բաժանվում է երկու մասի՝ ցանցային կապերի կորստի պատճառով։ Հայելու յուրաքանչյուր կողմը բարձրացվում է վարպետի կարգավիճակի, այնպես որ յուրաքանչյուր հերթում հայտնվում են մի քանի վարպետներ։

Բրինձ։ 17. Հիմնական հերթը և երկու հայելիներ, որոնցից յուրաքանչյուրը գտնվում է առանձին հանգույցի վրա։ Այնուհետև տեղի է ունենում ցանցի խափանում, և մեկ հայելին առանձնանում է։ Առանձնացված հանգույցը տեսնում է, որ մյուս երկուսը պոկվել են և իր հայելիները տեղափոխում է գլխավորին։ Մենք այժմ ունենք երկու հիմնական հերթեր՝ և՛ գրելու, և՛ կարդալու համար։
Եթե հրատարակիչները տվյալներն ուղարկեն երկու հիմնական ֆայլերին էլ, մենք կստանանք հերթի երկու տարբեր օրինակներ։
RabbitMQ-ի տարբեր ռեժիմները ապահովում են կամ մատչելիություն, կամ հետևողականություն։
Անտեսել ռեժիմը (նախնական)
Այս ռեժիմը ապահովում է հասանելիություն։ Համահունչության կորստից հետո տեղի է ունենում տրամաբանական տարանջատում։ Կապը վերականգնվելուց հետո, ադմինիստրատորը պետք է որոշի, թե որ բաժանմանը տալ առաջնահերթություն։ Պարտվող կողմը կվերագործարկվի, և այդ կողմում կուտակված բոլոր տվյալները կկորչեն։

Բրինձ։ 18. Երեք հրատարակիչներ կապված են երեք միջնորդների հետ։ Ներքինորեն, կլաստերը բոլոր հարցումները ուղղորդում է Broker 2-ի հիմնական հերթին։
Հիմա մենք կորցնում ենք Բրոքեր 3-ին։ Նա տեսնում է, որ մյուս բրոքերները դուրս են եկել խաղից և իր հայելին դարձնում է վարպետ։ Այսպես է տեղի ունենում տրամաբանական բաժանումը։

Բրինձ։ 19. Տրամաբանական բաժանում (ուղեղի բաժանում): Գրառումները բաժանվում են երկու հիմնական հերթերի, և երկու օրինակները տարբերվում են։
Համահունչությունը վերականգնված է, բայց տրամաբանական տարանջատումը մնում է։ Ադմինիստրատորը պետք է ձեռքով ընտրի պարտվող կողմը։ Ստորև բերված դեպքում ադմինիստրատորը վերագործարկում է Broker 3-ը: Բոլոր հաղորդագրությունները, որոնք այն չի կարողացել փոխանցել, կորչում են:

Բրինձ։ 20. Ադմինիստրատորը անջատում է Բրոքեր 3-ը։

Բրինձ։ 21. Ադմինիստրատորը գործարկում է Բրոքեր 3-ը, և այն միանում է կլաստերին՝ կորցնելով այնտեղ մնացած բոլոր հաղորդագրությունները։
Կապի կորստի ընթացքում և վերականգնումից հետո կլաստերը և այս հերթը հասանելի էին ընթերցման և գրելու համար։
Ավտոմատ բուժման ռեժիմ
Աշխատում է նման «Անտեսել» ռեժիմին, բացառությամբ այն բանի, որ կլաստերն ինքնին ավտոմատ կերպով ընտրում է պարտվող կողմը բաժանումից և վերամիացումից հետո։ Պարտվող կողմը դատարկ է վերադառնում կլաստեր, և հերթը կորցնում է բոլոր այն հաղորդագրությունները, որոնք ուղարկվել էին միայն այդ կողմին։
Փոքրամասնության ռեժիմի դադարեցում
Եթե մենք չենք ուզում թույլատրել տրամաբանական բաժանում, ապա մեր միակ տարբերակը կլաստերի բաժանումից հետո փոքր մասում կարդալն ու գրելը մերժելն է։ Երբ բրոքերը տեսնում է, որ այն ավելի փոքր է, այն դադարեցնում է գործողությունները, այսինքն՝ փակում է բոլոր առկա կապերը և մերժում նորերը։ Վայրկյան մեկ անգամ ստուգում է կապի վերականգնումը։ Կապը վերականգնվելուց հետո այն վերսկսում է աշխատանքը և միանում է կլաստերին։

Բրինձ։ 22. Երեք հրատարակիչներ կապված են երեք միջնորդների հետ։ Ներքինորեն, կլաստերը բոլոր հարցումները ուղղորդում է Broker 2-ի հիմնական հերթին։
Այնուհետև Բրոքեր 1-ը և 2-ը առանձնանում են Բրոքեր 3-ից։ Հայելին վարպետի վերածելու փոխարեն, Բրոքեր 3-ը կանգ է առնում և դառնում է անհասանելի։

Բրինձ։ 23. Բրոքեր 3-ը դադարեցնում է գործողությունները, անջատում է բոլոր հաճախորդներին և մերժում է միացման հարցումները։
Կապը վերականգնվելուց հետո այն վերադառնում է կլաստեր։
Եկեք դիտարկենք մեկ այլ օրինակ, որտեղ հիմնական հերթը գտնվում է Բրոքեր 3-ի վրա։

Բրինձ։ 24. Բրոքեր 3-ի գլխավոր հերթը։
Այնուհետև տեղի է ունենում նույն համադրության կորուստը։ Բրոքեր 3-ը դադար է տալիս, քանի որ ավելի փոքր է։ Մյուս կողմից, հանգույցները տեսնում են, որ Բրոքեր 3-ը ընկել է, ուստի Բրոքեր 1-ի և 2-ի ավելի հին հայելին բարձրացվում է վարպետի կարգավիճակի։

Բրինձ։ 25. Անցում Բրոքեր 2-ին, երբ Բրոքեր 3-ը հասանելի չէ։
Կապը վերականգնվելուց հետո, Broker 3-ը կմիանա կլաստերին։

Բրինձ։ 26. Կլաստերը վերադարձել է բնականոն աշխատանքի։
Այստեղ կարևորը հասկանալն այն է, որ մենք ստանում ենք հետևողականություն, բայց կարող ենք նաև հասանելիություն ստանալ, եթե Մենք հաջողությամբ կտեղափոխենք հաճախորդներին բաժնի մեծ մասը։ Շատ դեպքերում ես անձամբ կընտրեի «Դադարեցնել փոքրամասնություններին» ռեժիմը, բայց դա իսկապես կախված է կոնկրետ դեպքից։
Հասանելիությունն ապահովելու համար կարևոր է ապահովել, որ հաճախորդները կարողանան հաջողությամբ միանալ հանգույցին։ Եկեք քննարկենք մեր տարբերակները։
Հաճախորդների հետ կապի ապահովում
Մենք ունենք մի քանի տարբերակ, թե ինչպես ուղղորդել հաճախորդներին կլաստերի հիմնական մաս կամ աշխատանքային հանգույցներ (մեկ հանգույցի խափանումից հետո) կապի կորստից հետո։ Նախ, հիշենք, որ որոշակի հերթը տեղակայված է որոշակի հանգույցի վրա, բայց երթուղայնացումը և քաղաքականությունները կրկնօրինակվում են բոլոր հանգույցներում։ Հաճախորդները կարող են միանալ ցանկացած հանգույցի, և ներքին երթուղայնացումը կուղղորդի նրանց այնտեղ, որտեղ նրանք պետք է գնան։ Սակայն, երբ հանգույցը դադարեցված է, այն մերժում է միացումները, ուստի հաճախորդները պետք է միանան մեկ այլ հանգույցի։ Եթե հանգույցը պոկվել է, նա գրեթե ոչինչ չի կարող անել։
Մեր տարբերակները՝
- Կլաստերին մուտքը կատարվում է բեռի հավասարակշռիչի միջոցով, որը պարզապես ցիկլիկորեն անցնում է հանգույցների միջով, և հաճախորդները կրկին փորձում են միանալ մինչև հաջող կապ հաստատելը։ Եթե հանգույցը անջատված է կամ դադարեցված է, այդ հանգույցին միանալու փորձերը կձախողվեն, սակայն հետագա փորձերը կուղղվեն այլ սերվերների (շրջանաձև եղանակով): Սա հարմար է կապի կարճաժամկետ կորստի կամ սերվերի անջատման դեպքում, որը արագ կվերականգնվի։
- Մուտք գործեք կլաստեր բեռի հավասարակշռիչի միջոցով և հեռացրեք դադարեցված/ձախողված հանգույցները ցանկից, հենց որ դրանք հայտնաբերվեն։ Եթե մենք սա արագ անենք, և եթե հաճախորդները կարողանան կրկին փորձել միանալ, ապա մենք կունենանք մշտական հասանելիություն։
- Յուրաքանչյուր հաճախորդին տվեք բոլոր հանգույցների ցանկը, և հաճախորդը միանալիս պատահականորեն կընտրի դրանցից մեկը։ Եթե միանալու փորձի ժամանակ սխալ է առաջանում, այն անցնում է ցուցակի հաջորդ հանգույցին, մինչև միանա։
- Հեռացրեք երթևեկությունը անջատված/դադարեցված հանգույցից՝ օգտագործելով DNS: Սա արվում է փոքր TTL-ի միջոցով։
Արդյունքները
RabbitMQ կլաստերացումը ունի իր առավելություններն ու թերությունները։ Ամենալուրջ թերությունները հետևյալն են.
- Կլաստերին միանալիս հանգույցները մերժում են իրենց տվյալները։
- Սինխրոնիզացիայի արգելափակումը հանգեցնում է հերթի անհասանելիության։
Բոլոր դժվար որոշումները բխում են ճարտարապետության այս երկու առանձնահատկություններից։ Եթե RabbitMQ-ն կարողանար պահպանել տվյալները կլաստերի վերամիացումների ընթացքում, համաժամեցումն ավելի արագ կլիներ։ Եթե այն կարողանար չարգելափակող համաժամեցում, ապա այն ավելի լավ կաջակցեր մեծ հերթերին։ Այս երկու խնդիրների լուծումը զգալիորեն կբարելավի RabbitMQ-ի աշխատանքը որպես խափանումներին դիմացկուն և բարձր մատչելիությամբ հաղորդագրությունների փոխանակման տեխնոլոգիա։ Ես կվարանեի խորհուրդ տալ RabbitMQ-ն կլաստերացման հետ հետևյալ իրավիճակներում.
- Անվստահելի ցանց։
- Անհուսալի պահեստավորում։
- Շատ երկար հերթեր։
Ինչ վերաբերում է բարձր մատչելիության կարգավորումներին, հաշվի առեք հետևյալը.
ha-promote-on-failure=alwaysha-sync-mode=manualcluster_partition_handling=ignore(Կամautoheal)- մշտական հաղորդագրություններ
- համոզվեք, որ հաճախորդները միանում են ակտիվ հանգույցին, երբ հանգույցը անջատվում է
Համապատասխանության (տվյալների անվտանգության) համար հաշվի առեք հետևյալ կարգավորումները.
- Հրատարակչի հաստատումները և սպառողի կողմից ձեռքով հաստատումները
ha-promote-on-failure=when-synced, եթե հրատարակիչները կարողանան փորձել ավելի ուշ, և եթե դուք ունեք շատ հուսալի պահեստային տարածք։ Հակառակ դեպքում, դրեք այն=always.ha-sync-mode=automatic(սակայն մեծ, ոչ ակտիվ հերթերի համար կարող է պահանջվել ձեռքով ռեժիմ. հաշվի առեք նաև, թե արդյոք անհասանելիությունը կհանգեցնի հաղորդագրությունների կորստի):- Փոքրամասնության ռեժիմի դադարեցում
- մշտական հաղորդագրություններ
Մենք դեռ չենք անդրադարձել խափանումների նկատմամբ հանդուրժողականության և բարձր մատչելիության բոլոր հարցերին։ օրինակ՝ ինչպես անվտանգ կերպով կատարել վարչական ընթացակարգեր (օրինակ՝ շարունակական թարմացումներ): Մենք նաև պետք է խոսենք ֆեդերացիայի և Shovel հավելվածի մասին։
Եթե ուրիշ բան բաց եմ թողել, խնդրում եմ տեղյակ պահեք։
Տես նաև իմ , որտեղ ես Docker-ի և Blockade-ի միջոցով քաոս եմ ստեղծում RabbitMQ կլաստերի վրա՝ այս հոդվածում նկարագրված հաղորդագրությունների կորստի որոշ սցենարներ փորձարկելու համար։
Նախորդ հոդվածները շարքում.
Թիվ 1 -
Թիվ 2 -
Թիվ 3 -
Source: www.habr.com
