ՀՏՀ VKontakte-ի ճարտարապետության և աշխատանքի վերաբերյալ

VKontakte-ի ստեղծման պատմությունը գտնվում է Վիքիպեդիայում, այն պատմել է ինքը՝ Պավելը։ Կարծես նրան արդեն բոլորն են ճանաչում։ Կայքի ներքին կառուցվածքի, ճարտարապետության և կառուցվածքի մասին HighLoad++ Pavel-ում ասաց ինձ դեռ 2010 թ. Այդ ժամանակվանից ի վեր շատ սերվերներ են արտահոսել, ուստի մենք կթարմացնենք տեղեկատվությունը. կհերձենք այն, կհանենք ներսը, կկշռենք և կնայենք VK սարքին տեխնիկական տեսանկյունից։

ՀՏՀ VKontakte-ի ճարտարապետության և աշխատանքի վերաբերյալ

Ալեքսեյ Ակուլովիչ (AterCattus) backend ծրագրավորող VKontakte թիմում: Այս զեկույցի սղագրությունը կոլեկտիվ պատասխան է պլատֆորմի, ենթակառուցվածքի, սերվերների և դրանց միջև փոխգործակցության մասին հաճախ տրվող հարցերի, բայց ոչ զարգացման, մասնավորապես. երկաթի մասին. Առանձին-առանձին, տվյալների բազաների և դրա փոխարեն VK-ի մասին, տեղեկամատյաններ հավաքելու և ամբողջ նախագծի մոնիտորինգի մասին: Մանրամասները կտրվածքի տակ։



Չորս տարուց ավելի է, ինչ ես զբաղվում եմ backend-ի հետ կապված բոլոր տեսակի խնդիրներով:

  • Մեդիա վերբեռնում, պահպանում, մշակում, բաշխում՝ տեսանյութ, ուղիղ հեռարձակում, աուդիո, լուսանկարներ, փաստաթղթեր:
  • Ենթակառուցվածք, հարթակ, մշակողների մոնիտորինգ, տեղեկամատյաններ, տարածաշրջանային քեշեր, CDN, սեփականության RPC արձանագրություն:
  • Ինտեգրում արտաքին ծառայությունների հետ. push ծանուցումներ, արտաքին հղումների վերլուծություն, RSS հոսք:
  • Օգնել գործընկերներին տարբեր հարցերով, որոնց պատասխանները պահանջում են սուզվել անհայտ կոդի մեջ:

Այս ընթացքում ես ձեռք եմ բերել կայքի բազմաթիվ բաղադրիչներ: Ես ուզում եմ կիսվել այս փորձով:

Ընդհանուր ճարտարապետություն

Ամեն ինչ, ինչպես միշտ, սկսվում է սերվերից կամ սերվերների խմբից, որոնք ընդունում են հարցումները:

Առջևի սերվեր

Առջևի սերվերն ընդունում է հարցումները HTTPS-ի, RTMP-ի և WSS-ի միջոցով:

HTTPS - սրանք կայքի հիմնական և շարժական վեբ տարբերակների հարցումներ են՝ vk.com և m.vk.com, և մեր API-ի այլ պաշտոնական և ոչ պաշտոնական հաճախորդներ՝ բջջային հաճախորդներ, մեսենջերներ: Մենք ընդունելություն ունենք RTMP- երթևեկություն ուղիղ հեռարձակումների համար առանձին առջևի սերվերներով և WSS- ն- միացումներ Streaming API-ի համար:

Սերվերների վրա HTTPS-ի և WSS-ի համար դա արժե nginx. RTMP հեռարձակումների համար մենք վերջերս անցանք մեր սեփական լուծմանը kive, բայց դա դուրս է զեկույցի շրջանակներից։ Սխալների հանդուրժողականության համար այս սերվերները գովազդում են ընդհանուր IP հասցեները և գործում են խմբերով, որպեսզի եթե սերվերներից մեկի վրա խնդիր կա, օգտվողների հարցումները չկորչեն: HTTPS-ի և WSS-ի համար այս նույն սերվերները գաղտնագրում են տրաֆիկը, որպեսզի իրենց վրա վերցնեն պրոցեսորի բեռնվածությունը:

Մենք այլևս չենք խոսի WSS-ի և RTMP-ի մասին, այլ միայն ստանդարտ HTTPS հարցումների մասին, որոնք սովորաբար կապված են վեբ նախագծի հետ:

backend

Առջևի հետևում սովորաբար գտնվում են հետին մասի սերվերներ: Նրանք մշակում են այն հարցումները, որոնք առջևի սերվերը ստանում է հաճախորդներից:

այս kPHP սերվերներ, որի վրա աշխատում է HTTP դեյմոնը, քանի որ HTTPS-ն արդեն ապակոդավորված է։ kPHP-ը սերվեր է, որն աշխատում է prefork մոդելներ: սկսում է հիմնական պրոցես, մի ​​խումբ երեխա պրոցեսներ, նրանց փոխանցում լսողական վարդակներ և նրանք մշակում են իրենց հարցումները: Այս դեպքում պրոցեսները չեն վերսկսվում օգտատիրոջ յուրաքանչյուր հարցման միջև, այլ պարզապես վերագործարկում են իրենց վիճակը սկզբնական զրոյական արժեքի վիճակին՝ հարցումը հարցման հետևից, վերագործարկման փոխարեն:

Բեռի բաշխում

Մեր բոլոր հետին պլանները մեքենաների հսկայական լողավազան չեն, որոնք կարող են մշակել ցանկացած հարցում: Մենք՝ նրանց բաժանված են առանձին խմբերիԸնդհանուր, բջջային, api, վիդեո, բեմականացում... Մեքենաների առանձին խմբի խնդիրը չի ազդի բոլորի վրա: Տեսանյութի հետ կապված խնդիրների դեպքում երաժշտություն լսող օգտատերը չի էլ իմանա խնդիրների մասին։ Ո՞ր հետնամասին ուղարկել հարցումը, որոշվում է առջևի մասում գտնվող nginx-ի կողմից՝ ըստ կազմաձևի:

Մետրային հավաքագրում և հավասարակշռում

Հասկանալու համար, թե յուրաքանչյուր խմբում քանի մեքենա պետք է ունենանք, մենք մի ապավինեք QPS-ին. Հետադարձ կապերը տարբեր են, նրանք ունեն տարբեր հարցումներ, յուրաքանչյուր հարցում ունի QPS-ի հաշվարկման տարբեր բարդություն: Դրա համար մենք մենք աշխատում ենք սերվերի վրա բեռի հայեցակարգով, որպես ամբողջություն՝ պրոցեսորի և պերֆ.

Մենք ունենք հազարավոր նման սերվերներ: Յուրաքանչյուր ֆիզիկական սերվեր գործարկում է kPHP խումբ՝ բոլոր միջուկները վերամշակելու համար (քանի որ kPHP-ն մեկ թելերով է):

Բովանդակության սերվեր

CS կամ Content Server-ը պահեստ է. CS-ը սերվեր է, որը պահում է ֆայլերը, ինչպես նաև մշակում է վերբեռնված ֆայլերը և բոլոր տեսակի ֆոնային համաժամանակյա առաջադրանքները, որոնք գլխավոր վեբ ֆրոնդը վերագրում է նրան:

Մենք ունենք տասնյակ հազարավոր ֆիզիկական սերվերներ, որոնք պահում են ֆայլերը: Օգտատերերը սիրում են ֆայլեր վերբեռնել, իսկ մենք սիրում ենք դրանք պահել և տարածել: Այս սերվերներից մի քանիսը փակված են հատուկ pu/pp սերվերներով:

pu/pp

Եթե ​​բացել եք ցանցի ներդիրը VK-ում, տեսաք pu/pp:

ՀՏՀ VKontakte-ի ճարտարապետության և աշխատանքի վերաբերյալ

Ի՞նչ է pu/pp: Եթե ​​մենք փակում ենք սերվերը մյուսի հետևից, ապա փակված սերվերում ֆայլը վերբեռնելու և ներբեռնելու երկու տարբերակ կա. ուղղակիորեն միջոցով http://cs100500.userapi.com/path կամ միջանկյալ սերվերի միջոցով - http://pu.vk.com/c100500/path.

Pu-ն լուսանկարների վերբեռնման պատմական անվանումն է, իսկ pp-ը լուսանկարների վստահված անձ է. Այսինքն՝ մի սերվերը նկարներ վերբեռնելու համար է, մյուսը՝ վերբեռնելու համար։ Այժմ ոչ միայն լուսանկարներ են բեռնված, այլեւ անունը պահպանվել է։

Այս սերվերները դադարեցնել HTTPS նիստերըպրոցեսորի բեռնվածությունը պահեստից հեռացնելու համար: Բացի այդ, քանի որ օգտատերերի ֆայլերը մշակվում են այս սերվերների վրա, այնքան ավելի քիչ զգայուն տեղեկատվությունը պահվում է այս մեքենաներում, այնքան լավ: Օրինակ՝ HTTPS կոդավորման բանալիներ։

Քանի որ մեքենաները փակված են մեր մյուս մեքենաներով, մենք կարող ենք մեզ թույլ տալ չտալ նրանց «սպիտակ» արտաքին IP-ներ, և տալ «մոխրագույն». Այս կերպ մենք խնայեցինք IP լողավազանում և երաշխավորեցինք, որ կպաշտպանենք մեքենաները արտաքին մուտքից. պարզապես IP չկա ​​դրա մեջ մտնելու համար:

Ճկունություն ընդհանուր IP-ների նկատմամբ. Սխալների հանդուրժողականության առումով սխեման գործում է նույնը. մի քանի ֆիզիկական սերվերներ ունեն ընդհանուր ֆիզիկական IP, և նրանց դիմացի սարքավորումն ընտրում է, թե որտեղ ուղարկել հարցումը: Այլ տարբերակների մասին ավելի ուշ կխոսեմ:

Վիճահարույց կետն այն է, որ այս դեպքում հաճախորդը պահպանում է ավելի քիչ կապեր. Եթե ​​նույն IP-ն կա մի քանի մեքենաների համար՝ միևնույն հոսթով՝ pu.vk.com կամ pp.vk.com, հաճախորդի զննարկիչն ունի մեկ հոսթին միաժամանակյա հարցումների քանակի սահմանափակում: Բայց ամենուր տարածված HTTP/2-ի ժամանակ ես կարծում եմ, որ դա այլևս այնքան էլ տեղին չէ:

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

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

Արեւ

2017 թվականի սեպտեմբերին Oracle-ը, որը նախկինում գնել էր Sun-ը, աշխատանքից ազատել է Sun-ի հսկայական թվով աշխատակիցների. Կարելի է ասել, որ այս պահին ընկերությունը դադարեց գոյություն ունենալ։ Նոր համակարգի համար անուն ընտրելիս մեր ադմինիստրատորները որոշեցին հարգանքի տուրք մատուցել այս ընկերության հիշատակին և նոր համակարգը անվանեցին Sun։ Մեր մեջ մենք նրան պարզապես անվանում ենք «արևներ»:

ՀՏՀ VKontakte-ի ճարտարապետության և աշխատանքի վերաբերյալ

pp-ն մի քանի խնդիր ուներ. Մեկ IP յուրաքանչյուր խմբի համար՝ անարդյունավետ քեշ. Մի քանի ֆիզիկական սերվերներ կիսում են ընդհանուր IP հասցե, և ոչ մի միջոց չկա վերահսկելու, թե որ սերվերին կուղղվի հարցումը: Հետևաբար, եթե տարբեր օգտվողներ գալիս են նույն ֆայլի համար, ապա եթե այս սերվերների վրա կա քեշ, ֆայլը հայտնվում է յուրաքանչյուր սերվերի քեշում: Սա շատ անարդյունավետ սխեմա է, բայց ոչինչ հնարավոր չէր անել։

