OpenAI

2 նոյեմբերի, 2026 թ.

Ճարտարագիտություն

Git-ի մասշտաբավորումը OpenAI-ում

Սկզբնաղբյուրի կառավարման համակարգի ստեղծում՝ ագենտների աշխատանքի մասշտաբներին համապատասխան, և ներդրում Git-ի էկոհամակարգում։

Հեղինակներ՝ տեխնիկական թիմի անդամներ Աարոն Ֆրիլ, Թեյլոր Բլաու և Թեդ Նայման

Բեռնվում է…

Վերջին տարում մեր մոնոպահոցի ծավալն ու դրա նկատմամբ պահանջներն աճել են ապշեցուցիչ տեմպերով։ Պարզ էր, որ պետք է վերակառուցենք սկզբնաղբյուրի կառավարման մեր համակարգը՝ Codex-ի շնորհիվ հնարավոր դարձած զուգահեռ աշխատանքի ծավալներին համապատասխանելու համար։

Մենք ստեղծեցինք Pando-ն՝ Git պահոցների նոր սերվերային համակարգը՝ առանց ինժեներական աշխատանքն ընդհատելու կամ մեր թիմի՝ Git-ից օգտվելու ձևը փոխելու։ Այժմ OpenAI-ի մոնոպահոցի ամբողջ մշակումն իրականացվում է Pando-ի միջոցով։ Pando-ն նախագծված է երկու հավակնոտ նպատակի համար․ առաջինը հորիզոնական մասշտաբավորվող գրառումներն են՝ օպտիմալացված բազմաթիվ ճյուղեր միաժամանակ ուղարկելու համար։ Երկրորդը՝ առավելագույնի հասցնել ընթերցման թողունակությունը, որպեսզի կլիենտները տվյալները ներբեռնեն այնքան արագ, որ ամբողջությամբ օգտագործեն ցանցի հասանելի թողունակությունը։

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

Այստեղ կպատմենք, թե ինչու ստեղծեցինք սկզբնաղբյուրի կառավարման նոր համակարգ և ինչու որոշեցինք պահպանել Git-ի հետ համատեղելիությունը։ Մեր համակարգը կհամեմատենք Git-ի մասշտաբավորման տարածված մոտեցումների հետ և կբացատրենք, թե ինչն է Pando-ին առանձնահատուկ դարձնում OpenAI-ի մասշտաբավորման պահանջները բավարարելու հարցում։ Կքննարկենք նաև հետագա քայլերն ու այն, թե ինչպես կշարունակենք ներդրում ունենալ Git-ում՝ ագենտների աշխատանքին բնորոշ մասշտաբները սպասարկելու համար։

Ինչու էր մեզ պետք սկզբնաղբյուրի կառավարման նոր համակարգ

Codex-ը փոխել է OpenAI-ում մշակման մասշտաբն ու տեմպը՝ ինժեներներին թույլ տալով շատ ավելի մեծ ծավալի աշխատանք կատարել զուգահեռ։ Սա նշանակում է ավելի շատ ճյուղեր, ուղարկումներ ու միավորումներ, ինչպես նաև ավելի շատ ստացումներ և կլոնավորումներ՝ մշակման միջավայրերից, հետազոտական առաջադրանքներից և CI-ից։

Այս պահանջները բազմապատկում են միմյանց ազդեցությունը։ Այժմ մեկ ինժեները միաժամանակ ունի CI-ի համար պատրաստ մի քանի փոփոխություն, իսկ յուրաքանչյուր ուղարկում կարող է գործարկել նույն կոմիտը ստացող մի քանի առաջադրանք։

Անցյալ տարվա վերջից մեր մոնոպահոցը սպասարկող համակարգերը դժվարությամբ էին հասցնում հետևել այս տեմպին։ Ստացումներն ու ուղարկումները դանդաղում էին, միավորումները՝ ձախողվում, իսկ հուսալիությունը երբեմն իջնում էր 90%-ից ցածր։ Արդյո՞ք հասել էինք հենց Git-ի, թե՞ մեր մոնոպահոցի սպասարկման եղանակի հնարավորությունների սահմանին։ Git-ը ծնվել է մի համայնքում, որն էլեկտրոնային փոստով փոխանակում էր միջուկի կարկատանները։ Ավելի քան երկու տասնամյակ մշակողները իրենց գործիքները հարմարեցրել են Git-ին՝ ծրագրերի ստեղծման եղանակների փոփոխությանը զուգընթաց։ Երբ մեր մոնոպահոցում սկսեցին դժվարություններ առաջանալ, մեզ համար կարևոր էր շարունակել հենվել այդ աշխատանքի վրա։

Մենք տեսանք ծանոթ աշխատանքային գործընթացը պահպանելու հնարավորություն՝ վերակառուցելով սերվերային համակարգը, որպեսզի այն զուգահեռ մշակի տարբեր ճյուղեր կատարվող ուղարկումները և նույն պատմությունը միաժամանակ տրամադրի բազմաթիվ ընթերցողների։ Git-ը որպես սկզբնաղբյուրի կառավարման հիմք պահելը նշանակում էր, որ կլիենտի բարելավումները կարող էին օգտակար լինել նաև OpenAI-ից դուրս։ Մենք ցանկանում էինք այդ բարելավումները մեր Git-ի պատճենից⁠(բացվում է նոր պատուհանում) փոխանցել հիմնական նախագծին՝ դրանք հասանելի դարձնելով ավելի լայն համայնքին։

Git-ի լայնածավալ աշխատանքի ինժեներական լուծումները

Սկզբնաղբյուրի կառավարման համակարգի մասշտաբավորումն ունի երկու հիմնական ուղղություն՝ բազմաթիվ գրողներ, որոնք ուղարկում են տարբեր ճյուղեր, և բազմաթիվ ընթերցողներ, որոնք ստանում են նույն պատմությունը։ Pando-ն օպտիմալացված է երկուսի համար էլ։

Նախ՝ Pando-ն յուրաքանչյուր ճյուղի թարմացումները համակարգում է անկախ մյուսներից։ Իրարից անկախ ճյուղերի թարմացումները կարող են ընթանալ զուգահեռ, իսկ ճյուղ ստացող ընթերցողը ստանում է տվյալ տարբերակի համար անհրաժեշտ պատմությունը։ Փոխզիջումն այն է, որ մի քանի ճյուղ դիտող ընթերցողը կարող է տեսնել դրանց՝ տարբեր պահերին համապատասխանող վիճակները։

Երկրորդ՝ Pando-ն ստացումների միջև վերօգտագործում է փաթեթային ֆայլերը՝ Git-ի ձևաչափը մի քանի օբյեկտ միասին սեղմելու համար, այլ ոչ թե յուրաքանչյուր կլիենտի համար ստեղծում առանձին ֆայլ։ Կլիենտը կարող է ներբեռնել որոշ օբյեկտներ, որոնք արդեն ունի, բայց սերվերը կարող է նույն բայթերը տրամադրել բազմաթիվ կլիենտների՝ քիչ հաշվարկներով։

