Վերագրեք VKontakte հաղորդագրությունների բազան զրոյից և գոյատևեք

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

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

Մեզ համար այս պահը եկավ մեկուկես տարի առաջ։ Ինչպես եկանք դրան և ինչ եղավ վերջում, մենք ձեզ ասում ենք հերթականությամբ:

Նախապատմությունը

Հենց առաջին ներդրման ժամանակ VKontakte-ի հաղորդագրություններն աշխատում էին PHP backend-ի և MySQL-ի համակցության վրա: Սա միանգամայն նորմալ լուծում է փոքր ուսանողական կայքի համար: Այնուամենայնիվ, այս կայքը անվերահսկելի աճեց և սկսեց պահանջել տվյալների կառուցվածքների օպտիմալացում իր համար:

2009 թվականի վերջին գրվել է առաջին տեքստային շարժիչի պահոցը, իսկ 2010 թվականին հաղորդագրություններ են փոխանցվել դրան։

Տեքստային շարժիչում հաղորդագրությունները պահվում էին ցուցակներում՝ մի տեսակ «փոստարկղեր»: Յուրաքանչյուր նման ցուցակ որոշվում է uid-ի կողմից՝ այն օգտվողը, ում պատկանում են այս բոլոր հաղորդագրությունները: Հաղորդագրությունն ունի մի շարք հատկանիշներ՝ զրուցակցի նույնացուցիչ, տեքստ, հավելվածներ և այլն: «Վանդակի» ներսում հաղորդագրության նույնացուցիչը local_id է, այն երբեք չի փոխվում և հաջորդաբար նշանակվում է նոր հաղորդագրությունների համար: «Տուփերը» անկախ են և միմյանց հետ չեն համաժամանակացվում շարժիչի ներսում, նրանց միջև հաղորդակցությունը տեղի է ունենում PHP մակարդակում: Դուք կարող եք ներսից նայել տեքստային շարժիչի տվյալների կառուցվածքին և հնարավորություններին այստեղ.
Վերագրեք VKontakte հաղորդագրությունների բազան զրոյից և գոյատևեք
Սա բավական էր երկու օգտատերերի նամակագրության համար։ Կռահեք, թե ինչ եղավ հետո:

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

«PHP, եկեք հաղորդագրություն ուղարկենք չաթին», - ասում է օգտատերը:
«Արի, {username}», - ասում է PHP-ն:
Վերագրեք VKontakte հաղորդագրությունների բազան զրոյից և գոյատևեք
Այս սխեմայի թերությունները կան. Համաժամացումը դեռևս PHP-ի պարտականությունն է: Խոշոր չաթերն ու օգտատերերը, ովքեր նրանց միաժամանակ հաղորդագրություններ են ուղարկում, վտանգավոր պատմություն են: Քանի որ տեքստային շարժիչի օրինակը կախված է uid-ից, զրույցի մասնակիցները կարող են ստանալ նույն հաղորդագրությունը տարբեր ժամանակներում: Դրանով կարելի էր ապրել, եթե առաջընթացը կանգ առներ: Բայց դա տեղի չի ունենա:

2015-ի վերջին մենք գործարկեցինք համայնքային հաղորդագրություններ, իսկ 2016-ի սկզբին մենք գործարկեցինք API նրանց համար: Համայնքներում մեծ չաթ-բոտերի հայտնվելով հնարավոր եղավ մոռանալ բեռի հավասարաչափ բաշխման մասին:

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

Հաղորդագրությունների շարժիչները 2016-ին կազմում են չաթի անդամների և անդամ-չաթերի 100 դեպք և 8000 տեքստային շարժիչներ: Դրանք տեղակայված էին հազար սերվերների վրա՝ յուրաքանչյուրը 64 ԳԲ հիշողությամբ: Որպես առաջին արտակարգ միջոց, մենք ավելացրել ենք հիշողությունը ևս 32 ԳԲ-ով: Մենք գնահատել ենք կանխատեսումները։ Առանց կտրուկ փոփոխությունների, սա կբավարարի մոտ ևս մեկ տարի։ Դուք պետք է կամ ձեռք բերեք սարքավորումները կամ օպտիմիզացնեք տվյալների բազաները:

Ճարտարապետության բնույթից ելնելով, իմաստ ունի միայն ապարատային սարքավորումները բազմապատիկ ավելացնել: Այսինքն՝ մեքենաների թվի առնվազն կրկնապատկումը՝ ակնհայտորեն, սա բավականին թանկ ճանապարհ է։ Մենք օպտիմալացնելու ենք.

Նոր հայեցակարգ

Նոր մոտեցման կենտրոնական էությունը զրուցելն է։ Զրուցարանն ունի դրան առնչվող հաղորդագրությունների ցանկ: Օգտատերը ունի չաթերի ցուցակ:

Պահանջվող նվազագույնը երկու նոր տվյալների բազա է.

  • չաթ-շարժիչ. Սա չաթի վեկտորների պահեստ է: Յուրաքանչյուր զրույց ունի հաղորդագրությունների վեկտոր, որոնք վերաբերում են դրան: Յուրաքանչյուր հաղորդագրություն զրույցի ներսում ունի տեքստ և հաղորդագրության եզակի նույնացուցիչ՝ chat_local_id:
  • օգտագործող-շարժիչ. Սա օգտվողների վեկտորների պահեստ է՝ օգտատերերի հղումներ: Յուրաքանչյուր օգտատեր ունի peer_id-ի վեկտոր (զրուցակիցներ՝ այլ օգտվողներ, բազմազրույց կամ համայնքներ) և հաղորդագրությունների վեկտոր: Յուրաքանչյուր peer_id ունի հաղորդագրությունների վեկտոր, որոնք վերաբերում են դրան: Յուրաքանչյուր հաղորդագրություն ունի chat_local_id և եզակի հաղորդագրության ID այդ օգտվողի համար՝ user_local_id:

Վերագրեք VKontakte հաղորդագրությունների բազան զրոյից և գոյատևեք
Նոր կլաստերները միմյանց հետ շփվում են TCP-ի միջոցով. սա ապահովում է, որ հարցումների հերթականությունը չի փոխվում: Հարցումները և դրանց համար հաստատումները գրանցվում են կոշտ սկավառակի վրա, այնպես որ մենք կարող ենք ցանկացած պահի վերականգնել հերթի վիճակը շարժիչի ձախողումից կամ վերագործարկումից հետո: Քանի որ օգտագործողի շարժիչը և չաթի շարժիչը յուրաքանչյուրը 4 հազար բեկոր է, կլաստերների միջև հարցումների հերթը կբաշխվի հավասարաչափ (բայց իրականում ընդհանրապես չկա, և այն շատ արագ է աշխատում):

Մեր տվյալների շտեմարաններում սկավառակի հետ աշխատելը շատ դեպքերում հիմնված է փոփոխությունների երկուական գրանցամատյանի (binlog), ստատիկ նկարների և հիշողության մեջ մասնակի պատկերի համակցության վրա: Օրվա ընթացքում կատարված փոփոխությունները գրվում են բինլոգում, և պարբերաբար ստեղծվում է ընթացիկ վիճակի պատկերը: Պատկերը մեր նպատակների համար օպտիմիզացված տվյալների կառուցվածքների հավաքածու է: Այն բաղկացած է վերնագրից (պատկերի մետաինդեքսից) և մետաֆայլերի մի շարքից։ Վերնագիրը մշտապես պահվում է RAM-ում և ցույց է տալիս, թե որտեղ կարելի է տվյալներ փնտրել նկարից: Յուրաքանչյուր մետաֆայլ ներառում է տվյալներ, որոնք, հավանաբար, անհրաժեշտ կլինեն ժամանակի փակ կետերում, օրինակ՝ կապված մեկ օգտագործողի հետ: Երբ դուք հարցում եք անում տվյալների բազայի վրա՝ օգտագործելով «snapshot» վերնագիրը, պահանջվող մետաֆայլը կարդացվում է, այնուհետև հաշվի են առնվում բինլոգի փոփոխությունները, որոնք տեղի են ունեցել լուսանկարի ստեղծումից հետո: Դուք կարող եք ավելին կարդալ այս մոտեցման առավելությունների մասին այստեղ.

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

