Tarantool Քարտրիջ. Lua հետնամասի բեկում երեք տողով

Tarantool Քարտրիջ. Lua հետնամասի բեկում երեք տողով

Mail.ru Group-ում մենք ունենք Tarantool. սա հավելված սերվեր է Lua-ում, որը նաև կրկնապատկվում է որպես տվյալների բազա (կամ հակառակը): Այն արագ և զով է, բայց մեկ սերվերի հնարավորությունները դեռևս անսահմանափակ չեն: Ուղղահայաց մասշտաբը նույնպես համադարման չէ, ուստի Tarantool-ն ունի գործիքներ հորիզոնական մասշտաբավորման համար՝ vshard մոդուլը [1]. Այն թույլ է տալիս կիսել տվյալները մի քանի սերվերների վրա, բայց դուք պետք է շտկեք դրանց հետ՝ դրանք կարգավորելու և բիզնես տրամաբանությունը կցելու համար:

Լավ նորություն. մենք հավաքել ենք մի քանի մեծ կադրեր (օրինակ [2], [3]) և ստեղծել մեկ այլ շրջանակ, որը զգալիորեն կպարզեցնի այս խնդրի լուծումը:

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

Կոնկրետ ո՞րն է խնդիրը։

Տարանտուլա ունենք, վշարդ ունենք, էլ ի՞նչ ուզես։

Նախ, դա հարմարության խնդիր է: Vshard-ի կոնֆիգուրացիան կազմաձևված է Lua աղյուսակների միջոցով: Որպեսզի Tarantool-ի բազմաթիվ պրոցեսների բաշխված համակարգը ճիշտ աշխատի, կոնֆիգուրացիան պետք է ամենուր նույնը լինի: Ոչ ոք չի ցանկանում դա անել ձեռքով: Հետևաբար, օգտագործվում են բոլոր տեսակի սցենարներ, Ansible և տեղակայման համակարգեր:

Քարթրիջն ինքն է կառավարում vshard-ի կոնֆիգուրացիան, դա անում է դրա հիման վրա սեփական բաշխված կոնֆիգուրացիա. Դա, ըստ էության, պարզ YAML ֆայլ է, որի պատճենը պահվում է Tarantool-ի յուրաքանչյուր օրինակում: Պարզեցումն այն է, որ շրջանակն ինքն է վերահսկում իր կազմաձևումը և ապահովում, որ այն նույնն է ամենուր:

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

Մենք նորից ու նորից լուծեցինք այս խնդիրները, և ինչ-որ պահի մեզ հաջողվեց մշակել մի մոտեցում, որը պարզեցնում էր հավելվածի հետ աշխատանքը նրա ողջ կյանքի ցիկլի ընթացքում՝ ստեղծում, մշակում, փորձարկում, CI/CD, սպասարկում:

Քարթրիջը ներկայացնում է դերի հայեցակարգը Tarantool-ի յուրաքանչյուր գործընթացի համար: Դերը հասկացություն է, որը թույլ է տալիս ծրագրավորողին կենտրոնանալ կոդ գրելու վրա: Նախագծում առկա բոլոր դերերը կարող են գործարկվել Tarantool-ի մեկ օրինակով, և դա բավական կլինի թեստերի համար:

Tarantool Cartridge-ի հիմնական հատկանիշները.

  • ավտոմատացված կլաստերային խմբավորում;
  • ընդլայնելով հավելվածի ֆունկցիոնալությունը՝ օգտագործելով նոր դերեր.
  • Ծրագրի ձևանմուշ մշակման և տեղակայման համար;
  • ներկառուցված ավտոմատ Sharing;
  • ինտեգրում Luatest թեստավորման շրջանակին;
  • կլաստերի կառավարում WebUI-ի և API-ի միջոցով;
  • փաթեթավորման և տեղակայման գործիքներ:

Բարեւ աշխարհ!

Ես չեմ կարող սպասել, որ ցուցադրվի հենց շրջանակը, այնպես որ մենք ճարտարապետության մասին պատմությունը կթողնենք ավելի ուշ և կսկսենք պարզ բանից: Եթե ​​ենթադրենք, որ Tarantool-ն ինքն արդեն տեղադրված է, ապա մնում է անել