Այս ընտրությունները թույլ են տալիս մասշտաբավորել գրառումները տարբեր ճյուղերում և ընթերցումները սպասարկել քեշերից։ Հասկանալու համար, թե ինչպես են դրանք համատեղ աշխատում, սկսենք նրանից, թե ինչպես է Git-ը պահում և փոխանցում պատմությունը։

Git-ում օբյեկտների պահպանման հիմունքները

Git-ը պետք է կարողանա համաժամեցված պահել պահոցի երկու մասերը՝ օբյեկտները և հղումները։

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

Օբյեկտները նույնականացվում են իրենց տեսակի և բովանդակության հեշով։ Օբյեկտները նաև անփոփոխ են․ փոփոխված ֆայլը գրանցելիս ստեղծվում է նոր բլոբ, իսկ չփոփոխված ֆայլերն ու գրացուցակները կարող են վերօգտագործել առկա օբյեկտները։

Ճյուղերն ու պիտակները կոմիտները մատնանշող հղումներ են, որոնք կոչվում են նաև «refs»։ Ճյուղում կոմիտ կատարելիս ստեղծվում է նոր կոմիտ, և ճյուղի հղումը թարմացվում է՝ այն մատնանշելու համար։

refs/heads/main ճյուղը մատնանշում է C2 քոմիթը, որի ծնողը C1-ն է։ C1-ը մատնանշում է T1 արմատային ծառը, որտեղ parser.py-ն հղվում է B1 բլոբին։ C2-ը մատնանշում է T2 արմատային ծառը, որտեղ parser.py-ն հղվում է B2 բլոբին։ Երկու արմատային ծառերում էլ docs/-ը հղվում է նույն՝ T3 ծառին։ Դրա README.md գրառումը մատնանշում է B3 բլոբը, իսկ usage.md-ն՝ B4 բլոբը։

Git-ի օբյեկտները միմյանց հղվում են ID-ներով․ քոմիթները՝ ծառերին, իսկ ծառերը՝ այլ ծառերի և բլոբների։ refs/heads/main ճյուղը մատնանշում է C2 քոմիթը, որի ծնողը C1-ն է։ C1-ը մատնանշում է T1 արմատային ծառը, որտեղ parser.py-ն հղվում է B1 բլոբին։ C2-ը մատնանշում է T2 արմատային ծառը, որտեղ parser.py-ն հղվում է B2 բլոբին։ Երկու արմատային ծառերում էլ docs/-ը հղվում է նույն՝ T3 ծառին։ Դրա README.md գրառումը մատնանշում է B3 բլոբը, իսկ usage.md-ն՝ B4 բլոբը։

Git-ը օբյեկտները պահում է «առանձին» կամ «փաթեթավորված» վիճակում։ Առանձին օբյեկտները պահվում են առանձին ֆայլերում, որոնք նույնականացվում են օբյեկտի ID-ով։ Փաթեթավորված օբյեկտները միասին պահվում են փաթեթային ֆայլում, ինչը թույլ է տալիս նման օբյեկտները պահել որպես միմյանց նկատմամբ տարբերություններ։

$GIT_DIR/objects-ում ցուցադրված է parser.py-ի երկու տարբերակ։ Առանձին օբյեկտների դեպքում A բլոբը պարունակում է parse(), իսկ B բլոբը՝ և՛ parse(), և՛ parse_file()։ Փաթեթային ֆայլը պահում է A-ն ամբողջությամբ, իսկ B-ն ներկայացնում է որպես A-ն ամբողջությամբ պատճենելու և parse_file()-ն ավելացնելու հրահանգներ։ Ուղեկցող *.idx ֆայլը օբյեկտների ID-ներով որոշում է երկու բլոբների դիրքերը փաթեթային ֆայլում։

Git-ը կարող է բլոբները պահել առանձին ֆայլերում կամ փաթեթավորել միասին՝ մի բլոբը կոդավորելով որպես մյուսի նկատմամբ տարբերություն։

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

Ուղարկումը օբյեկտները փոխանցում է հակառակ ուղղությամբ՝ սերվերից պահանջելով թարմացնել մեկ կամ մի քանի հղում։ Կլիենտն օգտագործում է սերվերի հայտարարած հղումների հավաքածուն՝ սերվերում արդեն առկա օբյեկտները չուղարկելու համար։ Հետևաբար ուղարկվող փաթեթը կարող է կախված լինել առկա օբյեկտներից․ միայն փաթեթը ստանալը բավարար չէ նոր պատմությունը վերականգնելու համար։

Git պահոցի կրկնօրինակումը նշանակում է թե՛ օբյեկտները, թե՛ հղումները հասանելի պահել մի քանի սերվերներում։ Մինչև կրկնօրինակը կարողանա տրամադրել հղման նոր արժեքը, այն պետք է կարողանա տրամադրել այդ արժեքից հասանելի օբյեկտները։ Ծառայությունը պետք է նաև համակարգի մրցակցող հղումների թարմացումները՝ ուղարկումները, որոնք փորձում են նույն ճյուղը նույն հին վերջնակետից տեղափոխել տարբեր նոր քոմիթներ։ Պահոցի բոլոր գրառումների համար միասնական հերթականություն պարտադրող համակարգերի դեպքում իրարից անկախ ճյուղերին կատարվող ուղարկումները կարող են ստիպված լինել սպասել միմյանց։

Բաշխված Git ծառայությունների առկա կառուցվածքները

Pando-ն նախագծելիս գնահատեցինք Git-ով սկզբնաղբյուրի կառավարման մասշտաբավորման ընդունված մոտեցումները։ Մեկը պահոցի կրկնօրինակների հղումների թարմացումները համակարգում է եռափուլ հաստատմամբ (3PC՝ մի քանի հանգույցներում հաստատումը համակարգող արձանագրություն), մյուսը թարմացումները հերթագրում է բլոբների պահեստում գտնվող ընդհանուր նախնական գրառման մատյանով (WAL՝ փոփոխությունների գրանցում մինչև դրանց կիրառումը)։

Եռափուլ հաստատում (3PC)

Մեր մոդելավորած եռափուլ հաստատման կառուցվածքում Git ծառայությունը մի քանի կրկնօրինակ հանգույցներում պահում է պահոցի ամբողջական պատճենը։ Երբ որևէ սերվեր ընդունում է ուղարկում, մուտքային փաթեթային ֆայլը պատճենվում և զուգահեռ ուղարկվում է բոլոր կրկնօրինակներին։ Ուղարկումը հրապարակելու համար կրկնօրինակների մեծամասնությունը պետք է ընդունի հղման թարմացումը։ Սա կառավարող սերվերը համակարգողն է․ գործընթացը պահանջում է համակարգողի և մյուս յուրաքանչյուր կրկնօրինակի միջև հաղորդակցության մի քանի փուլ։

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

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