Հետևաբար - մենք չենք կարող կիսել բովանդակությունը, քանի որ մենք չենք կարող ընտրել կոնկրետ սերվեր այս խմբի համար. նրանք ունեն ընդհանուր IP: Նաև որոշ ներքին պատճառներով ունենք հնարավոր չէր նման սերվերներ տեղադրել մարզերում. Նրանք կանգնեցին միայն Սանկտ Պետերբուրգում։

Արևներով փոխեցինք ընտրության համակարգը։ Այժմ մենք ունենք anycast երթուղում: դինամիկ երթուղի, anycast, ինքնաստուգման դեյմոն: Յուրաքանչյուր սերվեր ունի իր անհատական ​​IP-ն, բայց ընդհանուր ենթացանց: Ամեն ինչ կազմաձևված է այնպես, որ եթե մեկ սերվերը ձախողվի, ապա տրաֆիկը ավտոմատ կերպով տարածվում է նույն խմբի մյուս սերվերների վրա: Այժմ հնարավոր է ընտրել կոնկրետ սերվեր, ոչ ավելորդ քեշավորում, և հուսալիությունը չի ազդել:

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

Տարածում ըստ բովանդակության ID-ի. Զվարճալի բան Sharing-ի հետ կապված. մենք սովորաբար կիսում ենք բովանդակությունը, որպեսզի տարբեր օգտվողներ նույն «արևի» միջոցով գնան նույն ֆայլը, որպեսզի նրանք ունենան ընդհանուր քեշ:

Վերջերս գործարկեցինք «Երեքնուկ» հավելվածը։ Սա առցանց վիկտորինան է ուղիղ եթերում, որտեղ հաղորդավարը հարցեր է տալիս, իսկ օգտատերերը պատասխանում են իրական ժամանակում՝ ընտրելով տարբերակներ։ Հավելվածն ունի չաթ, որտեղ օգտվողները կարող են զրուցել: Կարող է միաժամանակ միանալ հեռարձակմանը ավելի քան 100 հազար մարդ. Նրանք բոլորը գրում են հաղորդագրություններ, որոնք ուղարկվում են բոլոր մասնակիցներին, և հաղորդագրության հետ գալիս է ավատար: Եթե ​​մեկ «արևի տակ» մեկ ավատարի համար գալիս է 100 հազար մարդ, ապա այն երբեմն կարող է գլորվել ամպի հետևում։

Միևնույն ֆայլի հարցումների պայթյուններին դիմակայելու համար հենց որոշակի տեսակի բովանդակության համար մենք միացնում ենք հիմար սխեման, որը ֆայլերը տարածում է տարածաշրջանի բոլոր հասանելի «արևների» վրա:

Արևը ներսից

Reverse proxy-ը nginx-ում, քեշը կամ RAM-ում կամ արագ Optane/NVMe սկավառակների վրա: Օրինակ: http://sun4-2.userapi.com/c100500/path — հղում դեպի «արև», որը գտնվում է չորրորդ տարածաշրջանում՝ երկրորդ սերվերի խմբին։ Այն փակում է ուղու ֆայլը, որը ֆիզիկապես գտնվում է 100500 սերվերի վրա:

Գաղտնարան

Մենք մեր ճարտարապետական ​​սխեմային ավելացնում ենք ևս մեկ հանգույց՝ քեշավորման միջավայրը:

ՀՏՀ VKontakte-ի ճարտարապետության և աշխատանքի վերաբերյալ

Ստորև ներկայացված է դասավորության դիագրամը տարածաշրջանային պահոցներ, դրանք մոտ 20-ն են։ Սրանք այն վայրերն են, որտեղ գտնվում են պահոցները և «արևները», որոնք կարող են իրենց միջոցով քշել երթևեկությունը:

ՀՏՀ VKontakte-ի ճարտարապետության և աշխատանքի վերաբերյալ

Սա մուլտիմեդիա բովանդակության քեշավորում է, այստեղ օգտվողի տվյալներ չեն պահվում՝ միայն երաժշտություն, տեսանյութ, լուսանկարներ:

Օգտագործողի տարածաշրջանը որոշելու համար մենք մենք հավաքում ենք մարզերում հայտարարված BGP ցանցի նախածանցները. Հետադարձ կապի դեպքում մենք նաև պետք է վերլուծենք geoip տվյալների բազան, եթե չկարողացանք գտնել IP-ն ըստ նախածանցների: Մենք որոշում ենք տարածաշրջանը օգտագործողի IP-ով. Կոդում մենք կարող ենք դիտել օգտվողի մեկ կամ մի քանի շրջաններ՝ այն կետերը, որոնց նա աշխարհագրորեն ամենամոտ է:

Ինչպես է դա աշխատում.

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

Միևնույն ժամանակ, դևերը՝ ծառայություններ մարզերում, ժամանակ առ ժամանակ գալիս են API և ասում. » API-ն մատակարարում է ֆայլերի մի փունջ՝ դասավորված ըստ վարկանիշի, դեյմոնը ներբեռնում է դրանք, տանում է տարածաշրջաններ և այնտեղից առաքում ֆայլերը: Սա pu/pp-ի և Sun-ի հիմնական տարբերությունն է քեշերից. նրանք անմիջապես տալիս են ֆայլը իրենց միջոցով, նույնիսկ եթե այս ֆայլը քեշում չէ, և քեշը սկզբում ներբեռնում է ֆայլը իր մեջ, այնուհետև սկսում է վերադարձնել այն:

Այս դեպքում մենք ստանում ենք օգտվողներին ավելի մոտ բովանդակություն և տարածելով ցանցի բեռը: Օրինակ, միայն մոսկովյան քեշից մենք բաշխում ենք ավելի քան 1 Թբիթ/վրկ պիկ ժամերին։

