RabbitMQ vs Kafka. սխալների հանդուրժողականություն և բարձր հասանելիություն կլաստերներում

RabbitMQ vs Kafka. սխալների հանդուրժողականություն և բարձր հասանելիություն կլաստերներում

Սխալների հանդուրժողականությունը և բարձր հասանելիությունը մեծ թեմաներ են, ուստի մենք առանձին հոդվածներ կնվիրենք RabbitMQ-ին և Kafka-ին: Այս հոդվածը RabbitMQ-ի մասին է, իսկ հաջորդը Կաֆկայի մասին է՝ համեմատած RabbitMQ-ի հետ։ Սա երկար հոդված է, այնպես որ ձեզ հարմարավետ դարձրեք:

Եկեք նայենք սխալների հանդուրժողականության, հետևողականության և բարձր հասանելիության (HA) ռազմավարություններին և փոխզիջումներին, որոնք ստեղծում է յուրաքանչյուր ռազմավարություն: RabbitMQ-ն կարող է աշխատել հանգույցների կլաստերի վրա, և այնուհետև դասակարգվում է որպես բաշխված համակարգ: Երբ խոսքը վերաբերում է բաշխված համակարգերին, մենք հաճախ խոսում ենք հետևողականության և հասանելիության մասին:

Այս հասկացությունները նկարագրում են, թե ինչպես է համակարգը իրեն պահում, երբ այն ձախողվում է: Ցանցային կապի ձախողում, սերվերի ձախողում, կոշտ սկավառակի ձախողում, սերվերի ժամանակավոր անհասանելիություն՝ աղբահանության, փաթեթների կորստի կամ ցանցային կապի դանդաղման պատճառով: Այս ամենը կարող է հանգեցնել տվյալների կորստի կամ կոնֆլիկտների: Պարզվում է, որ գործնականում անհնար է ստեղծել այնպիսի համակարգ, որը և՛ լիովին համահունչ է (տվյալների կորուստ, ոչ տվյալների տարաձայնություններ), և՛ հասանելի (կընդունի կարդալ և գրել) բոլոր ձախողման սցենարների համար:

Մենք կտեսնենք, որ հետևողականությունը և հասանելիությունը գտնվում են սպեկտրի հակառակ ծայրերում, և դուք պետք է ընտրեք, թե որ ճանապարհն է օպտիմալացնելու: Լավ նորությունն այն է, որ RabbitMQ-ի հետ այս ընտրությունը հնարավոր է: Դուք ունեք այսպիսի «խղճուկ» լծակներ՝ հավասարակշռությունը դեպի ավելի մեծ հետևողականություն կամ ավելի մատչելիություն փոխելու համար:

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

Single Node Resilience Primitives

Ճկուն հերթեր / երթուղի

RabbitMQ-ում կան երկու տեսակի հերթեր՝ դիմացկուն և ոչ դիմացկուն: Բոլոր հերթերը պահվում են Mnesia տվյալների բազայում: Երկարատև հերթերը նորից գովազդվում են հանգույցի գործարկման ժամանակ և այդպիսով գոյատևում են վերագործարկումից, համակարգի խափանումներից կամ սերվերի խափանումներից (քանի դեռ տվյալները պահպանվում են): Սա նշանակում է, որ քանի դեռ դուք հայտարարում եք երթուղիների (փոխանակման) և հերթի ճկունության մասին, հերթերի/երթուղային ենթակառուցվածքը կվերադառնա առցանց:

Անկայուն հերթերը և երթուղավորումը հանվում են, երբ հանգույցը վերագործարկվում է:

Մշտական ​​հաղորդագրություններ

Պարզապես այն պատճառով, որ հերթը երկարակյաց է, չի նշանակում, որ դրա բոլոր հաղորդագրությունները գոյատևելու են հանգույցի վերագործարկումից հետո: Միայն հրատարակչի կողմից սահմանված հաղորդագրությունները որպես կայուն (համառ): Մշտական ​​հաղորդագրությունները իսկապես լրացուցիչ բեռ են ստեղծում բրոքերի վրա, բայց եթե հաղորդագրության կորուստն անընդունելի է, ապա այլ տարբերակ չկա:

RabbitMQ vs Kafka. սխալների հանդուրժողականություն և բարձր հասանելիություն կլաստերներում
Բրինձ. 1. Կայունության մատրիցա

Կլաստերավորում՝ հերթերի հայելապատմամբ

Բրոքերի կորստից գոյատևելու համար մեզ ավելորդություն է պետք: Մենք կարող ենք մի քանի RabbitMQ հանգույցներ միավորել կլաստերի մեջ, այնուհետև ավելացնել հավելյալ ավելորդություն՝ բազմակի հանգույցների միջև հերթեր կրկնելով։ Այս կերպ, եթե մեկ հանգույց ձախողվի, մենք չենք կորցնում տվյալները և մնում ենք հասանելի:

Հերթի հայելավորում.

  • մեկ հիմնական հերթ (master), որը ստանում է գրելու և կարդալու բոլոր հրամանները
  • մեկ կամ մի քանի հայելիներ, որոնք ստանում են բոլոր հաղորդագրությունները և մետատվյալները հիմնական հերթից: Այս հայելիները նախատեսված են ոչ թե չափման, այլ զուտ ավելորդության համար:

RabbitMQ vs Kafka. սխալների հանդուրժողականություն և բարձր հասանելիություն կլաստերներում
Բրինձ. 2. Հերթի հայելավորում

Mirroring-ը սահմանվում է համապատասխան քաղաքականությամբ: Դրանում դուք կարող եք ընտրել կրկնօրինակման գործակիցը և նույնիսկ այն հանգույցները, որոնց վրա պետք է տեղադրվի հերթը: Օրինակներ.

  • ha-mode: all
  • ha-mode: exactly, ha-params: 2 (մեկ վարպետ և մեկ հայելի)
  • ha-mode: nodes, ha-params: rabbit@node1, rabbit@node2

Հրատարակչի հաստատում

Հետևողական ձայնագրման հասնելու համար պահանջվում է Publisher Confirms: Առանց դրանց, հաղորդագրությունների կորստի վտանգ կա: Հաղորդագրությունը սկավառակի վրա գրվելուց հետո հաստատում է ուղարկվում հրատարակչին: RabbitMQ-ն սկավառակի վրա հաղորդագրություններ է գրում ոչ թե ստանալուց հետո, այլ պարբերական հիմունքներով՝ մի քանի հարյուր միլիվայրկյանների շրջանում: Երբ հերթը արտացոլվում է, հաստատումը ուղարկվում է միայն այն բանից հետո, երբ բոլոր հայելիները նույնպես գրեն հաղորդագրության իրենց պատճենը սկավառակի վրա: Սա նշանակում է, որ հաստատումների օգտագործումը ավելացնում է ուշացում, բայց եթե տվյալների անվտանգությունը կարևոր է, ապա դրանք անհրաժեշտ են:

Failover հերթ

Երբ բրոքերը հեռանում է կամ վթարի է ենթարկվում, այդ հանգույցի բոլոր հերթերի առաջատարները (վարպետները) վթարի են ենթարկվում դրա հետ մեկտեղ: Այնուհետև կլաստերն ընտրում է յուրաքանչյուր վարպետի ամենահին հայելին և այն ներկայացնում որպես նոր վարպետ:

RabbitMQ vs Kafka. սխալների հանդուրժողականություն և բարձր հասանելիություն կլաստերներում
Բրինձ. 3. Բազմաթիվ հայելային հերթեր և դրանց քաղաքականությունը

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

RabbitMQ vs Kafka. սխալների հանդուրժողականություն և բարձր հասանելիություն կլաստերներում
Բրինձ. 4. Բրոքեր 3-ը ձախողվում է, ինչը հանգեցնում է C հերթի ձախողմանը

Հաջորդ Բրոքեր 1-ն ընկնում է: Մեզ մնացել է ընդամենը մեկ բրոքեր։ The Queue B հայելին նպաստվում է վարպետության:

RabbitMQ vs Kafka. սխալների հանդուրժողականություն և բարձր հասանելիություն կլաստերներում
Բրինձ. 5

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

Այս դեպքում Broker 1-ի կորուստը ամբողջական էր, ինչպես և տվյալները, այնպես որ չհայելված B հերթն ամբողջությամբ կորավ:

RabbitMQ vs Kafka. սխալների հանդուրժողականություն և բարձր հասանելիություն կլաստերներում
Բրինձ. 6. Բրոքեր 1-ը վերադառնում է ծառայության

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

RabbitMQ vs Kafka. սխալների հանդուրժողականություն և բարձր հասանելիություն կլաստերներում
Բրինձ. 7. Բրոքեր 3-ը վերադառնում է ծառայության: Բոլոր հիմնական հերթերը մեկ հանգույցում:

Այսպիսով, այժմ դուք պետք է պատկերացնեք, թե ինչպես են հայելիներն ապահովում ավելորդության և սխալների հանդուրժողականություն: Սա ապահովում է հասանելիությունը մեկ հանգույցի ձախողման դեպքում և պաշտպանում է տվյալների կորստից: Բայց մենք դեռ չենք ավարտել, քանի որ իրականում դա շատ ավելի բարդ է։

Համաժամեցում

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

Այս համաժամացումը կատարվում է ավտոմատ կամ ձեռքով և կառավարվում է հերթերի քաղաքականության միջոցով: Դիտարկենք մի օրինակ։