Քվորումին սպասելու պատճառով կրկնօրինակների սկավառակների արտադրողականությունն ու հաղորդակցության ուշացումն ազդում են ուղարկման տևողության վրա։ Գրառումների ծավալի աճին զուգընթաց կրկնօրինակները պետք է հասցնեն մշակել թե՛ մուտքային փաթեթները, թե՛ ընթերցման թրաֆիկը։

Նախնական գրառման մատյան (WAL)

Մեր մոդելավորած WAL-ի վրա հիմնված կառուցվածքում Git ծառայությունը բլոբների պահեստում օգտագործում է ընդհանուր մանիֆեստ՝ ամբողջ պահոցի թարմացումները հերթագրելու համար։ Ուղարկում ընդունելիս սերվերը մուտքային փաթեթային ֆայլը վերբեռնում է բլոբների պահեստ և հղման թարմացումը պատրաստում պահոցի իր տեղային պատճենում։ Ուղարկումը հրապարակելու համար բլոբների պահեստում գտնվող ընդհանուր մանիֆեստին ավելացնում է գրառում, որն արձանագրում է հղման թարմացումը և մատնանշում փաթեթային ֆայլը։ Այնուհետև Git սերվերը թարմացնում է մանիֆեստը համեմատման և փոխարինման գործողությամբ։ Այն ատոմային ձևով փոխարինում է մանիֆեստը կամ մերժում փոփոխությունը։ Եթե այդ ընթացքում մեկ այլ գրող թարմացրել է այն, սերվերը կարդում է միջանկյալ գրառումները, ստուգում, որ իր հղման թարմացումը դեռ վավեր է, և կրկին փորձում՝ օգտագործելով արդեն վերբեռնած փաթեթային ֆայլը։

Գրողները կարող են իրենց փաթեթային ֆայլերը վերբեռնել զուգահեռ, բայց նույնիսկ իրարից անկախ ճյուղեր ուղարկելիս պետք է թարմացնել նույն մանիֆեստը։ Համեմատման և փոխարինման հաջող գործողության շրջափուլի տևողությունը սահմանափակում է պահոցի՝ նոր մանիֆեստ հրապարակելու հաճախականությունը։ Ցածր ուշացմամբ բլոբների պահեստն արագացնում է այս քայլը։ Խմբավորումը թույլ է տալիս մեկ մանիֆեստով միաժամանակ թարմացնել մի քանի հղում, բայց թարմացումները հերթի մեջ են կուտակվում, և ուշացումն աճում է։

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

Pando-ի ճարտարապետությունը

Այստեղ էլ անցնում ենք Pando-ին։ Pando-ն Git պահոցների սպասարկման նոր ճարտարապետություն է՝ բազմաթիվ կլիենտների միաժամանակյա ուղարկումների ծավալներին համապատասխան մասշտաբավորվելու նպատակով։ Ահա թե ինչպես է այն աշխատում․

Սահմանափակումների վերանայում

Մինչ Pando-ի մշակումը ենթադրում էինք, որ կարող ենք բավարարել մեր պահանջները՝ առանց Git-ից հրաժարվելու, բայց ստիպված էինք զիջումներ անել որոշ հարցերում, որոնք Git համակարգերի մեծ մասը պարտադիր պահանջ է համարում․

  • Համաձայնեցվածություն ամբողջ պահոցում․ Բոլոր հղումների՝ ժամանակի նույն պահին համապատասխանող համաձայնեցված պատկերը տրամադրելու համար անհրաժեշտ է համակարգում ամբողջ պահոցում։ Եթե համակարգը բոլոր հղումների թարմացումները դասավորում է մեկ ընդհանուր հերթականությամբ, իրարից անկախ ճյուղերին կատարվող ուղարկումները մրցակցում են համակարգման մեկ կետում։

  • Առանձին փաթեթային ֆայլեր յուրաքանչյուր կլիենտի համար․ Եթե տարբեր տեղային պատմություններ ունեցող երկու կլիենտ ստանում են նույն ճյուղը, սերվերը կարող է ստիպված լինել յուրաքանչյուրի համար առանձին փաթեթ ստեղծել՝ արդեն առկա օբյեկտները չուղարկելու համար։ Այս պատասխանների ստեղծումը ծախսում է պրոցեսորի և սկավառակի մուտք/ելքի ռեսուրսները՝ դժվարացնելով մեծ թվով ընթերցող կլիենտների սպասարկումը։

Փոխարենը Pando-ն գրառումների մասշտաբավորման համար տրամադրում է ավելի մեղմ համաձայնեցվածության մոդել (պատճառահետևանքային համաձայնեցվածություն), իսկ ընթերցումների մասշտաբավորման համար վերօգտագործում է փաթեթային ֆայլերը։

Պատճառահետևանքային համաձայնեցվածություն (CC)

Երբ կլիենտն ուղարկում է տվյալներ ճյուղ, Pando-ն մուտքային փաթեթային ֆայլը պահում է բլոբների պահեստում՝ որպես անփոփոխ բլոբ։ Ճյուղի յուրաքանչյուր առաջխաղացման ժամանակ Pando-ն մետատվյալների պահեստում գրանցում է հղման տարբերակ՝ ներառելով նոր վերջնակետը, այն տրամադրած փաթեթը և հղումների բոլոր նախորդ տարբերակները, որոնցից կախված է փաթեթը։ Ինչպես բլոբների, այնպես էլ մետատվյալների պահեստները հորիզոնական մասշտաբավորվող են։

Pando-ից քոմիթ կամ հղում ստանալու համար անհրաժեշտ է կլիենտի մոտ վերարտադրել հղումների տարբերակների հավաքածուն (փաթեթային ֆայլերը)՝ վերականգնելով պահանջվող հղման տարբերակը ստեղծած կլիենտի վիճակը։ Սա ամբողջ պահոցում ապահովում է համաձայնեցվածության ավելի թույլ ձև, բայց առանձին հղումների թարմացումների համար երաշխավորում է հաջորդական կատարմանը համարժեք արդյունք։ Կլիենտները բախվում են միայն նույն հղմանը միաժամանակ ուղարկելիս։ Մի քանի ճյուղ կարդացող կլիենտը չի կարող ենթադրել, որ այդ ընթերցումները նկարագրում են պահոցի վիճակը ժամանակի նույն պահին։

Ձախում հիմնական ճյուղի երեք հաջորդական փաթեթները պարունակում են համապատասխանաբար A, B և C, D և E, ապա F քոմիթները։ Աջում հիմնական և թեմատիկ ճյուղերը բաժանվում են C կետում։ Հիմնական ճյուղը հասնում է G-ին, իսկ թեմատիկը՝ անցնում D, E և F քոմիթներով։ Թեմատիկ ճյուղի վերջին փաթեթը պարունակում է D, E և F քոմիթները։ Կետագծով եզրագիծը ցույց է տալիս, որ D-ն և E-ն առկա են նաև թեմատիկ ճյուղի նախորդ փաթեթում։ Կապույտ սլաքը նշում է նոր փաթեթի կախվածությունը հիմնական ճյուղի G կետից։ Git-ում F-ի ծնողը E-ն է։