$ tarantoolctl rocks install cartridge-cli
$ export PATH=$PWD/.rocks/bin/:$PATH

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

$ cartridge create --name myapp

Եվ սա այն է, ինչ մենք ստանում ենք.

myapp/
├── .git/
├── .gitignore
├── app/roles/custom.lua
├── deps.sh
├── init.lua
├── myapp-scm-1.rockspec
├── test
│   ├── helper
│   │   ├── integration.lua
│   │   └── unit.lua
│   ├── helper.lua
│   ├── integration/api_test.lua
│   └── unit/sample_test.lua
└── tmp/

Սա git պահոց է պատրաստի «Բարև, աշխարհ»: դիմումը. Եկեք փորձենք գործարկել այն անմիջապես, նախապես տեղադրելով կախվածությունները (ներառյալ ինքնին շրջանակը).

$ tarantoolctl rocks make
$ ./init.lua --http-port 8080

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

Դիմումների մշակում

Պարզապես պատկերացրեք, մենք նախագծում ենք մի նախագիծ, որը պետք է ստանա տվյալներ, պահպանի դրանք և ստեղծի հաշվետվություն օրական մեկ անգամ:

Tarantool Քարտրիջ. Lua հետնամասի բեկում երեք տողով

Մենք սկսում ենք գծապատկեր նկարել և դրա վրա տեղադրել երեք բաղադրիչ՝ դարպաս, պահեստ և ժամանակացույց: Մենք շարունակում ենք աշխատել ճարտարապետության վրա: Քանի որ մենք օգտագործում ենք vshard-ը որպես պահեստ, մենք սխեմային ավելացնում ենք vshard-router և vshard-storage: Ո՛չ դարպասը, ո՛չ ժամանակացույցն ուղղակիորեն մուտք չեն գործի պահոց. հենց դրա համար է երթուղիչը, դրա համար է այն ստեղծվել:

Tarantool Քարտրիջ. Lua հետնամասի բեկում երեք տողով

Այս դիագրամը դեռ ճշգրիտ չի ներկայացնում, թե ինչ ենք կառուցելու նախագծում, քանի որ բաղադրիչները վերացական տեսք ունեն: Մենք դեռ պետք է տեսնենք, թե ինչպես է դա նախագծվելու իրական Tarantool-ի վրա. եկեք խմբավորենք մեր բաղադրիչներն ըստ գործընթացի:

Tarantool Քարտրիջ. Lua հետնամասի բեկում երեք տողով

Առանձին ատյաններում vshard-router-ը և gateway-ը պահելը քիչ իմաստ ունի: Ինչու՞ պետք է ևս մեկ անգամ շրջել ցանցում, եթե դա արդեն երթուղիչի պարտականությունն է: Դրանք պետք է իրականացվեն նույն գործընթացի շրջանակներում: Այսինքն՝ և՛ gateway-ը, և՛ vshard.router.cfg-ը սկզբնավորվում են մեկ պրոցեսում, և թող դրանք փոխազդեն լոկալ։

Դիզայնի փուլում հարմար էր աշխատել երեք բաղադրիչի հետ, բայց ես՝ որպես ծրագրավորող, կոդը գրելիս չեմ ուզում մտածել Tarnatool-ի երեք օրինակ գործարկելու մասին։ Պետք է թեստեր անցկացնեմ և ստուգեմ, որ ճիշտ եմ գրել gateway-ը: Կամ գուցե ես ուզում եմ իմ գործընկերներին ցույց տալ մի առանձնահատկություն: Ինչու՞ ես պետք է անցնեմ երեք օրինակ տեղակայելու դժվարությունների միջով: Այսպես ծնվեց դերեր հասկացությունը։ Դերը սովորական luash մոդուլ է, որի կյանքի ցիկլը կառավարվում է Քարթրիջի կողմից: Այս օրինակում դրանք չորսն են՝ դարպաս, երթուղիչ, պահեստ, ժամանակացույց: Մեկ այլ նախագծում կարող է ավելին լինել: Բոլոր դերերը կարող են իրականացվել մեկ գործընթացում, և դա բավարար կլինի:

Tarantool Քարտրիջ. Lua հետնամասի բեկում երեք տողով

Եվ երբ խոսքը վերաբերում է բեմադրության կամ արտադրության տեղակայմանը, ապա մենք Tarantool-ի յուրաքանչյուր գործընթացին կհատկացնենք իր դերերը՝ կախված ապարատային հնարավորություններից.

Tarantool Քարտրիջ. Lua հետնամասի բեկում երեք տողով

Տոպոլոգիայի կառավարում

Տեղեկություններ այն մասին, թե որտեղ են առաջադրվում դերերը, պետք է ինչ-որ տեղ պահվեն: Եվ սա «ինչ-որ տեղ» բաշխված կոնֆիգուրացիան է, որը ես արդեն նշեցի վերևում: Դրա հետ կապված ամենակարևորը կլաստերային տոպոլոգիան է։ Ահա 3 Tarantool գործընթացների 5 կրկնօրինակման խմբեր.

Tarantool Քարտրիջ. Lua հետնամասի բեկում երեք տողով

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

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

Tarantool Քարտրիջ. Lua հետնամասի բեկում երեք տողով

Դերերի կյանք

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

function init()
function validate_config()
function apply_config()
function stop()

Յուրաքանչյուր դեր ունի իր գործառույթը init. Այն կոչվում է մեկ անգամ, երբ դերը միացված է, կամ երբ Tarantool-ը վերագործարկվում է: Այնտեղ հարմար է, օրինակ, նախաստորագրել box.space.create-ը, կամ ժամանակացույցը կարող է գործարկել որոշ ֆոնային մանրաթել, որը կկատարի աշխատանքը որոշակի ժամանակային ընդմիջումներով:

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

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

Նաև դերերն ունեն մեթոդ stop, որն անհրաժեշտ է դերի արդյունքը մաքրելու համար: Եթե ​​ասենք, որ ժամանակացույցն այլևս անհրաժեշտ չէ այս սերվերում, այն կարող է դադարեցնել այն մանրաթելերը, որոնք սկսել է օգտագործել init.

Դերերը կարող են փոխազդել միմյանց հետ: Մենք սովոր ենք Lua-ով ֆունկցիայի կանչեր գրել, բայց կարող է պատահել, որ տվյալ պրոցեսը չունենա մեզ անհրաժեշտ դերը։ Ցանցով զանգերը հեշտացնելու համար մենք օգտագործում ենք rpc (հեռավոր ընթացակարգի զանգ) օժանդակ մոդուլը, որը կառուցված է Tarantool-ում ներկառուցված ստանդարտ netbox-ի հիման վրա: Սա կարող է օգտակար լինել, եթե, օրինակ, ձեր gateway-ը ցանկանում է ուղղակիորեն խնդրել ժամանակացույցին կատարել աշխատանքը հենց հիմա, այլ ոչ թե սպասել մեկ օր:

Մյուս կարևոր կետը սխալների հանդուրժողականության ապահովումն է: Քարթրիջը օգտագործում է SWIM արձանագրությունը՝ առողջությունը վերահսկելու համար [4]. Մի խոսքով, գործընթացները փոխադարձաբար «ասեկոսեներ» են փոխանակում UDP-ի շուրջ. յուրաքանչյուր գործընթաց իր հարևաններին հայտնում է վերջին նորությունները, և նրանք արձագանքում են: Եթե ​​հանկարծ պատասխանը չգա, Տարանտուլը սկսում է կասկածել, որ ինչ-որ բան այն չէ, և որոշ ժամանակ անց նա արտասանում է մահը և սկսում է պատմել բոլորին, ովքեր շրջապատում են այս լուրը:

Tarantool Քարտրիջ. Lua հետնամասի բեկում երեք տողով

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

Tarantool Քարտրիջ. Lua հետնամասի բեկում երեք տողով

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

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