Մենք ունենք երկու հայելային հերթ։ Հերթը A-ն ավտոմատ կերպով համաժամացվում է, իսկ հերթը B-ն՝ ձեռքով: Երկու հերթերն էլ պարունակում են տասը հաղորդագրություն:

RabbitMQ vs Kafka. սխալների հանդուրժողականություն և բարձր հասանելիություն կլաստերներում
Բրինձ. 8. Երկու հերթ՝ տարբեր համաժամացման ռեժիմներով

Այժմ մենք կորցնում ենք Բրոքեր 3-ը:

RabbitMQ vs Kafka. սխալների հանդուրժողականություն և բարձր հասանելիություն կլաստերներում
Բրինձ. 9. Բրոքեր 3-ն ընկավ

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

RabbitMQ vs Kafka. սխալների հանդուրժողականություն և բարձր հասանելիություն կլաստերներում
Բրինձ. 10. Հերթի A-ի նոր հայելին ստանում է բոլոր առկա հաղորդագրությունները, իսկ B-ի նոր հայելին՝ ոչ:

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

RabbitMQ vs Kafka. սխալների հանդուրժողականություն և բարձր հասանելիություն կլաստերներում
Բրինձ. 11. A հերթը վերադառնում է Բրոքեր 1 առանց հաղորդագրությունների կորստի

Երկու հերթերում էլ տասը հաղորդագրություն է գալիս: Այժմ Broker 1-ը խափանում է: Հերթ A-ն հեշտությամբ անցնում է հայելուն՝ չկորցնելով հաղորդագրությունները: Այնուամենայնիվ, հերթ B-ն խնդիրներ ունի: Այս պահին մենք կարող ենք օպտիմալացնել կա՛մ հասանելիությունը, կա՛մ հետևողականությունը:

Եթե ​​մենք ցանկանում ենք օպտիմալացնել հասանելիությունը, ապա քաղաքականությունը ha-promote-on-failure պետք է տեղադրվի միշտ. Սա լռելյայն արժեքն է, այնպես որ դուք պարզապես կարող եք ընդհանրապես չնշել քաղաքականությունը: Այս դեպքում մենք, ըստ էության, թույլ ենք տալիս ձախողումներ չհամաժամեցված հայելիներում: Սա կհանգեցնի հաղորդագրությունների կորստի, բայց հերթը կմնա ընթեռնելի և գրելու համար:

RabbitMQ vs Kafka. սխալների հանդուրժողականություն և բարձր հասանելիություն կլաստերներում
Բրինձ. 12. A հերթը վերադարձվում է Բրոքեր 3՝ առանց հաղորդագրությունների կորստի: Հերթը B-ն վերադառնում է Բրոքեր 3՝ տասը հաղորդագրություն կորած

Կարող ենք նաև տեղադրել ha-promote-on-failure իմաստի մեջ when-synced. Այս դեպքում, հայելու մոտ վերադառնալու փոխարեն, հերթը կսպասի մինչև Բրոքեր 1-ն իր տվյալներով վերադառնա առցանց ռեժիմ: Վերադառնալուց հետո հիմնական հերթը վերադառնում է Բրոքեր 1-ին՝ առանց տվյալների կորստի: Հասանելիությունը զոհաբերվում է տվյալների անվտանգության համար: Բայց սա ռիսկային ռեժիմ է, որը կարող է նույնիսկ հանգեցնել տվյալների ամբողջական կորստի, որը մենք շուտով կանդրադառնանք:

RabbitMQ vs Kafka. սխալների հանդուրժողականություն և բարձր հասանելիություն կլաստերներում
Բրինձ. 13. Բրոքեր 1-ը կորցնելուց հետո B հերթը մնում է անհասանելի

Դուք կարող եք հարցնել. «Ավելի լավ է երբեք չօգտագործել ավտոմատ համաժամացումը»: Պատասխանն այն է, որ համաժամացումը արգելափակող գործողություն է: Համաժամացման ընթացքում հիմնական հերթը չի կարող կարդալ կամ գրել որևէ գործողություն:

Դիտարկենք մի օրինակ։ Հիմա շատ երկար հերթեր ունենք։ Ինչպե՞ս կարող են դրանք մեծանալ նման չափի: Մի քանի պատճառներով.

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

RabbitMQ vs Kafka. սխալների հանդուրժողականություն և բարձր հասանելիություն կլաստերներում
Բրինձ. 14. Երկու մեծ հերթեր՝ տարբեր համաժամացման ռեժիմներով

Այժմ Բրոքեր 3-ն ընկնում է:

RabbitMQ vs Kafka. սխալների հանդուրժողականություն և բարձր հասանելիություն կլաստերներում
Բրինձ. 15. Բրոքեր 3-ն ընկնում է՝ յուրաքանչյուր հերթում թողնելով մեկ վարպետ և հայելի