Հիմնական ճյուղ ուղարկելիս ավելացվում է մեկ կամ մի քանի քոմիթ պարունակող հավելաճային փաթեթ։ Կողային ճյուղ կատարվող յուրաքանչյուր ուղարկում կրկին ներառում է թեմատիկ ճյուղի նախորդ քոմիթները, որպեսզի հիմնական ճյուղի հայտարարված տարբերակն ունեցող կլիենտը կարողանա թեմատիկ ճյուղը ստանալ մեկ փաթեթով։

Սա պատճառահետևանքային համաձայնեցվածության ձև է։ Հղումը ստանալու համար ընթերցողը տեսնում է այն ստեղծած գրող կլիենտի պատմությունը։ Ուղարկման ժամանակ Pando-ն վերահսկում է, թե կլիենտն ու սերվերը որ ընդհանուր պատմության շուրջ են համաձայնության գալիս, որպեսզի կլիենտները ստեղծեն ավելի հեշտ վերօգտագործվող փաթեթային ֆայլեր։

Հետևաբար, Git գործողությունների ժամանակ Pando-ն չի տրամադրում բոլոր հղումների՝ ժամանակի մեկ պահին համապատասխանող վիճակը կամ կլոնավորման կամ ստացման շրջանակում հղումների թարմացումների միասնական հերթականություն։ Օրինակ՝ ենթադրենք, որ ամբողջական կլոնավորման համաձայնեցման ընթացքում թարմացվում են և՛ foo, և՛ bar ճյուղերը։ Համաձայնեցման ընթացքում մի կլիենտը կարող է տեսնել foo-ի 1-ին և bar-ի 2-րդ տարբերակները, իսկ մյուսը՝ foo-ի 2-րդ և bar-ի 1-ին տարբերակները։ Գործնականում օգտատերերի և ագենտների համար կարևոր չէ հղումների թարմացումների գլոբալ հերթականությունը․ նրանք ապավինում են առանձին հղման թարմացումների հերթականությանը։

Մոտեցումների համեմատություն

Համաձայնեցվածության երեք մոդելների այս սիմուլյացիայում 1 000 կլիենտից յուրաքանչյուրը ընտրում է առանձին ճյուղ և բազմիցս ուղարկում եզակի քոմիթներ։ Մենք չափում ենք ընդհանուր անցած ժամանակը և ուղարկումից մինչև ստացում ուշացումը։ Վերջինս աշխատանքային ծանրաբեռնվածության կարևոր ցուցանիշ է․ այն չափում է օգտատերերի ու ագենտների համագործակցության կամ տարբերակների կառավարման վրա հիմնված այլ համակարգերի օգտագործման ամբողջ շրջափուլի ժամանակը։ Սիմուլյացիան մոդելավորում է սարքավորումներ՝ սովորականից մինչև բարձրակարգ վիրտուալ մեքենաներ և բլոբների պահեստավորման համակարգեր։ Այս սիմուլյացիայում եռափուլ հաստատման համար մեղմացրել ենք ամբողջ պահոցի համաձայնեցվածության պահանջը։

Simulating Git Server Implementations

Follow each writer through repeated pushes, and separately measure when an independent reader can check out each commit.

Three-phase commit

Ready
Simulated time
0 s
Mean push to fetch
—
Writers done
0 / 1,000

Each square represents one writer. All selected architectures run the same workload. Squares lighten as pushes are acknowledged and turn blue when a writer finishes. The chart shows writers finished over simulated time; independent readers can continue fetching afterward. Use arrow keys to select a writer, Home or End to jump, and Escape to clear.

0 / 10,000 pushes acknowledged · 0 fetched

Select a square to inspect that writer.

Object-store WAL

Ready
Simulated time
0 s
Mean push to fetch
—
Writers done
0 / 1,000

Each square represents one writer. All selected architectures run the same workload. Squares lighten as pushes are acknowledged and turn blue when a writer finishes. The chart shows writers finished over simulated time; independent readers can continue fetching afterward. Use arrow keys to select a writer, Home or End to jump, and Escape to clear.

0 / 10,000 pushes acknowledged · 0 fetched

Select a square to inspect that writer.

Pando

Ready
Simulated time
0 s
Mean push to fetch
—
Writers done
0 / 1,000

Each square represents one writer. All selected architectures run the same workload. Squares lighten as pushes are acknowledged and turn blue when a writer finishes. The chart shows writers finished over simulated time; independent readers can continue fetching afterward. Use arrow keys to select a writer, Home or End to jump, and Escape to clear.

0 / 10,000 pushes acknowledged · 0 fetched

Select a square to inspect that writer.

Writer progress through verified fetches

  • Three-phase commit
  • Object-store WAL
  • Pando
05001,00000 s
  • Waiting
  • Pushing
  • All pushes acknowledged
0 sLater

Synthetic teaching models, not production benchmarks. Mean push to fetch covers topic pushes, from the first attempt through retries until an independent reader verifies that commit. It includes waiting for a reader slot and excludes builds and tests. With merges enabled, writer completion includes the required fetches and trunk merge.

Experiment settings

Preparing simulation…

Results

Play the comparison to see the recorded results.

Synthetic teaching models, not production benchmarks. Mean push to fetch covers topic pushes, from the first attempt through retries until an independent reader verifies that commit. It includes waiting for a reader slot and excludes builds and tests. With merges enabled, writer completion includes the required fetches and trunk merge.

Գործարկեք այս սիմուլյացիան՝ Pando-ն երկու այլ մոտեցումների հետ համեմատելու համար։ Ընտրեք ենթակառուցվածքը՝ սովորականից մինչև բարձրակարգ սարքավորումներ, կլիենտների թիվը և այլ կարգավորումներ՝ արդյունքները համեմատելու համար։

Մոդելավորված եռափուլ հաստատման համակարգում ծանրաբեռնվածության տակ գրառման ուշացումը զգալիորեն մեծանում է, երբ սկավառակների հնարավորությունները սպառվում են։ Նույն պատճառով նախնական գրառման մատյանի վրա հիմնված համակարգերում զգալիորեն աճում է ընթերցման ուշացումը․ սերվերները չեն հասցնում կարդալ մատյանը։ Ինչպես մեր մոնոպահոցի իրական փորձարկումներում, այնպես էլ այս սիմուլյացիայում Pando-ն սպասարկում է հազարավոր կլիենտների միաժամանակյա ուղարկումները՝ առանց ծանրաբեռնվածության տակ արտադրողականության անկման։