Բայց կան խնդիրներ - քեշ սերվերները ռետինե չեն. Գեր հանրաճանաչ բովանդակության համար երբեմն առանձին սերվերի համար բավարար ցանց չկա: Մեր քեշ սերվերները 40-50 Գբիթ/վրկ են, բայց կա բովանդակություն, որն ամբողջությամբ խցանում է նման ալիքը։ Մենք շարժվում ենք տարածաշրջանում հայտնի ֆայլերի մեկից ավելի պատճենների պահպանման իրականացման ուղղությամբ: Հուսով եմ, որ մինչև տարեվերջ դա կիրականացնենք։

Մենք նայեցինք ընդհանուր ճարտարապետությանը:

  • Առջևի սերվերներ, որոնք ընդունում են հարցումները:
  • Backends, որոնք մշակում են հարցումները:
  • Պահեստներ, որոնք փակված են երկու տեսակի վստահված անձանց կողմից:
  • Տարածաշրջանային պահոցներ.

Ի՞նչ է պակասում այս դիագրամից: Իհարկե, տվյալների բազաները, որոնցում մենք պահում ենք տվյալները:

Տվյալների բազաներ կամ շարժիչներ

Մենք դրանք անվանում ենք ոչ թե տվյալների բազաներ, այլ շարժիչներ - Շարժիչներ, քանի որ մենք գործնականում չունենք տվյալների շտեմարաններ ընդհանուր ընդունված իմաստով։

ՀՏՀ VKontakte-ի ճարտարապետության և աշխատանքի վերաբերյալ

Սա անհրաժեշտ միջոց է. Դա տեղի ունեցավ այն պատճառով, որ 2008-2009 թվականներին, երբ VK-ն ուներ ժողովրդականության պայթյունավտանգ աճ, նախագիծն ամբողջությամբ աշխատում էր MySQL-ի և Memcache-ի վրա, և խնդիրներ կային: MySQL-ը սիրում էր խափանել և փչացնել ֆայլերը, որից հետո այն չէր վերականգնվի, և Memcache-ն աստիճանաբար վատթարացավ կատարողականությամբ և պետք է վերագործարկվեր:

Պարզվում է, որ ավելի ու ավելի մեծ ժողովրդականություն վայելող նախագիծն ուներ մշտական ​​պահեստավորում, որը փչացնում է տվյալները, և քեշ, որը դանդաղեցնում է արագությունը: Նման պայմաններում դժվար է զարգացող նախագիծ մշակել։ Որոշվեց փորձել վերաշարադրել այն քննադատական ​​բաները, որոնց վրա նախագիծը կենտրոնացած էր մեր սեփական հեծանիվների վրա:

Լուծումը հաջող էր. Սրա հնարավորությունը կար, ինչպես նաև ծայրահեղ անհրաժեշտություն, քանի որ այն ժամանակ մասշտաբի այլ եղանակներ չկային։ Չկային տվյալների բազաների մի փունջ, NoSQL դեռ գոյություն չուներ, կային միայն MySQL, Memcache, PostrgreSQL, և վերջ:

Ունիվերսալ գործողություն. Մշակումը ղեկավարում էր C մշակողների մեր թիմը, և ամեն ինչ արվում էր հետևողական կերպով: Անկախ շարժիչից, նրանք բոլորն ունեին մոտավորապես նույն ֆայլի ձևաչափը, որը գրված էր սկավառակի վրա, նույն գործարկման պարամետրերը, նույն ձևով մշակում էին ազդանշանները և իրենց պահում էին մոտավորապես նույնը եզրային իրավիճակների և խնդիրների դեպքում: Շարժիչների աճով, ադմինիստրատորների համար հարմար է համակարգը գործարկել. չկա կենդանաբանական այգի, որը պետք է պահպանվի, և նրանք պետք է նորից սովորեն, թե ինչպես վարել երրորդ կողմի յուրաքանչյուր նոր տվյալների բազան, ինչը հնարավորություն է տվել արագ և հարմարավետորեն ավելացնել: նրանց թիվը։

Շարժիչների տեսակները

Թիմը գրել է բավականին շատ շարժիչներ: Ահա դրանցից միայն մի քանիսը. ընկեր, ակնարկներ, պատկեր, ipdb, տառեր, ցուցակներ, տեղեկամատյաններ, memcached, meowdb, նորություններ, նոստրադամուս, լուսանկար, երգացանկ, pmemcached, sandbox, որոնում, պահեստավորում, հավանումներ, առաջադրանքներ,…

Յուրաքանչյուր առաջադրանքի համար, որը պահանջում է տվյալների հատուկ կառուցվածք կամ մշակում է անտիպ հարցումներ, C թիմը գրում է նոր շարժիչ: Ինչու ոչ.

Ունենք առանձին շարժիչ հուշում, որը նման է սովորականին, բայց բարիքների փունջով, և որը չի դանդաղում։ ClickHouse-ը չէ, բայց այն նաև աշխատում է: Առկա է առանձին pmemcached - Ից համառ memcached, որը կարող է նաև տվյալներ պահել սկավառակի վրա, ընդ որում՝ տեղավորվում է RAM-ում՝ վերագործարկման ժամանակ տվյալները չկորցնելու համար։ Առանձին առաջադրանքների համար կան տարբեր շարժիչներ՝ հերթեր, ցուցակներ, հավաքածուներ՝ այն ամենը, ինչ պահանջում է մեր նախագիծը:

Կլաստերներ

Կոդի տեսանկյունից, շարժիչները կամ տվյալների բազաները որպես գործընթացներ, միավորներ կամ օրինակներ մտածելու կարիք չկա: Կոդն աշխատում է հատուկ կլաստերների հետ, շարժիչների խմբերի հետ. մեկ տեսակի մեկ կլաստերի համար. Ենթադրենք, կա memcached կլաստեր՝ դա պարզապես մեքենաների խումբ է:

Կոդն ընդհանրապես կարիք չունի իմանալու ֆիզիկական գտնվելու վայրը, չափը կամ սերվերների քանակը: Նա գնում է կլաստերի՝ օգտագործելով որոշակի նույնացուցիչ:

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