Broker 3-ը վերադառնում է առցանց և ստեղծվում են նոր հայելիներ: Հիմնական հերթը A-ն սկսում է գոյություն ունեցող հաղորդագրությունների կրկնօրինակումը նոր հայելու մեջ, և այս ընթացքում հերթը անհասանելի է: Տվյալների կրկնօրինակման համար տևում է երկու ժամ, ինչը հանգեցնում է այս հերթի երկու ժամ անգործության:

Այնուամենայնիվ, հերթը B մնում է հասանելի ողջ ժամանակահատվածում: Նա զոհաբերեց որոշ ավելորդություն մատչելիության համար:

RabbitMQ vs Kafka. սխալների հանդուրժողականություն և բարձր հասանելիություն կլաստերներում
Բրինձ. 16. Համաժամացման ընթացքում հերթը մնում է անհասանելի

Երկու ժամ հետո Հերթ A-ը նույնպես հասանելի է դառնում և կարող է նորից սկսել կարդալ և գրել:

Updates

Այս արգելափակման վարքագիծը համաժամացման ընթացքում դժվարացնում է շատ մեծ հերթերով կլաստերների թարմացումը: Ինչ-որ պահի, հիմնական հանգույցը պետք է վերագործարկվի, ինչը նշանակում է կամ անցնել հայելու կամ անջատել հերթը, երբ սերվերը թարմացվում է: Եթե ​​մենք ընտրենք անցում կատարել, մենք կկորցնենք հաղորդագրությունները, եթե հայելիները համաժամանակացված չեն: Լռելյայնորեն, բրոքերային անջատման ժամանակ, ձախողում դեպի չհամաժամանակացված հայելին չի կատարվում: Սա նշանակում է, որ հենց բրոքերը վերադառնում է, մենք ոչ մի հաղորդագրություն չենք կորցնում, միակ վնասը պարզ հերթն էր։ Վարքագծի կանոնները, երբ բրոքերն անջատված է, սահմանվում են քաղաքականությամբ ha-promote-on-shutdown. Դուք կարող եք սահմանել երկու արժեքներից մեկը.

  • always= անցումը չհամաժամեցված հայելիներին միացված է
  • when-synced= անցում միայն սինխրոն հայելու, հակառակ դեպքում հերթը դառնում է անընթեռնելի և անգրելի: Հերթը վերադառնում է ծառայության հենց բրոքերը վերադառնում է

Այսպես թե այնպես, մեծ հերթերի դեպքում պետք է ընտրություն կատարել տվյալների կորստի և անհասանելիության միջև:

Երբ հասանելիությունը բարելավում է տվյալների անվտանգությունը

Որոշում կայացնելուց առաջ պետք է հաշվի առնել ևս մեկ բարդություն. Թեև ավտոմատ համաժամացումը ավելի լավ է ավելորդության համար, ինչպե՞ս է դա ազդում տվյալների անվտանգության վրա: Իհարկե, ավելի լավ ավելորդության դեպքում RabbitMQ-ն ավելի քիչ հավանական է կորցնի առկա հաղորդագրությունները, բայց ի՞նչ կասեք հրատարակիչների նոր հաղորդագրությունների մասին:

Այստեղ դուք պետք է հաշվի առնեք հետևյալը.

  • Կարո՞ղ է հրատարակիչը պարզապես սխալ վերադարձնել և թույլ տալ, որ վերին հոսքի ծառայությունը կամ օգտվողը նորից փորձի ավելի ուշ:
  • Կարո՞ղ է հրատարակիչը պահել հաղորդագրությունը տեղական կամ տվյալների բազայում՝ ավելի ուշ նորից փորձելու համար:

Եթե ​​հրատարակիչը կարող է միայն հրաժարվել հաղորդագրությունից, ապա իրականում մատչելիության բարելավումը նաև բարելավում է տվյալների անվտանգությունը:

Այսպիսով, պետք է հավասարակշռություն փնտրել, իսկ լուծումը կախված է կոնկրետ իրավիճակից։

Խնդիրներ ha-promote-on-failure=when-synced-ի հետ

Գաղափար ha-promote-on-failure= երբ-համաժամեցված այն է, որ մենք կանխում ենք անցումը չհամաժամանակացված հայելուն և դրանով իսկ խուսափում ենք տվյալների կորստից: Հերթը մնում է անընթեռնելի կամ գրավոր: Փոխարենը, մենք փորձում ենք վերականգնել վթարի ենթարկված բրոքերը՝ իր անձեռնմխելի տվյալներով, որպեսզի այն կարողանա վերսկսել աշխատել որպես վարպետ՝ առանց տվյալների կորստի:

Բայց (և սա մեծ, բայց) եթե բրոքերը կորցրել է իր տվյալները, ապա մենք մեծ խնդիր ունենք. հերթը կորել է: Բոլոր տվյալները անհետացել են: Նույնիսկ եթե դուք ունեք հայելիներ, որոնք հիմնականում հասնում են հիմնական հերթին, այդ հայելիները նույնպես դեն են նետվում:

Նույն անունով հանգույց նորից ավելացնելու համար մենք կլաստերին ասում ենք, որ մոռանա կորցրած հանգույցը (հրամանով rabbitmqctl forget_cluster_node) և բացեք նոր բրոքեր նույն հյուրընկալողի անունով: Մինչ կլաստերը հիշում է կորցրած հանգույցը, այն հիշում է հին հերթը և չհամաժամեցված հայելիները: Երբ կլաստերին ասում են, որ մոռանա որբացած հանգույցը, այդ հերթը նույնպես մոռացվում է: Այժմ մենք պետք է նորից հայտարարենք: Մենք կորցրեցինք բոլոր տվյալները, թեև ունեինք տվյալների մասնակի հավաքածուով հայելիներ: Ավելի լավ կլինի անցնել ոչ սինխրոն հայելու:

Հետևաբար, ձեռքով համաժամացումը (և համաժամացման ձախողումը) հետ համատեղ ha-promote-on-failure=when-synced, իմ կարծիքով՝ բավականին ռիսկային։ Փաստաթղթերն ասում են, որ այս տարբերակը գոյություն ունի տվյալների անվտանգության համար, բայց դա երկսայրի դանակ է:

Master rebalancing

Ինչպես խոստացել էինք, մենք վերադառնում ենք մեկ կամ մի քանի հանգույցների վրա բոլոր վարպետների կուտակման խնդրին: Դա կարող է տեղի ունենալ նույնիսկ շարժվող կլաստերի թարմացման արդյունքում: Երեք հանգույցներից բաղկացած կլաստերում բոլոր հիմնական հերթերը կկուտակվեն մեկ կամ երկու հանգույցների վրա:

Վերահավասարակշռման վարպետները կարող են խնդրահարույց լինել երկու պատճառով.

  • Վերահավասարակշռում կատարելու լավ գործիքներ չկան
  • Հերթի համաժամացում

Վերահավասարակշռման համար կա երրորդ կողմ plug-in- ը, որը պաշտոնապես չի աջակցվում։ RabbitMQ ձեռնարկի երրորդ կողմի հավելումների վերաբերյալ ասվում է«Փլագինը տրամադրում է որոշ լրացուցիչ կազմաձևման և հաշվետվությունների գործիքներ, բայց չի աջակցվում կամ հաստատված RabbitMQ թիմի կողմից: Օգտագործեք ձեր ռիսկով»:

Գոյություն ունի մեկ այլ հնարք՝ հիմնական հերթը HA-ի քաղաքականության միջոցով տեղափոխելու համար: Ձեռնարկը նշում է սցենար սրա համար. Այն աշխատում է այսպես.

  • Հեռացնում է բոլոր հայելիները՝ օգտագործելով ժամանակավոր քաղաքականությունը, որն ավելի բարձր առաջնահերթություն ունի, քան առկա HA քաղաքականությունը:
  • Փոխում է HA-ի ժամանակավոր քաղաքականությունը՝ օգտագործելու հանգույցի ռեժիմը՝ նշելով այն հանգույցը, որին պետք է փոխանցվի հիմնական հերթը:
  • Համաժամացնում է հրում միգրացիայի հերթը:
  • Միգրացիայի ավարտից հետո ժամանակավոր քաղաքականությունը ջնջվում է: Նախնական HA քաղաքականությունը ուժի մեջ է մտնում, և անհրաժեշտ թվով հայելիներ են ստեղծվում:

Բացասական կողմն այն է, որ այս մոտեցումը կարող է չաշխատել, եթե ունեք մեծ հերթեր կամ կրճատման խիստ պահանջներ:

Այժմ տեսնենք, թե ինչպես են RabbitMQ կլաստերները աշխատում ցանցային միջնորմների հետ:

Կապի կորուստ

Բաշխված համակարգի հանգույցները միացված են ցանցային կապերով, և ցանցային կապերը կարող են և կանջատվեն: Անջատումների հաճախականությունը կախված է տեղական ենթակառուցվածքից կամ ընտրված ամպի հուսալիությունից: Ամեն դեպքում, բաշխված համակարգերը պետք է կարողանան հաղթահարել դրանք: Կրկին մենք ընտրություն ունենք մատչելիության և հետևողականության միջև, և կրկին լավ նորությունն այն է, որ RabbitMQ-ն տրամադրում է երկու տարբերակները (միայն ոչ միաժամանակ):