Ուղարկումը մշակելիս Pando-ն ստուգում է մուտքային փաթեթային ֆայլը և միաժամանակ հոսքային ձևով փոխանցում բլոբների պահեստ՝ առանց այն տեղային պահոցում ապափաթեթավորելու։ Երբ կլիենտը սկսում է ստացումը, Pando-ն ընտրում է նրան անհրաժեշտ պահպանված փաթեթները, իսկ կլիենտը ներբեռնում է դրանք։ Ոչ մի սերվեր ստիպված չէ փաթեթային ֆայլերը կիրառել տեղային պահոցում կամ կատարել ռեսուրսատար ապափաթեթավորում և փաթեթավորում։ Քանի որ այս սերվերները հիմնականում կատարում են համաձայնեցում և փաթեթային ֆայլերի ընտրություն, Pando-ի սերվերները կարող են աշխատել սովորական սարքավորումներով։

Սա թույլ է տալիս Pando-ն մասշտաբավորել մինչև կլիենտների, կլիենտների և Pando-ի միջև ցանցի, ինչպես նաև բլոբների պահեստավորման ծառայության հնարավորությունների սահմանը։ Բավարար հզորության դեպքում անկախ ճյուղերում աշխատող կլիենտներից յուրաքանչյուրը կարող է փաթեթները փոխանցել իր կապի առավելագույն արագությամբ։ Այդ արագությամբ ավելի շատ կլիենտներ սպասարկելու համար կարող ենք ավելացնել Pando-ի սերվերներ և դրանց հետ մեկտեղ մասշտաբավորել մետատվյալների ու բլոբների պահեստները։

Pushing and Fetching a Branch in Pando

Pando stores the writer’s packfile in blob storage and records the ref version in metadata service. On fetch, Pando selects the packs the reader needs, and Express serves them.

Stream the push

  • Packfile bytes
  • Metadata
  • Request / acknowledgment
  • Packfile URIs

Ագենտը տեղային միջավայրում խմբագրում է ֆայլերը, ստեղծում քոմիթ և գործարկում git push-ը, որը ճյուղը թարմացնելու համար այդ փոփոխություններից ստեղծում է փաթեթային ֆայլ։ Pando-ն ընդունում է փաթեթը և հոսքային ձևով փոխանցում բլոբների պահեստ։ Մուտքային ուղարկումը մեկ անցումով վերծանելու և ստուգելուց հետո Pando-ն բազմաբանալի տրանզակցիայով մեր մետատվյալների պահեստում գրանցում է հղման տարբերակը և ատոմային ձևով թարմացնում հղման ցուցիչը։ Սա թույլ է տալիս Pando-ին ապահովել «կարդա քո գրածը» համաձայնեցվածությունը։ Գրառման այս ամբողջ գործողությունը պահանջում է O(1)O(1) մետատվյալների ընթերցում և գրառում։

Երբ մեկ այլ կլիենտ ստանում է ճյուղը, Pando-ն ընտրում է պահպանված փաթեթների հավաքածու՝ հաշվի առնելով կլիենտի արդեն ունեցած պատմությունը։ Այս գործողությունը պահանջում է O(log⁡Δ)O(\log \Delta) մետատվյալների ընթերցում, որտեղ Δ\Delta-ն կլիենտի ունեցածի և պահանջածի միջև ամենակարճ հեռավորությունն է՝ հղումների տարբերակներով։ Սերվերը վերադարձնում է փաթեթային ֆայլերի URI-ները, իսկ կլիենտը դրանք ներբեռնում է Express ծառայության միջոցով, որը փաթեթային ֆայլերը պահում է տարածաշրջանային քեշերում։

Այս կառուցվածքը հիմնվում է Pando-ի ճարտարապետության երեք հիմնական ծառայությունների վրա՝ ուղարկումներ, ստացումներ և խտացում։

Ուղարկումների մասշտաբավորում

Երբ կլիենտն ուղարկում է տվյալները, սովորական Git սերվերը նման է իր բոլոր խաղաքարտերը բացող պոկեր խաղացողի․ այն կլիենտին ցույց է տալիս իր բոլոր ճյուղերը։ Այնուհետև կլիենտը հավաքում է քոմիթները, ծառերն ու բլոբները՝ ստեղծելով փաթեթային ֆայլ, որը բացառում է այն օբյեկտները, որոնք, իր տեղեկությամբ, սերվերն արդեն ունի։

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

Pando-ն այլ մոտեցում է կիրառում։ Բոլոր խաղաքարտերը բացելու փոխարեն այն կլիենտին հայտարարում է միայն ընտրված ճյուղերի հավաքածուն։ Դրա համար կա երկու պատճառ․

  1. Բոլոր հղումների համաձայնեցված պատկերը տրամադրելը ծախսատար է։ Միլիոնավոր ճյուղերի դեպքում միայն հղումների հայտարարումը կարող է գերազանցել 100 MiB-ը։ Դրա համար յուրաքանչյուր սերվեր պետք է կամ պահի արդիական համապատասխանեցում՝ համակարգման զգալի հավելյալ ծախսերով, կամ կատարի տվյալների բազայի հարցում, որի ծավալն աճում է հղումների թվին համաչափ։

  2. Կլիենտին տրամադրելով միայն հղումների ենթաբազմություն՝ ապահովում ենք, որ նրա ստեղծած փաթեթը կախված լինի միայն այն օբյեկտներից, որոնք սերվերը բացահայտ թույլ է տալիս բացառել։ Կախվածություններին հետևելը Pando-ին թույլ է տալիս մեկ ուղարկման ժամանակ կլիենտի ստեղծած փաթեթային ֆայլը վերօգտագործել՝ տրամադրելով այն որպես հետագա ստացման պատասխան։

Որքան շատ հղումներ է հայտարարում Git սերվերը, այնքան շատ աղբյուրներից կարող են ուղարկող կլիենտները բացառել օբյեկտները՝ ստեղծելով ավելի փոքր փաթեթներ։ Սակայն այս փաթեթային ֆայլերը վերօգտագործելու համար սերվերը պետք է կարողանա հաստատել, որ ստացող կլիենտներն ունեն բոլոր կախվածությունները։ Հակառակ դեպքում փաթեթային ֆայլը կարող է չներառել կլիենտին անհրաժեշտ օբյեկտներ։

Մյուս կողմից, եթե Git սերվերը ոչ մի հղում չհայտարարի, կլիենտը կստեղծի պահոցի ամբողջ պատմությունը պարունակող փաթեթային ֆայլ։ Այդ ֆայլը կարող է օգտագործել ցանկացած այլ կլիենտ, բայց զգալի գնով․ ցանկացած ճյուղի ստացումն ըստ էության կդառնա ամբողջական կլոնավորում։

Կոր, որը ցույց է տալիս հայտարարված հղումների ազդեցությունը փաթեթային ֆայլի չափի վրա․ առանց հղումներ հայտարարելու՝ ամբողջ պատմությունը, միայն հիմնական ճյուղը հայտարարելիս՝ դրա մի մասը, իսկ բոլոր հղումները հայտարարելիս՝ միայն նոր օբյեկտները։