RPC վստահված անձ

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

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

ՀՏՀ VKontakte-ի ճարտարապետության և աշխատանքի վերաբերյալ

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

Հատուկ իրականացումներ

Երբեմն մենք դեռ իսկապես ցանկանում ենք որպես շարժիչ ունենալ ինչ-որ ոչ ստանդարտ լուծում: Միևնույն ժամանակ որոշվեց չօգտագործել մեր պատրաստի rpc-proxy-ը, որը ստեղծվել է հատուկ մեր շարժիչների համար, այլ առաջադրանքի համար պատրաստել առանձին պրոքսի։

MySQL-ի համար, որը մենք դեռ ունենք այստեղ և այնտեղ, մենք օգտագործում ենք db-proxy, իսկ ClickHouse-ի համար՝ Kittenhouse.

Այն սովորաբար աշխատում է այսպես. Կա որոշակի սերվեր, այն աշխատում է kPHP, Go, Python - ընդհանրապես, ցանկացած կոդ, որը կարող է օգտագործել մեր RPC արձանագրությունը: Կոդն աշխատում է տեղական RPC վստահված անձի վրա. յուրաքանչյուր սերվեր, որտեղ գտնվում է կոդը, գործարկում է իր տեղական վստահված անձը: Հարցման դեպքում վստահված անձը հասկանում է, թե ուր գնալ:

ՀՏՀ VKontakte-ի ճարտարապետության և աշխատանքի վերաբերյալ

Եթե ​​մի շարժիչը ցանկանում է գնալ մյուսին, նույնիսկ եթե դա հարեւան է, այն անցնում է վստահված անձի միջոցով, քանի որ հարեւանը կարող է լինել մեկ այլ տվյալների կենտրոնում: Շարժիչը չպետք է հույս դնի իրենից բացի որևէ այլ բանի գտնվելու վայրի իմացության վրա. սա մեր ստանդարտ լուծումն է: Բայց իհարկե կան բացառություններ :)

TL-ի սխեմայի օրինակ, ըստ որի բոլոր շարժիչները գործում են:

memcache.not_found                                = memcache.Value;
memcache.strvalue	value:string flags:int = memcache.Value;
memcache.addOrIncr key:string flags:int delay:int value:long = memcache.Value;

tasks.task
    fields_mask:#
    flags:int
    tag:%(Vector int)
    data:string
    id:fields_mask.0?long
    retries:fields_mask.1?int
    scheduled_time:fields_mask.2?int
    deadline:fields_mask.3?int
    = tasks.Task;
 
tasks.addTask type_name:string queue_id:%(Vector int) task:%tasks.Task = Long;

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

RPC-ն TL-ի նկատմամբ TCP/UDP-ի նկատմամբ… UDP:

Մենք ունենք RPC արձանագրություն՝ շարժիչի հարցումները կատարելու համար, որն աշխատում է TL սխեմայի վերևում: Այս ամենը աշխատում է TCP/UDP կապի միջոցով: TCP-ն հասկանալի է, բայց ինչո՞ւ է մեզ հաճախ UDP-ի կարիքը:

UDP-ն օգնում է խուսափել սերվերների միջև հսկայական թվով կապերի խնդրից. Եթե ​​յուրաքանչյուր սերվեր ունի RPC պրոքսի և, ընդհանուր առմամբ, այն կարող է գնալ ցանկացած շարժիչի, ապա մեկ սերվերի համար կան տասնյակ հազարավոր TCP կապեր: Բեռ կա, բայց անօգուտ։ UDP-ի դեպքում այս խնդիրը գոյություն չունի։

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

Այո, ամեն ինչ պարզապես աշխատում է փաթեթների կորստի շատ փոքր տոկոսով. Արձանագրությունն ունի վերահաղորդումների և ժամանակի ընդհատումների աջակցություն, բայց եթե մենք շատ բան կորցնենք, մենք կստանանք գրեթե TCP, ինչը ձեռնտու չէ: Մենք UDP-ն չենք քշում օվկիանոսներով:

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

Մշտական ​​տվյալների պահպանում

Շարժիչները գրում են բինլոգներ. Բինլոգը ֆայլ է, որի վերջում ավելացվում է վիճակի կամ տվյալների փոփոխության իրադարձություն: Տարբեր լուծումներում այն ​​կոչվում է այլ կերպ՝ երկուական մատյան, WAL, AOF, բայց սկզբունքը նույնն է.