RabbitMQ-ի հետ մենք ունենք երկու հիմնական տարբերակ.

  • Թույլատրել տրամաբանական բաժանումը (բաժանված ուղեղ): Սա ապահովում է հասանելիությունը, բայց կարող է հանգեցնել տվյալների կորստի:
  • Անջատել տրամաբանական տարանջատումը: Կարող է հանգեցնել մատչելիության կարճաժամկետ կորստի՝ կախված նրանից, թե ինչպես են հաճախորդները միանում կլաստերին: Կարող է նաև հանգեցնել երկու հանգույցների կլաստերի ամբողջական անհասանելիության:

Բայց ի՞նչ է տրամաբանական բաժանումը։ Սա այն դեպքում, երբ կլաստերը բաժանվում է երկու մասի ցանցային կապերի կորստի պատճառով: Յուրաքանչյուր կողմում հայելիները վերածվում են վարպետի, այնպես որ, ի վերջո, կան մի քանի վարպետներ յուրաքանչյուր հերթափոխում:

RabbitMQ vs Kafka. սխալների հանդուրժողականություն և բարձր հասանելիություն կլաստերներում
Բրինձ. 17. Հիմնական հերթ և երկու հայելի, յուրաքանչյուրը առանձին հանգույցի վրա: Հետո ցանցի խափանում է տեղի ունենում, և մեկ հայելին անջատվում է: Առանձնացված հանգույցը տեսնում է, որ մյուս երկուսը ընկել են և իր հայելիները բարձրացնում է վարպետին: Այժմ մենք ունենք երկու հիմնական հերթ՝ և՛ գրավոր, և՛ ընթեռնելի:

Եթե ​​հրատարակիչները տվյալներ են ուղարկում երկու վարպետներին, մենք վերջում ունենում ենք հերթի երկու տարբեր օրինակներ:

RabbitMQ-ի տարբեր ռեժիմներն ապահովում են կա՛մ հասանելիություն, կա՛մ հետևողականություն:

Անտեսման ռեժիմ (կանխադրված)

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

RabbitMQ vs Kafka. սխալների հանդուրժողականություն և բարձր հասանելիություն կլաստերներում
Բրինձ. 18. Երեք հրատարակիչ ասոցացվում է երեք բրոքերների հետ։ Ներքին մասում կլաստերը ուղղորդում է բոլոր հարցումները Բրոքեր 2-ի հիմնական հերթին:

Հիմա մենք կորցնում ենք Բրոքեր 3-ը: Նա տեսնում է, որ այլ բրոքերներ են ընկել և իր հայելին առաջ է քաշում վարպետի մոտ: Ահա թե ինչպես է տեղի ունենում տրամաբանական բաժանումը.

RabbitMQ vs Kafka. սխալների հանդուրժողականություն և բարձր հասանելիություն կլաստերներում
Բրինձ. 19. Տրամաբանական բաժանում (սպլիտ-ուղեղ). Գրառումները գնում են երկու հիմնական հերթերի, և երկու օրինակները տարբերվում են:

Կապը վերականգնված է, բայց տրամաբանական տարանջատումը մնում է: Ադմինիստրատորը պետք է ձեռքով ընտրի պարտվող կողմը: Ստորև բերված դեպքում ադմինիստրատորը վերագործարկում է Broker 3-ը: Բոլոր հաղորդագրությունները, որոնք նա չի հասցրել փոխանցել, կորչում են:

RabbitMQ vs Kafka. սխալների հանդուրժողականություն և բարձր հասանելիություն կլաստերներում
Բրինձ. 20. Ադմինիստրատորն անջատում է Բրոքեր 3-ը:

RabbitMQ vs Kafka. սխալների հանդուրժողականություն և բարձր հասանելիություն կլաստերներում
Բրինձ. 21. Ադմինիստրատորը սկսում է Broker 3-ը և այն միանում է կլաստերին՝ կորցնելով այնտեղ մնացած բոլոր հաղորդագրությունները:

Կապի կորստի ժամանակ և դրա վերականգնումից հետո կլաստերը և այս հերթը հասանելի էին կարդալու և գրելու համար:

Ավտոբուժման ռեժիմ

Աշխատում է նույն կերպ, ինչ «Անտեսել» ռեժիմը, այն տարբերությամբ, որ կլաստերն ինքնին ավտոմատ կերպով ընտրում է պարտվող կողմը՝ կապը բաժանելուց և վերականգնելուց հետո: Պարտվող կողմը վերադառնում է դատարկ կլաստեր, իսկ հերթը կորցնում է բոլոր հաղորդագրությունները, որոնք ուղարկվել են միայն այդ կողմին:

Դադարեցնել փոքրամասնության ռեժիմը