Ի տարբերություն Docker-ի, մենք չենք կարող պարզապես դերի «պատկեր» վերցնել, այն տեղափոխել մեկ այլ սարք և գործարկել այնտեղ: Մեր դերերը այնքան մեկուսացված չեն, որքան Docker կոնտեյներները: Բացի այդ, մենք չենք կարող երկու նույնական դերեր կատարել մեկ օրինակում: Դերը կա՛մ կա, կա՛մ չկա, ինչ-որ իմաստով դա միայնակ է: Եվ երրորդը, դերերը պետք է նույնը լինեն ամբողջ վերարտադրման խմբում, քանի որ հակառակ դեպքում դա անհեթեթ կլինի. տվյալները նույնն են, բայց կոնֆիգուրացիան տարբեր է:

Տեղակայման գործիքներ

Ես խոստացա ցույց տալ, թե ինչպես է Քարտրիջն օգնում տեղակայել հավելվածները: Ուրիշների կյանքը հեշտացնելու համար շրջանակը փաթեթավորում է RPM փաթեթներ.

$ cartridge pack rpm myapp -- упакует для нас ./myapp-0.1.0-1.rpm
$ sudo yum install ./myapp-0.1.0-1.rpm

Տեղադրված փաթեթը պարունակում է գրեթե այն ամենը, ինչ ձեզ հարկավոր է՝ և՛ հավելվածը, և՛ տեղադրված կախվածությունները: Tarantool-ը նույնպես կհայտնվի սերվերում՝ որպես RPM փաթեթի կախվածություն, և մեր ծառայությունը պատրաստ է գործարկման: Սա արվում է systemd-ի միջոցով, բայց նախ պետք է մի փոքր կոնֆիգուրացիա գրել։ Նվազագույնը նշեք յուրաքանչյուր գործընթացի URI-ը: Օրինակ երեքը բավական է.

$ sudo tee /etc/tarantool/conf.d/demo.yml <<CONFIG
myapp.router: {"advertise_uri": "localhost:3301", "http_port": 8080}
myapp.storage_A: {"advertise_uri": "localhost:3302", "http_enabled": False}
myapp.storage_B: {"advertise_uri": "localhost:3303", "http_enabled": False}
CONFIG

Այստեղ մի հետաքրքիր նրբերանգ կա. Միայն երկուական արձանագրության պորտը նշելու փոխարեն, մենք նշում ենք գործընթացի ողջ հանրային հասցեն, ներառյալ հոսթի անունը: Սա անհրաժեշտ է, որպեսզի կլաստերային հանգույցները իմանան, թե ինչպես միանալ միմյանց: Վատ գաղափար է օգտագործել 0.0.0.0 որպես advertise_uri հասցե, այն պետք է լինի արտաքին IP հասցե, այլ ոչ թե վարդակից: Առանց դրա, ոչինչ չի աշխատի, ուստի Քարթրիջը պարզապես թույլ չի տա ձեզ սխալ advertise_uri հանգույց գործարկել:

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

$ sudo systemctl start myapp@router
$ sudo systemctl start myapp@storage_A
$ sudo systemctl start myapp@storage_B

Կազմաձևում մենք նշել ենք HTTP պորտը, որի վրա Քարթրիջը սպասարկում է վեբ ինտերֆեյսը - 8080: Եկեք գնանք դրան և նայենք.

Tarantool Քարտրիջ. Lua հետնամասի բեկում երեք տողով

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

Եկեք մի բաժակ լցնենք ձեր սիրելի ըմպելիքը և հանգստանանք երկար աշխատանքային շաբաթից հետո։ Հավելվածը կարող է օգտագործվել:

Tarantool Քարտրիջ. Lua հետնամասի բեկում երեք տողով

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

Որո՞նք են արդյունքները: Փորձեք այն, օգտագործեք այն, թողեք հետադարձ կապ, ստեղծեք տոմսեր Github-ում:

Սայլակ

[1] Tarantool » 2.2 » Reference » Rocks reference » Module vshard

[2] Ինչպես ենք մենք իրականացրել Alfa-Bank-ի ներդրումային բիզնեսի առանցքը՝ հիմնված Tarantool-ի վրա

[3] Նոր սերնդի բիլինգի ճարտարապետություն. վերափոխում Tarantool-ին անցումով

[4] SWIM - կլաստերի կառուցման արձանագրություն

[5] GitHub - tarantool/cartridge-cli

[6] GitHub - tarantool/cartridge

Source: www.habr.com

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