Հաղորդագրություն ուղարկելը նոր սխեմայով ունի հետևյալ տեսքը.

  1. PHP backend-ը կապվում է օգտագործողի շարժիչի հետ՝ հաղորդագրություն ուղարկելու խնդրանքով:
  2. user-engine-ը վստահեցնում է հարցումը ցանկալի chat-engine օրինակին, որը վերադառնում է user-engine chat_local_id՝ այս չաթում նոր հաղորդագրության եզակի նույնացուցիչ: Այնուհետև chat_engine-ը հեռարձակում է հաղորդագրությունը զրույցի բոլոր հասցեատերերին:
  3. user-engine-ը ստանում է chat_local_id-ը chat-engine-ից և վերադարձնում user_local_id-ը PHP-ին՝ այս օգտվողի համար եզակի հաղորդագրության նույնացուցիչ: Այս նույնացուցիչն այնուհետև օգտագործվում է, օրինակ, API-ի միջոցով հաղորդագրությունների հետ աշխատելու համար:

Վերագրեք VKontakte հաղորդագրությունների բազան զրոյից և գոյատևեք
Բայց բացի իրականում հաղորդագրություններ ուղարկելուց, դուք պետք է իրականացնեք ևս մի քանի կարևոր բան.

  • Ենթացանկերը, օրինակ, ամենավերջին հաղորդագրություններն են, որոնք տեսնում եք զրույցների ցանկը բացելիս: Չընթերցված հաղորդագրություններ, պիտակներով հաղորդագրություններ («Կարևոր է», «Սպամ» և այլն):
  • Հաղորդագրությունների սեղմում չաթի շարժիչում
  • Հաղորդագրությունների քեշավորում օգտատիրոջ շարժիչում
  • Որոնում (բոլոր երկխոսությունների միջոցով և կոնկրետ մեկի ներսում):
  • Իրական ժամանակի թարմացում (Longpolling):
  • Պատմության պահպանում բջջային հաճախորդների վրա քեշավորումն իրականացնելու համար:

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

Հաղորդագրությունները ներառում են մեծ քանակությամբ տեղեկատվություն, հիմնականում՝ տեքստ, որն օգտակար է սեղմելու հնարավորության համար: Կարևոր է, որ մենք կարողանանք ճշգրիտ հանել նույնիսկ մեկ անհատական ​​հաղորդագրություն: Օգտագործվում է հաղորդագրությունները սեղմելու համար Հաֆմանի ալգորիթմ մեր սեփական էվրիստիկայով, օրինակ, մենք գիտենք, որ հաղորդագրություններում բառերը փոխարինվում են «ոչ բառերով»՝ բացատներով, կետադրական նշաններով, և մենք հիշում ենք նաև ռուսաց լեզվի համար սիմվոլների օգտագործման որոշ առանձնահատկություններ:

Քանի որ կան շատ ավելի քիչ օգտվողներ, քան չաթերը, պատահական մուտքի սկավառակի հարցումները չաթի շարժիչում պահելու համար մենք հաղորդագրությունները պահում ենք օգտագործողի շարժիչում:

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

Դե, բոլոր մանրամասները հաշվի են առնվել, մնում է անցնել նոր սխեմայի, և ցանկալի է՝ առանց օգտվողների դա նկատելու։

Տվյալների միգրացիա

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

Հին սխեմայի անդամ-չաթերը հիմնականում օգտագործվում էին օպտիմալացման համար: Մենք դրանից արագ փոխանցեցինք անհրաժեշտ տվյալները չաթ-անդամներին, այնուհետև նա այլևս չմասնակցեց միգրացիայի գործընթացին։