Որպեսզի շարժիչը վերագործարկելիս երկար տարիներ չվերընթերցի ամբողջ բինլոգը, շարժիչները գրում են snapshots - ընթացիկ վիճակ. Անհրաժեշտության դեպքում սկզբում կարդում են դրանից, հետո ավարտում են բինլոգից կարդալը։ Բոլոր բինլոգները գրված են նույն երկուական ձևաչափով` համաձայն TL սխեմայի, որպեսզի ադմինները կարողանան հավասարապես կառավարել դրանք իրենց գործիքներով: Պատկերների նման կարիք չկա։ Գոյություն ունի ընդհանուր վերնագիր, որը ցույց է տալիս, թե ում պատկերն է int-ը, շարժիչի կախարդանքը և որ մարմինը որևէ մեկի համար կարևոր չէ: Սա ֆոտոշարքի հետ կապված խնդիր է:

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

ՀՏՀ VKontakte-ի ճարտարապետության և աշխատանքի վերաբերյալ

Ինչ-որ պահի նա կամ ինքն է որոշում լուսանկարել, կամ էլ ազդանշան է ստանում։ Սերվերը ստեղծում է նոր ֆայլ, գրում է դրա ամբողջ վիճակը, ֆայլի վերջում ավելացնում է ընթացիկ բինլոգի չափը՝ օֆսեթ, և շարունակում է գրել հետագա: Նոր բինլոգ չի ստեղծվում:

ՀՏՀ VKontakte-ի ճարտարապետության և աշխատանքի վերաբերյալ

Ինչ-որ պահի, երբ շարժիչը վերագործարկվի, սկավառակի վրա կլինի և՛ բինլոգը, և՛ լուսանկարը: Շարժիչը կարդում է ամբողջ պատկերը և որոշակի կետում բարձրացնում է իր վիճակը:

ՀՏՀ VKontakte-ի ճարտարապետության և աշխատանքի վերաբերյալ

Կարդում է դիրքը, որը եղել է լուսանկարի ստեղծման պահին և բինլոգի չափը:

ՀՏՀ VKontakte-ի ճարտարապետության և աշխատանքի վերաբերյալ

Կարդում է բինլոգի վերջը՝ ներկայիս վիճակը ստանալու համար և շարունակում է գրել հետագա իրադարձությունները: Սա պարզ սխեմա է, մեր բոլոր շարժիչներն աշխատում են դրա համաձայն:

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

Արդյունքում տվյալների կրկնօրինակումը մեր հայտարարության վրա հիմնված — Բինլոգում գրում ենք ոչ թե էջի փոփոխություններ, այլ մասնավորապես փոփոխության հարցումները. Շատ նման է այն, ինչ գալիս է ցանցի միջոցով, միայն մի փոքր փոփոխված է:

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

ՀՏՀ VKontakte-ի ճարտարապետության և աշխատանքի վերաբերյալ

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

Այստեղ ուշացումը շատ փոքր է, և հնարավոր է պարզել, թե որքանով է կրկնօրինակը հետ մնում վարպետից։

Տվյալների փոխանակում RPC վստահված անձի մեջ

Ինչպե՞ս է աշխատում փոխանակումը: Ինչպե՞ս է վստահված անձը հասկանում, թե որ կլաստերի բեկորն ուղարկել: Կոդը չի ասում. «Ուղարկել 15 բեկորների համար»: - Ոչ, դա արվում է վստահված անձի կողմից:

Ամենապարզ սխեման առաջինն է — հարցումի առաջին համարը։

get(photo100_500) => 100 % N.

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

Սա օգտակար է, երբ մենք ցանկանում ենք ունենալ մեկ անձի տվյալների տեղայնություն: Ենթադրենք, 100-ը օգտագործողի կամ խմբի ID է, և մենք ցանկանում ենք, որ մեկ անձի բոլոր տվյալները լինեն մեկ բեկորի վրա բարդ հարցումների համար:

Եթե ​​մեզ չի հետաքրքրում, թե ինչպես են հարցումները տարածվում կլաստերի վրա, կա մեկ այլ տարբերակ. խաշել ամբողջ բեկորը.

hash(photo100_500) => 3539886280 % N

Մենք նաև ստանում ենք հեշը, բաժանման մնացորդը և բեկորային համարը:

Այս երկու տարբերակներն էլ աշխատում են միայն այն դեպքում, եթե մենք պատրաստ լինենք այն փաստին, որ երբ մենք մեծացնում ենք կլաստերի չափը, մենք այն կբաժանենք կամ կմեծացնենք մի քանի անգամ: Օրինակ, մենք ունեինք 16 բեկոր, մենք չունենք բավարար, մենք ավելին ենք ուզում. մենք կարող ենք ապահով կերպով ստանալ 32 առանց պարապուրդի: Եթե ​​մենք ցանկանում ենք ավելացնել ոչ թե բազմապատիկ, ապա կլինեն պարապուրդներ, քանի որ մենք չենք կարողանա ճշգրիտ բաժանել ամեն ինչ առանց կորուստների: Այս տարբերակները օգտակար են, բայց ոչ միշտ:

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

Կան սուպերկոնկրետ հարցումներ։ Կարծես այսպես. RPC վստահված անձը ստանում է հարցումը, որոշում, թե որ կլաստերին գնալ և որոշում է բեկորը: Այնուհետև կան կամ գրելու վարպետներ, կամ, եթե կլաստերը ունի կրկնօրինակի աջակցություն, այն ուղարկում է կրկնօրինակին ըստ պահանջի: Այս ամենն անում է վստահված անձը։

ՀՏՀ VKontakte-ի ճարտարապետության և աշխատանքի վերաբերյալ

Տեղեկամատյանները

Մենք գրում ենք տեղեկամատյանները մի քանի ձևով. Ամենաակնհայտն ու պարզն է գրել տեղեկամատյաններ memcache-ում.

ring-buffer: prefix.idx = line

Կա բանալի նախածանց՝ մատյանի անվանումը, տող, և կա այս մատյանի չափը՝ տողերի քանակը։ Մենք վերցնում ենք պատահական թիվ 0-ից մինչև տողերի թիվը՝ մինուս 1: Memcache-ի բանալին այս պատահական թվի հետ միացված նախածանցն է: Մենք պահպանում ենք մատյան գիծը և ընթացիկ ժամանակը արժեքին:

Երբ անհրաժեշտ է կարդալ տեղեկամատյանները, մենք իրականացնում ենք Multi Get բոլոր ստեղները՝ դասավորված ըստ ժամանակի, և այդպիսով ստացեք արտադրության գրանցամատյան իրական ժամանակում: Սխեման օգտագործվում է, երբ դուք պետք է իրական ժամանակում ինչ-որ բան կարգաբերեք արտադրության մեջ, առանց որևէ բան կոտրելու, առանց դադարեցնելու կամ թույլ տալու երթևեկությունը դեպի այլ մեքենաներ, բայց այս գրանցամատյանը երկար չի տևում:

Գերանների հուսալի պահպանման համար մենք ունենք շարժիչ տեղեկամատյաններ-շարժիչ. Հենց սա է պատճառը, որ այն ստեղծվել է և լայնորեն կիրառվում է հսկայական թվով կլաստերներում: Ամենամեծ կլաստերը, որը ես գիտեմ, պահում է 600 ՏԲ փաթեթավորված գերաններ:

Շարժիչը շատ հին է, կան կլաստերներ, որոնք արդեն 6-7 տարեկան են։ Դրա հետ կապված խնդիրներ կան, որոնք մենք փորձում ենք լուծել, օրինակ՝ սկսել ենք ակտիվորեն օգտագործել ClickHouse-ը տեղեկամատյանները պահելու համար։

Տեղեկամատյանների հավաքում ClickHouse-ում

Այս դիագրամը ցույց է տալիս, թե ինչպես ենք մենք մտնում մեր շարժիչները:

ՀՏՀ VKontakte-ի ճարտարապետության և աշխատանքի վերաբերյալ

Կա կոդ, որը տեղական RPC-ի միջոցով գնում է դեպի RPC վստահված անձ, և այն հասկանում է, թե ուր գնալ դեպի շարժիչը: Եթե ​​ցանկանում ենք տեղեկամատյաններ գրել ClickHouse-ում, մենք պետք է փոխենք այս սխեմայի երկու մաս.

  • փոխարինել որոշ շարժիչներ ClickHouse-ով;
  • փոխարինեք RPC վստահված անձին, որը չի կարող մուտք գործել ClickHouse, ինչ-որ լուծումով, որը կարող է, և RPC-ի միջոցով:

Շարժիչը պարզ է. մենք այն փոխարինում ենք սերվերով կամ սերվերների կլաստերով ClickHouse-ով:

Եվ ClickHouse գնալու համար մենք արեցինք KittenHouse. Եթե ​​մենք անմիջապես KittenHouse-ից գնանք ClickHouse, այն չի դիմանա: Նույնիսկ առանց հարցումների, այն ավելանում է հսկայական թվով մեքենաների HTTP միացումներից: Որպեսզի սխեման աշխատի, ClickHouse-ով սերվերի վրա տեղական հակադարձ վստահված անձը բարձրացվում է, որը գրված է այնպես, որ կարողանա դիմակայել միացումների պահանջվող ծավալներին։ Այն կարող է նաև համեմատաբար հուսալիորեն բուֆերացնել տվյալներն իր ներսում:

ՀՏՀ VKontakte-ի ճարտարապետության և աշխատանքի վերաբերյալ

Երբեմն մենք չենք ցանկանում իրականացնել RPC սխեման ոչ ստանդարտ լուծումներում, օրինակ, nginx-ում: Հետևաբար, KittenHouse-ն ունի UDP-ի միջոցով տեղեկամատյաններ ստանալու հնարավորություն:

ՀՏՀ VKontakte-ի ճարտարապետության և աշխատանքի վերաբերյալ

Եթե ​​տեղեկամատյանների ուղարկողն ու ստացողը աշխատում են նույն մեքենայի վրա, ապա տեղական հոսթում UDP փաթեթը կորցնելու հավանականությունը բավականին ցածր է: Որպես փոխզիջում երրորդ կողմի լուծման մեջ RPC-ի ներդրման անհրաժեշտության և հուսալիության միջև, մենք պարզապես օգտագործում ենք UDP ուղարկումը: Այս սխեմային մենք կանդրադառնանք ավելի ուշ:

Մոնիտորինգ

Մենք ունենք երկու տեսակի տեղեկամատյաններ՝ դրանք հավաքագրված են ադմինիստրատորների կողմից իրենց սերվերների վրա և ծրագրավորողների կողմից գրված կոդից: Դրանք համապատասխանում են երկու տեսակի չափումների. համակարգ և արտադրանք.

Համակարգի չափումներ

Այն աշխատում է մեր բոլոր սերվերների վրա ցանցային տվյալներ, որը հավաքում է վիճակագրություն և ուղարկում դրանք Գրաֆիտ ածխածին. Հետևաբար, ClickHouse-ն օգտագործվում է որպես պահեստավորման համակարգ, և ոչ թե օրինակ՝ Whisper-ը։ Անհրաժեշտության դեպքում կարող եք ուղղակիորեն կարդալ ClickHouse-ից կամ օգտագործել Գրաֆանա չափումների, գրաֆիկների և հաշվետվությունների համար: Որպես ծրագրավորողներ, մենք բավականաչափ մուտք ունենք դեպի Netdata և Grafana:

Ապրանքի չափումներ

Հարմարության համար մենք շատ բաներ ենք գրել։ Օրինակ, կա սովորական գործառույթների մի շարք, որոնք թույլ են տալիս վիճակագրության մեջ գրել Counts, UniqueCounts արժեքները, որոնք ուղարկվում են ինչ-որ տեղ հետագա:

statlogsCountEvent   ( ‘stat_name’,            $key1, $key2, …)
statlogsUniqueCount ( ‘stat_name’, $uid,    $key1, $key2, …)
statlogsValuetEvent  ( ‘stat_name’, $value, $key1, $key2, …)

$stats = statlogsStatData($params)

Հետագայում մենք կարող ենք օգտագործել տեսակավորման և խմբավորման զտիչներ և անել այն ամենը, ինչ ցանկանում ենք վիճակագրությունից՝ կառուցել գրաֆիկներ, կարգավորել Watchdogs-ը:

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

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

ՀՏՀ VKontakte-ի ճարտարապետության և աշխատանքի վերաբերյալ

Անհրաժեշտության դեպքում մենք կարող ենք ուղղակիորեն գրել լոգեր-կոլեկցիոներներին:

ՀՏՀ VKontakte-ի ճարտարապետության և աշխատանքի վերաբերյալ

Բայց կոդից ուղղակիորեն կոլեկտորներին գրելը, շրջանցելով stas-daemom-ը, վատ մասշտաբային լուծում է, քանի որ այն մեծացնում է կոլեկցիոների բեռը: Լուծումը հարմար է միայն այն դեպքում, եթե ինչ-ինչ պատճառներով մենք չենք կարող բարձրացնել memcache stats-daemon-ը մեքենայի վրա, կամ այն ​​խափանվել է, և մենք ուղղակիորեն գնացել ենք:

Հաջորդը, տեղեկամատյաններ-հավաքիչները միաձուլում են վիճակագրությունը meowDB - սա մեր տվյալների բազան է, որը կարող է նաև պահպանել չափումները:

ՀՏՀ VKontakte-ի ճարտարապետության և աշխատանքի վերաբերյալ

Այնուհետև մենք կարող ենք կոդից կատարել երկուական «մոտ SQL» ընտրություն:

ՀՏՀ VKontakte-ի ճարտարապետության և աշխատանքի վերաբերյալ

Փորձ

2018 թվականի ամռանը մենք ունեցանք ներքին հաքաթոն, և գաղափարը ծագեց՝ փորձել փոխարինել դիագրամի կարմիր հատվածը մի բանով, որը կարող է պահել չափումները ClickHouse-ում: Մենք ունենք տեղեկամատյաններ ClickHouse-ում. ինչու չփորձել այն:

ՀՏՀ VKontakte-ի ճարտարապետության և աշխատանքի վերաբերյալ

Մենք ունեինք մի սխեմա, որը տեղեկամատյաններ էր գրում KittenHouse-ի միջոցով:

ՀՏՀ VKontakte-ի ճարտարապետության և աշխատանքի վերաբերյալ

Մենք որոշեցինք դիագրամին ավելացրեք ևս մեկ «*House»:, որը կստանա ճշգրիտ չափումներ այն ձևաչափով, երբ մեր կոդը դրանք գրում է UDP-ի միջոցով: Այնուհետև այս *House-ը դրանք վերածում է ներդիրների, ինչպես տեղեկամատյանները, որոնք KittenHouse-ը հասկանում է: Նա կարող է կատարելապես փոխանցել այս տեղեկամատյանները ClickHouse-ին, որը պետք է կարողանա կարդալ դրանք:

ՀՏՀ VKontakte-ի ճարտարապետության և աշխատանքի վերաբերյալ

Memcache, stats-daemon և logs-collectors տվյալների բազայի սխեման փոխարինվել է այսով:

ՀՏՀ VKontakte-ի ճարտարապետության և աշխատանքի վերաբերյալ

Memcache, stats-daemon և logs-collectors տվյալների բազայի սխեման փոխարինվել է այսով:

  • Այստեղ կա կոդից ուղարկում, որը գրված է տեղում StatsHouse-ում։
  • StatsHouse-ը գրում է UDP չափումներ, որոնք արդեն վերածվել են SQL ներդիրների, խմբաքանակով KittenHouse-ին:
  • KittenHouse-ը դրանք ուղարկում է ClickHouse:
  • Եթե ​​մենք ցանկանում ենք դրանք կարդալ, ապա մենք կարդում ենք դրանք՝ շրջանցելով StatsHouse-ը՝ անմիջապես ClickHouse-ից՝ օգտագործելով սովորական SQL:

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

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

Տեղակայել

Նախ, եկեք նայենք PHP-ի տեղակայմանը: Մենք զարգանում ենք գիտ: օգտագործել Գիտլաբը и TeamCity- ը տեղակայման համար։ Զարգացման ճյուղերը միաձուլվում են գլխավոր ճյուղի մեջ, վարպետից փորձարկման համար դրանք միաձուլվում են բեմականացման, իսկ բեմականացումից՝ արտադրության։

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

Մենք նաև շատ ենք տեղակայում kPHP-ն, և այն նաև ունի իր սեփական զարգացումը գիտ ըստ վերը նշված գծապատկերի: Քանի որ այս HTTP սերվեր երկուական, ապա մենք չենք կարող արտադրել տարբերություն. թողարկման երկուականը կշռում է հարյուրավոր ՄԲ: Հետևաբար, այստեղ կա ևս մեկ տարբերակ՝ տարբերակը գրված է binlog copyfast. Յուրաքանչյուր կառուցման հետ այն մեծանում է, իսկ հետադարձի ժամանակ նույնպես մեծանում է: Տարբերակ կրկնօրինակվում է սերվերներին. Տեղական copyfast-ները տեսնում են, որ նոր տարբերակ է մտել բինլոգ, և նույն բամբասանքի կրկնօրինակմամբ նրանք վերցնում են երկուականի վերջին տարբերակը՝ առանց մեր գլխավոր սերվերին հոգնեցնելու, բայց զգուշորեն բեռը տարածելով ցանցով։ Այն, ինչ հետևում է նրբագեղ վերագործարկում նոր տարբերակի համար։

Մեր շարժիչների համար, որոնք նույնպես ըստ էության երկուական են, սխեման շատ նման է.

  • git master մասնաճյուղ;
  • երկուական մեջ .deb;
  • տարբերակը գրված է binlog copyfast-ում;
  • կրկնօրինակվում է սերվերներին;
  • սերվերը դուրս է հանում թարմ .dep;
  • dpkg -i;
  • նրբագեղ վերագործարկում նոր տարբերակի համար:

Տարբերությունն այն է, որ մեր երկուականը փաթեթավորված է արխիվներում .deb, և դրանք դուրս հանելիս dpkg -i տեղադրված են համակարգի վրա: Ինչու է kPHP-ն տեղակայվում որպես երկուական, իսկ շարժիչները՝ որպես dpkg: Այդպես էլ եղավ։ Այն աշխատում է, մի դիպչեք դրան:

Օգտակար հղումներ

Ալեքսեյ Ակուլովիչը նրանցից է, ով որպես Ծրագրային հանձնաժողովի մաս օգնում է PHP Ռուսաստան մայիսի 17-ին կդառնա PHP ծրագրավորողների ամենամեծ իրադարձությունը վերջին ժամանակներում: Տեսեք, թե ինչ թույն համակարգիչ ունենք, ինչ խոսնակներ (նրանցից երկուսը մշակում են PHP միջուկը!) - կարծես մի բան է, որը դուք չեք կարող բաց թողնել, եթե գրեք PHP:

Source: www.habr.com

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