Եթե ​​մենք չենք ցանկանում թույլատրել տրամաբանական բաժանումը, ապա մեր միակ տարբերակը կլաստերային բաժանումից հետո փոքր կողմում կարդալն ու գրելը հեռացնելն է: Երբ բրոքերը տեսնում է, որ այն գտնվում է ավելի փոքր կողմում, դադարեցնում է աշխատանքը, այսինքն՝ փակում է առկա բոլոր կապերը և հրաժարվում նորերից։ Վայրկյանում մեկ անգամ այն ​​ստուգում է կապի վերականգնումը: Կապը վերականգնվելուց հետո այն վերսկսում է աշխատանքը և միանում կլաստերին:

RabbitMQ vs Kafka. սխալների հանդուրժողականություն և բարձր հասանելիություն կլաստերներում
Բրինձ. 22. Երեք հրատարակիչ ասոցացվում է երեք բրոքերների հետ։ Ներքին մասում կլաստերը ուղղորդում է բոլոր հարցումները Բրոքեր 2-ի հիմնական հերթին:

Այնուհետև 1-ին և 2-րդ բրոքերները բաժանվում են Բրոքեր 3-ից: Իրենց հայելին տիրանալու փոխարեն, Բրոքեր 3-ը կասեցնում է և դառնում անհասանելի:

RabbitMQ vs Kafka. սխալների հանդուրժողականություն և բարձր հասանելիություն կլաստերներում
Բրինձ. 23. Բրոքեր 3-ը դադարեցնում է, անջատում է բոլոր հաճախորդներին և մերժում միացման հարցումները:

Կապը վերականգնվելուց հետո այն վերադառնում է կլաստեր:

Դիտարկենք մեկ այլ օրինակ, որտեղ հիմնական հերթը գտնվում է Broker 3-ում:

RabbitMQ vs Kafka. սխալների հանդուրժողականություն և բարձր հասանելիություն կլաստերներում
Բրինձ. 24. Հիմնական հերթ Բրոքեր 3-ում:

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

RabbitMQ vs Kafka. սխալների հանդուրժողականություն և բարձր հասանելիություն կլաստերներում
Բրինձ. 25. Անցում Բրոքեր 2-ին, եթե Բրոքեր 3-ը անհասանելի է:

Երբ կապը վերականգնվի, Բրոքեր 3-ը կմիանա կլաստերին:

RabbitMQ vs Kafka. սխալների հանդուրժողականություն և բարձր հասանելիություն կլաստերներում
Բրինձ. 26. Կլաստերը վերադարձել է բնականոն աշխատանքի:

Այստեղ հասկանալու կարևորն այն է, որ մենք հետևողականություն ենք ստանում, բայց կարող ենք նաև հասանելիություն ստանալ, եթե Մենք հաջողությամբ կփոխանցենք հաճախորդներին բաժինների մեծ մաս: Շատ իրավիճակների համար ես անձամբ կընտրեի Pause Minority ռեժիմը, բայց դա իսկապես կախված է անհատական ​​դեպքից:

Հասանելիությունն ապահովելու համար կարևոր է ապահովել, որ հաճախորդները հաջողությամբ միանան հոսթին: Եկեք նայենք մեր տարբերակներին:

Հաճախորդների կապի ապահովում

Մենք ունենք մի քանի տարբերակ, թե ինչպես հաճախորդներին ուղղորդել դեպի կլաստերի հիմնական մասը կամ դեպի աշխատանքային հանգույցներ (մեկ հանգույցի ձախողումից հետո) կապի կորստից հետո: Նախ, եկեք հիշենք, որ որոշակի հերթ տեղադրվում է կոնկրետ հանգույցի վրա, բայց երթուղիներն ու քաղաքականությունները կրկնօրինակվում են բոլոր հանգույցներում: Հաճախորդները կարող են միանալ ցանկացած հանգույցի, և ներքին երթուղիչը նրանց կուղղորդի այնտեղ, ուր նրանք պետք է գնան: Բայց երբ հանգույցը կասեցվում է, այն մերժում է կապերը, ուստի հաճախորդները պետք է միանան մեկ այլ հանգույցի: Եթե ​​հանգույցը ընկնում է, նա ընդհանրապես քիչ բան կարող է անել:

Մեր տարբերակները.

  • Կլաստերը հասանելի է բեռի հավասարակշռման միջոցով, որը պարզապես շրջում է հանգույցների միջով, և հաճախորդները նորից փորձում են միանալ մինչև հաջողության հասնելը: Եթե ​​հանգույցն անջատված է կամ կասեցված է, ապա այդ հանգույցին միանալու փորձերը կձախողվեն, բայց հետագա փորձերը կգնան այլ սերվերներ (կլոր ռոբին եղանակով): Սա հարմար է կապի կարճաժամկետ կորստի կամ խափանված սերվերի համար, որը արագ կվերականգնվի:
  • Մուտք գործեք կլաստերը ծանրաբեռնվածության հավասարակշռիչի միջոցով և ցանկից հանեք կասեցված/ձախողված հանգույցները, հենց որ դրանք հայտնաբերվեն: Եթե ​​մենք դա անենք արագ, և եթե հաճախորդները կարողանան նորից փորձել կապը, ապա մենք կհասնենք մշտական ​​հասանելիության:
  • Յուրաքանչյուր հաճախորդին տվեք բոլոր հանգույցների ցուցակը, և հաճախորդը միանալու ժամանակ պատահականորեն ընտրում է դրանցից մեկը: Եթե ​​այն սխալ է ստանում միանալու փորձի ժամանակ, այն տեղափոխվում է ցուցակի հաջորդ հանգույց, մինչև միանա:
  • Հեռացրեք տրաֆիկը ձախողված/կասեցված հանգույցից՝ օգտագործելով DNS: Սա արվում է օգտագործելով փոքր TTL:

Արդյունքները

RabbitMQ կլաստերավորումն ունի իր առավելություններն ու թերությունները: Ամենալուրջ թերությունները հետևյալն են.

  • կլաստերին միանալիս հանգույցները հեռացնում են իրենց տվյալները.
  • արգելափակման համաժամացումը հանգեցնում է նրան, որ հերթը դառնում է անհասանելի:

Բոլոր դժվար որոշումները բխում են այս երկու ճարտարապետական ​​առանձնահատկություններից: Եթե ​​RabbitMQ-ն կարողանար պահպանել տվյալները, երբ կլաստերը նորից միանա, ապա համաժամացումը ավելի արագ կլիներ: Եթե ​​այն կարողանար չարգելափակել համաժամացման, ապա ավելի լավ կլիներ մեծ հերթերի աջակցություն: Այս երկու խնդիրների շտկումը զգալիորեն կբարելավի RabbitMQ-ի աշխատանքը՝ որպես անսարքությունների հանդուրժող և բարձր հասանելի հաղորդագրությունների տեխնոլոգիա: Ես կհապաղեմ խորհուրդ տալ RabbitMQ-ին կլաստերավորումով հետևյալ իրավիճակներում.

  • Անվստահելի ցանց.
  • Անվստահելի պահեստավորում:
  • Շատ երկար հերթեր.

Երբ խոսքը վերաբերում է բարձր հասանելիության պարամետրերին, հաշվի առեք հետևյալը.

  • ha-promote-on-failure=always
  • ha-sync-mode=manual
  • cluster_partition_handling=ignore (Կամ autoheal)
  • համառ հաղորդագրություններ
  • ապահովել, որ հաճախորդները միանան ակտիվ հանգույցին, երբ որոշ հանգույց ձախողվի

Հետևողականության (տվյալների անվտանգության) համար հաշվի առեք հետևյալ պարամետրերը.

  • Հրատարակիչը հաստատում է և ձեռքով հաստատում սպառողի կողմից
  • ha-promote-on-failure=when-synced, եթե հրատարակիչները կարողանան ավելի ուշ նորից փորձել, և եթե դուք ունեք շատ հուսալի պահեստ: Հակառակ դեպքում դրեք =always.
  • ha-sync-mode=automatic (սակայն մեծ անգործուն հերթերի համար կարող է պահանջվել ձեռքով ռեժիմ, նաև հաշվի առեք, թե արդյոք անհասանելիությունը կհանգեցնի հաղորդագրությունների կորստի)
  • Դադարեցնել փոքրամասնության ռեժիմը
  • համառ հաղորդագրություններ

Մենք դեռ չենք անդրադարձել սխալների հանդուրժողականության և բարձր հասանելիության բոլոր հարցերին. օրինակ՝ ինչպես ապահով կերպով կատարել վարչական ընթացակարգերը (օրինակ՝ շարժական թարմացումները): Մենք պետք է խոսենք նաև ֆեդերացիայի և «Shovel» հավելվածի մասին:

Եթե ​​ես որևէ այլ բան բաց եմ թողել, խնդրում եմ ինձ տեղյակ պահեք:

Տես նաև իմ գրառում, որտեղ ես կործանում եմ RabbitMQ կլաստերի վրա՝ օգտագործելով Docker և Blockade՝ այս հոդվածում նկարագրված հաղորդագրությունների կորստի որոշ սցենարներ փորձարկելու համար:

Շարքի նախորդ հոդվածները.
Թիվ 1 - habr.com/ru/company/itsumma/blog/416629
Թիվ 2 - habr.com/ru/company/itsumma/blog/418389
Թիվ 3 - habr.com/ru/company/itsumma/blog/437446

Source: www.habr.com

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