Հերթ չաթի անդամների համար: Այն ներառում է 100 դեպք, մինչդեռ չաթ-ինջինը 4 հազ. Տվյալները փոխանցելու համար անհրաժեշտ է դրանք համապատասխանեցնել. դրա համար չաթի անդամները բաժանվել են նույն 4 հազար օրինակի, այնուհետև չաթի շարժիչում միացվել է չաթի անդամների բինլոգի ընթերցումը:
Վերագրեք VKontakte հաղորդագրությունների բազան զրոյից և գոյատևեք
Այժմ chat-engine-ը գիտի chat-անդամներից բազմակի չաթի մասին, բայց դեռ ոչինչ չգիտի երկու զրուցակիցների հետ երկխոսությունների մասին: Նման երկխոսությունները տեղադրված են տեքստային շարժիչում՝ օգտատերերին հղումով: Այստեղ մենք «գլխով» վերցրեցինք տվյալները. չաթ-շարժիչի յուրաքանչյուր օրինակ հարցրեց բոլոր տեքստային շարժիչի օրինակներին, թե արդյոք նրանք ունեին անհրաժեշտ երկխոսությունը:

Հիանալի - չաթ-շարժիչը գիտի, թե ինչ բազմակի չաթեր կան և գիտի, թե ինչ երկխոսություններ կան:
Դուք պետք է համադրեք հաղորդագրությունները բազմազրույց զրույցներում, որպեսզի յուրաքանչյուր չաթում հայտնվեք հաղորդագրությունների ցանկով: Նախ, chat-engine-ը տեքստային շարժիչից առբերում է այս զրույցից օգտվողի բոլոր հաղորդագրությունները: Որոշ դեպքերում դրանք բավականին շատ են (մինչև հարյուր միլիոններ), բայց շատ հազվադեպ բացառություններով զրույցն ամբողջությամբ տեղավորվում է RAM-ի մեջ: Մենք ունենք չպատվիրված հաղորդագրություններ՝ յուրաքանչյուրը մի քանի օրինակով. ի վերջո, դրանք բոլորը վերցված են օգտվողներին համապատասխանող տեքստային շարժիչի տարբեր օրինակներից: Նպատակն է տեսակավորել հաղորդագրությունները և ազատվել ավելորդ տեղ գրավող պատճեններից:

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

Դրանից հետո multichat-ում հաղորդագրությունների մասին տվյալները ուղարկվում են օգտագործողի շարժիչին: Եվ այստեղ գալիս է ներմուծված հաղորդագրությունների տհաճ առանձնահատկությունը. Նորմալ աշխատանքի դեպքում շարժիչին հասնող հաղորդագրությունները պատվիրվում են խիստ աճման կարգով user_local_id-ի կողմից: Հին շարժիչից օգտվողի շարժիչ ներմուծված հաղորդագրությունները կորցրել են այս օգտակար հատկությունը: Միևնույն ժամանակ, թեստավորման հարմարության համար դուք պետք է կարողանաք արագ մուտք գործել դրանք, ինչ-որ բան փնտրել դրանցում և ավելացնել նորերը:

Ներմուծված հաղորդագրությունները պահելու համար մենք օգտագործում ենք տվյալների հատուկ կառուցվածք:

Այն ներկայացնում է չափի վեկտոր Վերագրեք VKontakte հաղորդագրությունների բազան զրոյից և գոյատևեքորտեղ են բոլորը Վերագրեք VKontakte հաղորդագրությունների բազան զրոյից և գոյատևեք - տարբեր են և դասավորված են նվազման կարգով, տարրերի հատուկ կարգով: Յուրաքանչյուր հատվածում ինդեքսներով Վերագրեք VKontakte հաղորդագրությունների բազան զրոյից և գոյատևեք տարրերը դասավորված են. Նման կառուցվածքում տարր փնտրելը ժամանակ է պահանջում Վերագրեք VKontakte հաղորդագրությունների բազան զրոյից և գոյատևեք միջոցով Վերագրեք VKontakte հաղորդագրությունների բազան զրոյից և գոյատևեք երկուական որոնումներ. Տարրերի ավելացումը ամորտիզացվում է Վերագրեք VKontakte հաղորդագրությունների բազան զրոյից և գոյատևեք.

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