Ավելի շատ հղումներ հայտարարելիս փաթեթային ֆայլերը փոքրանում են։ Չափի կրճատման մեծ մասը կարելի է ստանալ՝ հայտարարելով ընդամենը մեկ հղում։

Ըստ կանխադրման, երբ կլիենտն ուղարկում է նոր ֆունկցիոնալության ճյուղ, Pando-ն որպես հիմք հայտարարում է միայն նախապես ընտրված հիմնական ճյուղը։ Այսպես հայտարարության չափը չի փոխվում պահոցում ճյուղերի ավելացման հետ, բայց դա փոխզիջումներ է պահանջում։ Երբ ինժեները բազմիցս ուղարկում է նույն ճյուղը կամ մի ֆունկցիոնալության ճյուղը կառուցում մյուսի վրա, կլիենտը պետք է նորից ուղարկի հիմնական ճյուղից դուրս գտնվող ամեն ինչ։

Դրա պատճառով ճյուղի հաջորդական ուղարկումները մեծանում են՝ ներառելով հնարավոր կրկնվող օբյեկտներ և օգտագործելով կլիենտի ցանցի լրացուցիչ թողունակությունը։ Մեր մոնոպահոցում այս եղանակով ստեղծված փաթեթային ֆայլի մեդիանային չափը 20 KiB-ից փոքր էր, իսկ 99-րդ պերսենտիլը՝ 3 MiB-ից փոքր։ Մեզ համար սա ողջամիտ փոխզիջում էր, քանի որ հայտարարված հիմնական ճյուղի պատմությունն արդեն ունեցող ընթերցողը կարող է ճյուղը ստանալ այդ մեկ փաթեթային ֆայլով։

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

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

Կարևորն այն է, որ Pando-ի սերվերները կարող են անկախ ընդունել իրար հետ չկապված հղումներին կատարվող ուղարկումները։ Միակ բանալին, որի համար մրցակցություն է առաջանում, հղման ցուցիչն է․ այն պաշտպանում ենք համեմատման և փոխարինման նման ատոմային գործողությամբ։ Գրառման թողունակությունը կարող ենք մեծացնել՝ ավելացնելով Pando-ի սերվերներ, մետատվյալների պահեստի մասշտաբավորման միավորներ կամ բլոբների պահեստներ։

Ստացում և կլոնավորում՝ կապի առավելագույն արագությամբ

Ստացում կատարելիս կլիենտը սերվերին տրամադրում է քոմիթների ID-ների երկու հավաքածու, որոնք արձանագրությունում կոչվում են have-եր և want-եր։ Սովորական Git սերվերը հաշվարկում է առկա և պահանջվող քոմիթներից հասանելի օբյեկտների բազմությունների տարբերությունը, սեղմում այն և արդյունքն ուղարկում կլիենտին։ Թեև Git-ի բաց կոդով սերվերն այս գործողությունն արագացնելու համար ունի տարբեր տեղային ինդեքսներ, այս փաթեթային ֆայլերի հաշվարկը կարող է ծախսատար լինել, և դրանք սովորաբար դժվար է քեշավորել։

Փոխարենը Pando-ն ուղարկումների ընթացքում գրանցված քոմիթների համապատասխանեցումներով գտնում է կլիենտի have-երը և want-երը՝ որոշելով դրանք պարունակող հղումների տարբերակների հավաքածուն։ Այդ հղումների տարբերակներից յուրաքանչյուրը կապված է Pando-ի նախկինում ստացած փաթեթային ֆայլի հետ։ Սերվերն այս տեղեկությամբ որոշում է կլիենտի կարիքները՝ ընտրելով անհրաժեշտ օբյեկտների հավաքածուն պարունակող փաթեթային ֆայլերը։

Planning fetches in Pando

Pando compares what a client has with what it wants, then selects the stored packfiles needed—including any missing branch dependencies.

Already heldFetchMissing branch dependency

Fetch 27 trunk packs.

Select a branch to include its trunk dependencies.

Pando-ն Git արձանագրության առկա և պահանջվող քոմիթները համապատասխանեցնում է հղումների տարբերակների հաջորդականությանը։ Կողային ճյուղը պահանջելը ենթադրում է նաև հիմնական ճյուղի պատմության պահանջ՝ մինչև այդ ճյուղի կախվածությունները ներառյալ։

Git արձանագրությունը կլոնավորման կամ ստացման HTTP պատասխանում թույլ է տալիս ուղարկել միայն մեկ փաթեթային ֆայլ։ Սակայն Git արձանագրության թերագնահատված հնարավորություններից մեկը՝ packfile-uri-ն, սերվերին թույլ է տալիս վերադարձնել լրացուցիչ փաթեթներն առանձին ներբեռնելու հղումներ։ Pando-ն օգտագործում է բացառապես այս եղանակը և անմիջական պատասխանում փոխանցում դատարկ փաթեթային ֆայլ։ Այս հնարավորությունն ապահովելու համար OpenAI-ը հիմնական նախագծին փոխանցել է packfile-uri-ի մի շարք բարելավումներ։

OpenAI-ի համակարգերն աշխատում են բազմաթիվ աշխարհագրական տարածաշրջաններում, ուստի յուրաքանչյուրում պահում ենք Pando-ի կլաստերներ՝ տեղային քեշերով։ Փաթեթների առաքման Express ծառայությունը քեշավորում է մեր բլոբների պահեստը, իսկ մեկ այլ ծառայություն՝ մետատվյալների պահեստը։ Այս քեշերը Pando-ին թույլ են տալիս քոմիթի ID-ի հարցումները կամ հղման հատուկ ընթերցումն ամբողջությամբ սպասարկել տվյալ կլաստերի քեշավորված վիճակից։ Փաթեթային ֆայլերի հարցումները Express սերվերներին ուղղորդելու համար օգտագործում ենք համաձայնեցված հեշավորում, որի դեպքում հարցումների ավելի քան 99%-ը սպասարկվում է քեշից։

Քեշերի այս համակարգն ապահովում է չափազանց բարձր թողունակություն՝ ամբողջությամբ օգտագործելով կլիենտների և Pando-ի միջև ցանցի հնարավորությունները։ Օգտագործելով այս փաթեթային ֆայլերի URI-ներն ու տեղային քեշերը՝ հաստատել ենք, որ նույնիսկ ամպային մատակարարի սովորական վիրտուալ մեքենաներով կլոնավորումն ու ստացումն ամբողջությամբ օգտագործում են 10 Գբիթ/վ ցանցային կապերը։

Խտացում և մինչև առաջին բայթը ստանալու ժամանակը

Git սերվերների մեծ մասում վերափաթեթավորումն ու աղբահանությունն անհրաժեշտ են աճող պահոցի արտադրողականությունը պահպանելու համար։ Երկուսն էլ ազատում են տարածք, բայց պահանջում են մեծ հաշվարկային և մուտք/ելքի ռեսուրսներ։