Տվյալները գրվում են chat-անդամներին և օգտագործողի շարժիչին (և ոչ թե տեքստային շարժիչին, ինչպես սովորական շահագործման դեպքում հին սխեմայով): user-engine-ը վստահեցնում է chat-engine-ի հարցումը, և այստեղ վարքագիծը կախված է նրանից, թե արդյոք այս զրույցն արդեն միացվել է, թե ոչ: Եթե ​​չաթը դեռ միաձուլված չէ, chat-engine-ն ինքն իրեն չի գրում հաղորդագրությունը, և դրա մշակումը տեղի է ունենում միայն տեքստային շարժիչում: Եթե ​​զրույցն արդեն միացվել է chat-engine-ին, այն վերադարձնում է chat_local_id-ը օգտագործողի շարժիչին և ուղարկում հաղորդագրություն բոլոր հասցեատերերին: user-engine-ը բոլոր տվյալները փոխանցում է տեքստային շարժիչին, այնպես որ, եթե ինչ-որ բան պատահի, մենք միշտ կարողանանք հետ գլորել՝ ունենալով բոլոր ընթացիկ տվյալները հին շարժիչում: text-engine-ը վերադարձնում է user_local_id-ը, որը պահպանում է օգտագործողի շարժիչը և վերադառնում հետին պլան:
Վերագրեք VKontakte հաղորդագրությունների բազան զրոյից և գոյատևեք
Արդյունքում անցումային գործընթացն այսպիսի տեսք ունի՝ մենք միացնում ենք դատարկ օգտատեր-շարժիչ և չաթ-շարժիչ կլաստերներ: chat-engine-ը կարդում է չաթի անդամների ամբողջական բինլոգը, այնուհետև սկսվում է պրոքսիավորումը վերը նկարագրված սխեմայի համաձայն: Մենք փոխանցում ենք հին տվյալները և ստանում երկու սինխրոն կլաստերներ (հին և նոր): Մնում է միայն կարդալը տեքստային շարժիչից անցնել օգտատիրոջ շարժիչի և անջատել պրոքսին:

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

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

Տրամաբանության փոփոխություններն իսկապես հսկայական են։ Եվ ես կցանկանայի նշել, որ դա միշտ չէ, որ նշանակում է հսկայական թիմի և կոդերի անհամար տողերի զարգացման ամբողջ տարիներ: chat-engine-ը և user-engine-ը, ինչպես նաև բոլոր լրացուցիչ պատմությունները, ինչպիսիք են Huffman-ը հաղորդագրությունների սեղմման համար, Splay ծառերը և ներմուծված հաղորդագրությունների կառուցվածքը 20 հազար տողից քիչ կոդ է: Եվ դրանք գրվել են 3 ծրագրավորողների կողմից ընդամենը 10 ամսում (սակայն, արժե նկատի ունենալ բոլորը երեք մշակող - աշխարհի չեմպիոններ սպորտային ծրագրավորման մեջ).

Ավելին, սերվերների թիվը կրկնապատկելու փոխարեն մենք կրճատեցինք դրանց թիվը կիսով չափ. այժմ օգտագործողի շարժիչը և չաթ-շարժիչը գործում են 500 ֆիզիկական մեքենաների վրա, մինչդեռ նոր սխեման ունի բեռնման մեծ տարածք: Սարքավորումների վրա մեծ գումարներ ենք խնայել՝ տարեկան մոտ 5 մլն դոլար + 750 հազար դոլար գործառնական ծախսեր։

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

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

Source: www.habr.com

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