OpenAI-ի մոնոպահոցի պես արագ փոփոխվող պահոցում գործնական չէ վերջին ստացումից հետո կատարված յուրաքանչյուր ուղարկման համար առանձին փաթեթային ֆայլի URI ուղարկելը։ Հիմնական ճյուղը թարմացնելու համար կլիենտն ամեն օր ստիպված կլիներ ներբեռնել տասնյակ հազարավոր փաթեթային ֆայլեր։

Փոխարենը Pando-ն ֆոնային ռեժիմում միավորում է փաթեթները՝ նվազեցնելով այս հավելյալ ծախսերը։ Դրա կառուցվածքը նման է մատյանահեն միավորման ծառերում կիրառվող խտացմանը։ Յուրաքանչյուր ուղարկում ստեղծում է փաթեթային ֆայլ, որը Pando-ն անվանում է «L0»․ սա Pando-ի փոխանցելիք տվյալների ամենափոքր միավորն է։ Ժամանակի ընթացքում ֆոնային մշակիչներն այս ֆայլերը հավաքում են հղումների տարբերակների հաջորդականություններ ընդգրկող խմբերի մեջ, որոնց չափը L0-ից սկսած աճում է երկրաչափական պրոգրեսիայով։ Այսօր մեր մոնոպահոցն օգտագործում է փաթեթային ֆայլերի ընդգրկող խմբեր՝ մինչև L4 մակարդակը։

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

Compaction in Pando

Small packfiles are grouped into larger covers across levels, improving compression and speeding up fetches.

Compaction in progressPublished cover

Խտացումը ֆոնային ռեժիմում միավորում է հղումների բազմաթիվ տարբերակների փաթեթային ֆայլերը՝ ապահովելով ավելի արդյունավետ ստացում՝ ավելի քիչ ֆայլերով։

Ի տարբերություն Git-ի բազմաթիվ սերվերների՝ փաթեթային ֆայլերը պահպանվում են բոլոր մակարդակներում և չեն հեռացվում կամ աղբահանվում։ Բոլոր մակարդակների փաթեթները շարունակաբար օգտագործվում են կլիենտներին սպասարկելու համար՝ հիմնվելով ստացման ժամանակ նրանց նշած have-երի և want-երի վրա։ Իսկ Pando-ն որպես API օգտագործող կլիենտների համար փաթեթային ֆայլից կամայական օբյեկտ կարդալը սովորաբար ավելի քիչ տվյալներ է պահանջում L0-ից, քան L4-ից, քանի որ օբյեկտի սեղմված լինելու հավանականությունն ավելի փոքր է։

Pando-ում խտացումը զգալիորեն նվազեցնում է կլիենտներին փոխանցվող տվյալների ընդհանուր ծավալը և թույլ է տալիս, որ փաթեթների պլանավորման ծախսերն աճեն ենթագծային կերպով՝ կախված նրանից, թե որքանով է կլիենտը հետ մնացել։ Սա հատկապես կարևոր է մեծ և արագ փոփոխվող պահոցների համար, որոնք, մեր ակնկալիքով, սովորական երևույթ կդառնան ծրագրային մշակման մեջ։

Pando-ի ստեղծումը

Մենք Pando-ն ստեղծեցինք Codex-ի օգնությամբ՝ նախագծի մեկնարկից մինչև արտադրական գործարկում անցնելով ընդամենը 10 շաբաթում։ Pando-ի միջուկը նախագծել է մեկ ինժեներ, իրականացրել են ագենտների թիմերը, իսկ ներդրել՝ մի քանի ինժեներներ։ Pando-ն արտադրական թրաֆիկը սկսել է սպասարկել այս տարվա ապրիլին և OpenAI-ում օգտագործվող սկզբնաղբյուրի կառավարման գործիքների ավելի մեծ համակարգի մի մասն է։

Pando-ի նախագծի վավերացման համար կիրառեցինք բազմազան մոտեցումներ։ Մենք կիրառեցինք ավելի անվտանգ ծրագրային հիմքեր ստեղծելու⁠ մեր սկզբունքները։ Քանի որ նախագիծը սկսում էինք զրոյից, որոշեցինք Pando-ն իրականացնել Rust-ով՝ առանց հին կախվածությունների։ Մենք գրեցինք համապատասխանության թեստերի հավաքածու, որպեսզի ագենտները կարողանան իրենց փոփոխությունները ստուգել Git-ի ստանդարտ վարքագծի նկատմամբ։ Մշակեցինք նաև դետերմինիստական սիմուլյացիոն թեստավորման հարնեսներ՝ համակարգի ինվարիանտներն ու հատկությունները ստուգելու համար։ Դրանցով հայտնաբերեցինք և մեղմեցինք համաձայնեցման ու փաթեթների պլանավորման դժվար նկատելի մրցակցային վիճակներն ու հետընթացները։

Այս համակարգի ստեղծմանը մասնակցել են բազմաթիվ մոդելներ․ նոր մոդելների հասանելի դառնալուն պես դրանք օգտագործում էինք Pando-ի արտադրողականությունն ու հուսալիությունը բարելավելու համար։ GPT‑6 Astra-ի օգնությամբ ագենտները Lean-ով և TLA+-ով ձևայնացրին «Pando-ի տեսությունը», որով հայտնաբերեցինք ու շտկեցինք իրականացման սխալները և ապացուցեցինք համակարգի հատկությունները։ Մի քանի անընդհատ աշխատաշրջաններ հարյուրավոր ժամեր գործեցին՝ գտնելով և շտկելով Pando-ի սահմանային դեպքերը։ Մենք նաև շուրջօրյա գործարկում ենք ագենտներ՝ Daybreak-ի հնարավորություններն ունեցող մոդելներով Git-ի և Pando-ի անվտանգությունը հակառակորդի դիրքից փորձարկելու համար։

Pando-ի ներդրումը

Սկզբում Pando-ն ներդրեցինք որպես ընթերցումներն ու գրառումները մեր առկա սկզբնաղբյուրի կառավարման համակարգին փոխանցող միջնորդ սերվեր։ Սա թույլ տվեց Pando-ն և նախորդ համակարգը պահել համաժամեցված, որպեսզի թրաֆիկն անվտանգ տեղափոխենք Pando՝ առանց պարապուրդի։

Քեշավորման իր կառուցվածքի շնորհիվ Pando-ն կարող է նաև հեռացնել կրկնվող հարցումները և միավորել դրանք մինչև փոխանցելը։ Այսպիսով պահպանեցինք առկա գործիքների անխափան աշխատանքը՝ համակարգերը հերթով տեղափոխելով Pando։ Որքան ավելի շատ աշխատանքներ էինք տեղափոխում Pando, այնքան դրանց ուղարկումները լցնում էին Pando-ի քեշը և բարձրացնում նախորդ սերվերային համակարգի հուսալիությունը։

Pando-ն օգտագործելիս արտադրողականությունն օպտիմալացնելու համար սկսեցինք Git-ի մեր հրապարակային բաշխումը տրամադրել մշակողների համակարգիչներին և ChatGPT‑ի համակարգչային հավելվածի կազմում։ Կլիենտներին փուլ առ փուլ Pando տեղափոխելու համար օգտագործեցինք Git CLI-ի մեր ներքին պատյանը։ Ստեղծեցինք բազմաթիվ այլ գործիքներ՝ փոփոխությունների հարցումների մշակման, կոդի վերանայման, ինչպես նաև ավտոմատացումների API-ների համար։ Git-ի թրաֆիկի հետ մեկտեղ տեղափոխեցինք հարյուրավոր ինտեգրումներ, որոնք կախված էին հին API-ներից, վեբհուքներից և պահոցների ներբեռնումներից։

Codex-ն ինքն էլ օգնեց մշակողներին ու թիմերին կատարել այս անցումը։ Ստեղծեցինք հմտություններ՝ առկա աշխատանքային պատճենները պատրաստելու և ագենտներին նոր համակարգի օգտագործման հարցում ուղղորդելու համար։ Արդյունքում մշակողները կարող էին պարզապես խնդրել Codex-ին տեղափոխել իրենց մշակման միջավայրերն ու ծառայությունները։

Pando-ին անցումը բարձրացրեց միավորումների հուսալիությունը և ուղարկման մեդիանային ուշացումը կրճատեց գրեթե 80%-ով։

Pando-ն կարող է օրական տրամադրել մեկ պետաբայթ Git տվյալներ՝ ընդամենը մի քանի պրոցեսորային միջուկով։ Pando-ն մեկ ժամում տրամադրել է ավելի քան 57 տերաբայթ Git փաթեթներ, որոնց բայթերի ավելի քան 99%-ը՝ տեղային սկավառակի քեշից։

Փաթեթների վերօգտագործումը բազմաթիվ կլիենտների թույլ է տալիս ներբեռնել պահոցի նույն պատմությունը՝ սպասարկող հանգույցներում քիչ հաշվարկներով։ Այս օրինակը վերաբերում է մեկ պահոցի, բայց Pando-ն նախատեսված է շատ ավելին սպասարկելու համար։ Պահանջարկի աճին զուգընթաց կարող ենք անկախ մասշտաբավորել տվյալների տրամադրումն ու Git-ի համաձայնեցումը։

Ներդրում Git նախագծի զարգացման գործում

Pando-ն Git արձանագրության և կլիենտի վրա կառուցելն օգնեց մեզ հայտնաբերել սխալներ և հենց Git-ի արտադրողականությունը բարելավելու հնարավորություններ։

Օրինակ՝ Pando-ն վերօգտագործվող փաթեթներն անմիջապես տրամադրում է կլիենտներին, ուստի դրանց ներբեռնումն ու ինդեքսավորումը դարձան համակարգի արագության և հուսալիության առանցքային գործոններ։ Այդ աշխատանքը բացահայտեց սահմանային դեպքեր՝ զուգահեռ ներբեռնումների, ընդհատված փոխանցումներից հետո մաքրման և արդեն ավարտված ներբեռնումների վերսկսման ժամանակ։ Մենք շտկեցինք այդ դեպքերը, ստացման համար առկա փաթեթն ընդունելիս ավելացրինք ստուգումներ և այդ աշխատանքը փոխանցեցինք հիմնական նախագծին։

Պետք էր նաև հասկանալ՝ որտեղ են ծախսվում ժամանակն ու թողունակությունը։ Ուստի ավելացրինք packfile-uri ներբեռնումների հետագծում և փաթեթների ստեղծման ընթացքում բայթերի քանակի հաշվառում՝ հեշտությամբ պարզելու համար, թե դանդաղ ստացման ժամանակը ծախսվում է փաթեթների ստեղծման, թե փոխանցման վրա։

OpenAI-ի Git հավաքածուում⁠(բացվում է նոր պատուհանում) կլիենտը կարող է անկախ փաթեթները ներբեռնել և ինդեքսավորել զուգահեռ։ Ավելացրինք «բացահայտ նշված առկա քոմիթների» հասկացությունը, որպեսզի սերվերը կարողանա ճյուղի ընթացիկ վերջնակետը հայտարարել առանձին այն պատմությունից, որը ուղարկող կլիենտը կարող է բաց թողնել իր փաթեթում։ Pando-ում սա կլիենտներին թույլ է տալիս --force-with-lease-ով ստուգել, որ ֆունկցիոնալության ճյուղը չի փոխվել, և դրա փաթեթը կառուցել միայն հիմնական ճյուղի հիման վրա։ Հիմնական ճյուղի այդ պատմությունն ունեցող ցանկացած կլիենտ այնուհետև կարող է ճյուղը ստանալ նույն փաթեթով։

Այս բարելավումներից մի քանիսն արդեն Git-ի հիմնական նախագծում են, իսկ շատերը՝ մեր հրապարակային պահոցում։ Շարունակում ենք համագործակցել Git համայնքի հետ, որպեսզի այս բարելավումները օգտակար լինեն նաև Pando-ից դուրս։ Այդ աշխատանքին կարող եք հետևել մեր կարկատանների հրապարակային հետագծիչում⁠(բացվում է նոր պատուհանում)։

Հաջորդող քայլերը

Վերանայելով Git պահոցների մասշտաբավորման ընդունված մոտեցումները՝ Pando-ն թույլ է տալիս մասշտաբավորել մեր մոնոպահոցը՝ առանց փոխելու Git-ի աշխատանքային գործընթացները, որոնցից արդեն օգտվում են մեր ինժեներներն ու ագենտները։ Մեր մոնոպահոցում Pando-ն ավելացրել է զուգահեռ աշխատանքի հնարավորությունները, բարձրացրել միավորումների հուսալիությունը և կրճատել կոդի փոփոխությունները հրապարակելու ժամանակը։ Մոնոպահոցից բացի՝ ուսումնասիրում ենք նաև Pando-ի այլ կիրառություններ OpenAI-ում, այդ թվում՝ աշխատանքներ, որտեղ մեծ թվով ագենտներ պետք է համագործակցեն ընդհանուր Git պահոցում։

Քանի որ ինժեներներն ու ագենտներն ավելի շատ ծրագրեր են ստեղծում, OpenAI-ից դուրս ավելի շատ թիմեր կբախվեն սկզբնաղբյուրի կառավարման այն սահմանափակումներին, որոնց մենք հանդիպեցինք։ Այժմ ուսումնասիրում ենք Pando-ի հիմքում ընկած տեխնոլոգիան մեր օգտատերերին հասանելի դարձնելու ուղիները։

Pando-ն հիմնվում է Git պահոցների օգտատերերի և օպերատորների երկու տասնամյակի փորձի վրա։ Կշարունակենք զարգացնել Pando-ն և համագործակցել Git-ի բաց կոդով համայնքի հետ՝ կիսվելու այն բարելավումներով, որոնք օգտակար են Git-ի օգտատերերի ավելի լայն շրջանակին։

Հեղինակ

OpenAI