OpenAI-да Git жүйесін масштабтау
Git экожүйесін дамыта отырып, агенттер ауқымына сай бастапқы кодты басқару жүйесін құру.
Соңғы бір жылда монорепозиторийіміздің көлемі мен оған түсетін жүктеме таңғаларлық қарқынмен өсті. Codex мүмкіндік берген қатар орындалатын жұмыс ауқымына жету үшін бастапқы кодты басқару жүйесін жаңарту қажет екені анық болды.
Біз инженерлік жұмысты тоқтатпай әрі команданың Git қолдану тәсілін өзгертпей, Git репозиторийлеріне арналған жаңа серверлік жүйе — Pando жасадық. Қазір OpenAI монорепозиторийіндегі бүкіл әзірлеу жұмысы Pando арқылы жүреді. Pando екі өршіл мақсатқа сай жасалған. Біріншісі — көптеген тармаққа бір мезгілде өзгеріс жіберуге оңтайландырылған, көлденең масштабталатын жазу. Екіншісі — клиенттер қолжетімді желі өткізу жолағын толық пайдаланып, деректерді барынша жылдам жүктеп алуы үшін оқудың өткізу қабілетін барынша арттыру.
Бұл мақсаттарға Git протоколы және клиентімен үйлесімділікті сақтай отырып жеттік. Соның арқасында инженерлеріміз де, агенттеріміз де Pando жүйесін қолданыстағы жұмыс процестеріне оңай енгізді. Өндірістік ортада Pando өзгеріс жіберудің медианалық кідірісін 5 есеге жуық қысқартты. Қазір ол күніне бір петабайтқа жуық Git дерегін жеткізеді.
Бұл мақалада жаңа бастапқы кодты басқару жүйесін не үшін жасағанымызды және Git-пен үйлесімділікті неге сақтағанымызды түсіндіреміз. Жүйемізді Git масштабтаудың кең тараған тәсілдерімен салыстырып, Pando неліктен OpenAI масштабтау қажеттіліктерін ерекше тиімді өтей алатынын баяндаймыз. Сондай-ақ алдағы жоспарларымызды және агенттер ауқымындағы жұмысты қолдау үшін Git жобасына қалай үлес қоса беретінімізді талқылаймыз.
Codex OpenAI-дағы әзірлеудің ауқымы мен қарқынын өзгертіп, инженерлерге әлдеқайда көп жұмысты қатар орындауға мүмкіндік берді. Бұл — көбірек тармақ, өзгеріс жіберу мен біріктіру, сондай-ақ әзірлеу орталары, зерттеу тапсырмалары және CI тарапынан көбірек алу және клондау операциясы деген сөз.
Бұл жүктемелер бірін-бірі еселейді. Қазір бір инженердің CI үшін бірден бірнеше өзгерісі дайын болады, ал әр жіберу бір коммитті қатар алатын бірнеше тапсырманы іске қоса алады.
Өткен жылдың соңына қарай монорепозиторийімізге қызмет көрсететін жүйелер жүктемеге ілесе алмай бастады. Алу мен жіберу баяулап, біріктірулер сәтсіз аяқтала бастады; кейде сенімділік 90%-дан төмен түсті. Біз Git жүйесінің өз шегіне жеттік пе, әлде монорепозиторийге қызмет көрсету тәсіліміздің шегіне ме? Git ядроға арналған түзетулерді электрондық поштамен алмасатын қауымдастықтан бастау алған. Жиырма жылдан астам уақыт бойы әзірлеушілер бағдарламалық жасақтама жасау тәсілдері өзгерген сайын құралдарын Git негізінде бейімдеп келді. Өз монорепозиторийімізде қиындықтар сезіле бастағанда, біз үшін осы еңбектерге сүйенуді жалғастыру маңызды болды.
Серверлік жүйені әртүрлі тармақтарға жіберуді қатар өңдеуге және бір тарихты көптеген оқушы клиентке бір мезгілде беруге бейімдеп, үйреншікті жұмыс процесін сақтаудың жолын көрдік. Бастапқы кодты басқару процесінің негізі ретінде Git-ті сақтау клиентке енгізілген жетілдірулердің OpenAI-дан тыс жерде де пайдалы болуына жол ашты. Біз Git көшірмеміздегі(жаңа терезеде ашылады) осы жетілдірулерді негізгі жобаға қосып, кең қауымдастықпен бөліскіміз келді.
Бастапқы кодты басқару жүйесін масштабтаудың екі негізгі бағыты бар: көптеген жазушы клиенттің әртүрлі тармаққа өзгеріс жіберуі және көптеген оқушы клиенттің бір тарихты алуы. Pando екеуіне де оңтайландырылған.
Біріншіден, Pando әр тармақтың жаңартуларын тәуелсіз үйлестіреді. Өзара байланыссыз тармақтар қатар жаңартыла алады, ал тармақты алатын клиент сол нұсқаға қажет тарихты алады. Бірақ мұның есесіне бірнеше тармақты қарайтын клиент олардың әртүрлі уақыт мезетіндегі күйлерін көруі мүмкін.
Екіншіден, Pando әр клиентке жеке пакет файлын жасаудың орнына, пакет файлдарын (Git жүйесінің бірнеше объектіні бірге сығу пішімін) алу операциялары арасында қайта пайдаланады. Клиент өзінде бар кейбір объектіні қайта жүктеп алуы мүмкін, есесіне сервер бірдей байттарды көптеген клиентке аз есептеу шығынымен бере алады.
Осы шешімдер жазуды тармақтар арасында масштабтауға және оқу сұрауларына кэштен жауап беруге мүмкіндік береді. Олардың қалай бірге жұмыс істейтінін түсіну үшін Git тарихты қалай сақтап, тасымалдайтынынан бастайық.
Git репозиторийдің екі бөлігін — объектілерді және сілтемелерді — синхронды ұстауы керек.
Git репозиторийі файлдардың белгілі бір сәттегі күйлерін және оларды байланыстыратын тарихты объектілер графы ретінде сақтайды. Объект блоб, ағаш, коммит немесе тег болуы мүмкін. Блоб жеке файлдың мазмұнын сақтайды, ал ағаштар атауларды блобтармен не басқа ағаштармен байланыстырып, каталог құрылымын жасайды. Коммиттер түбірлік ағашқа және нөл не одан көп ата-ана коммитке сілтеп, репозиторий тарихын құрайды.
Объектілер түрі мен мазмұнының хеші арқылы анықталады. Объектілер өзгермейді: өзгертілген файлды жазу жаңа блоб жасайды, ал өзгермеген файлдар мен каталогтар бұрынғы объектілерді қайта пайдалана алады.
Тармақтар мен тегтер — коммиттерді көрсететін сілтемелер, яғни «refs». Тармақта коммит жасау жаңа коммит құрып, тармақ сілтемесін соған бағыттайды.
Git объектілері бір-біріне ID мәндері арқылы сілтейді: коммиттер ағаштарға, ал ағаштар басқа ағаштар мен блобтарға сілтейді. refs/heads/main тармағы ата-анасы C1 болатын C2 коммитін көрсетеді. C1 түбірлік T1 ағашын көрсетеді, онда parser.py B1 блобын көрсетеді. C2 түбірлік T2 ағашын көрсетеді, онда parser.py B2 блобын көрсетеді. Екі түбірлік ағашта да docs/ бір T3 ағашын көрсетеді. Ондағы README.md жазбасы B3 блобын, ал usage.md B4 блобын көрсетеді.
Git объектілерді «бөлек» немесе «пакеттелген» күйде сақтайды. Бөлек объектілер өз ID мәнімен анықталатын жеке файлдарда сақталады. Пакеттелген объектілер бір пакет файлында бірге сақталады. Бұл ұқсас объектілерді бір-біріне қатысты айырмалар түрінде сақтауға мүмкіндік береді.
Git блобтарды жеке файлдарда сақтай алады немесе бір блобты екіншісіне қатысты айырма ретінде кодтап, оларды бірге пакеттей алады.
Git жүйесінде объектіні белгілі бір коммиттен бастап оның ата-аналарына, ағаштарына және блобтарына апаратын сілтемелерді қадағалау арқылы табуға болса, ол сол коммиттен қол жеткізілетін объект деп есептеледі. Деректерді алу кезінде клиент серверге өзіне қандай коммиттер қажет екенін және қай коммиттер өзінде бар екенін хабарлайды. Сервер сұралған коммиттерден қол жеткізілетін объектілерді анықтап, клиентте бар екені белгілі объектілерді алып тастайды да, қалғандарын Git дискіде қолданатын пішімдегі пакет файлы ретінде жібереді. Толық клондау кезінде клиентте бастапқыда ешбір объект болмайды, сондықтан оған клонданатын тарихтан қол жеткізілетін барлық объект қажет.
Жіберу операциясы серверден бір не бірнеше сілтемені жаңартуды сұрап, объектілерді кері бағытта тасымалдайды. Серверде бар объектілерді қайта жібермеу үшін клиент сервер жариялаған сілтемелер жиынын пайдаланады. Сондықтан жіберілетін пакет бұрыннан бар объектілерге тәуелді болуы мүмкін: жаңа тарихты қалпына келтіру үшін пакеттің өзін алу жеткіліксіз.
Git репозиторийін репликациялау — объектілер мен сілтемелерді бірнеше серверде қолжетімді ұстау деген сөз. Реплика сілтеменің жаңа мәнін ұсынбас бұрын, сол мәннен жетуге болатын объектілерді бере алуы керек. Қызмет сонымен қатар бәсекелес сілтеме жаңартуларын, яғни бір тармақты бір ескі ұштық коммиттен әртүрлі жаңа коммитке жылжытуға тырысатын жіберулерді үйлестіруі керек. Репозиторийдегі барлық жазуға бірыңғай рет орнататын жүйелер өзара байланыссыз тармақтарға жіберулерді бірін-бірі күтуге мәжбүр етуі мүмкін.
Pando жобалау кезінде Git арқылы бастапқы кодты басқаруды масштабтаудың дәстүрлі тәсілдерін бағаладық. Бірі репозиторий репликаларының сілтеме жаңартуларын үш фазалы бекіту арқылы үйлестіреді (3PC — бірнеше түйіндегі бекітуді үйлестіру протоколы). Екіншісі жаңартуларды блоб қоймасындағы ортақ алдын ала жазу журналы арқылы реттейді (WAL — өзгерістер қолданылғанға дейін жазылатын журнал).
Біз үлгілеген үш фазалы бекіту құрылымында Git қызметі репозиторийдің толық көшірмесін бірнеше репликада сақтайды. Кез келген сервер жіберілген өзгерісті қабылдағанда, келген пакет файлы көшіріліп, барлық репликаға қатар жіберіледі. Жіберілген өзгерісті жариялау үшін репликалардың көпшілігі сілтеме жаңартуын қабылдауы керек. Осы процесті басқаратын сервер үйлестіруші болады. Оған әрбір басқа репликамен бірнеше айналым байланыс жасау қажет.
Сілтеме жаңартуын қабылдау үшін әр реплика сілтеменің өз көшірмесін бұғаттап, оның әлі де клиент күткен коммитті көрсететінін тексереді. Содан кейін үйлестіруші қабылдаған репликаларға алдын ала бекіту хабарламасын жібереді. Көпшілігі алдын ала бекіту хабарламасын растаған соң, үйлестіруші оларға жаңартуды орындауды тапсырады. Одан кейін өзекті күйдегі кез келген реплика репозиторийдің жергілікті көшірмесінен тармақтың жаңа ұштық коммитін жариялай алады.
Толық репликаларды сақтау оқу сұрауларына жергілікті жауап беруге мүмкіндік береді және клиент қай репликаны таңдаса да, барлық сілтеменің келісімді күйін алуына кепілдік береді. Соның салдарынан сілтемелер бір-бірден жаңартылады, ал әр жіберу сілтеме жаңартуын репликалар арасында үйлестіру үшін бірнеше толық байланыс айналымын қажет етеді.
Кворумды күту салдарынан өзгеріс жіберу операциясының орындалу уақыты репликалар дискілерінің өнімділігіне және желідегі байланыс кідірісіне тәуелді болады. Жазу көлемі өскен сайын, репликалар кіріс пакеттерін де, оқу трафигін де өңдеп үлгеруі керек.
Біз үлгілеген WAL негізіндегі құрылымда Git қызметі бүкіл репозиторийдегі жаңартуларды реттеу үшін блоб қоймасындағы ортақ манифестті қолданады. Сервер жіберілген өзгерісті қабылдағанда, келген пакет файлын блоб қоймасына жүктеп, репозиторийдің жергілікті көшірмесінде сілтеме жаңартуын дайындайды. Жіберілген өзгерісті жариялау үшін ол блоб қоймасындағы ортақ манифестке сілтеме жаңартуын тіркейтін және пакет файлын көрсететін жазба қосады. Содан кейін Git сервері манифестті салыстыру және алмастыру операциясымен жаңартады. Бұл манифестті атомарлы түрде алмастырады немесе өзгерісті қабылдамайды. Осы аралықта басқа жазушы оны жаңартса, сервер аралық жазбаларды оқып, өз сілтеме жаңартуының әлі жарамды екенін тексереді де, бұрын жүктеген пакет файлын пайдаланып, қайта әрекет етеді.
Жазушы клиенттер пакет файлдарын қатар жүктей алады, бірақ өзара байланыссыз тармақтарға жіберудің өзі бір манифестті жаңартуды қажет етеді. Сәтті салыстыру және алмастыру операциясының толық айналым уақыты репозиторийдің жаңа манифестті қаншалықты жиі жариялай алатынын шектейді. Кідірісі аз блоб қоймасы бұл қадамды жылдамдатады. Топтап өңдеу бір манифестпен бірнеше сілтемені қатар жаңартуға мүмкіндік береді, бірақ жаңартулар кезекке қойылып, кідіріс артады.
Блоб қоймасы пакет файлдарын қатар қабылдай алады, алайда ортақ манифесттің жаңартулары бәрібір бір-бірімен бәсекелеседі. Блоб қоймасының қуатын арттырудың өзі бұл тар орынды жоймайды. Әр реплика пакеттерді жергілікті түрде ұсынбас бұрын, оларды блоб қоймасынан оқып, индекстеуі керек. Кіріс жазулары осы жұмыстан жылдамырақ келсе, репликалар артта қалып, клиенттер жаңадан жіберілген коммиттерді алу үшін ұзағырақ күтеді.
Енді Pando жүйесіне көшейік. Pando — бір мезгілде өзгеріс жіберетін көптеген клиентке дейін масштабталуды көздейтін, Git репозиторийлеріне қызмет көрсетудің жаңа архитектурасы. Ол былай жұмыс істейді:
Pando әзірлеуге кіріспей тұрып, Git-тен бас тартпай-ақ талаптарымызды орындай алатынымызды болжадық. Бірақ Git жүйелерінің көбі міндетті деп санайтын кейбір талаптарды жеңілдету керек болды:
Бүкіл репозиторийдегі келісімділік: Барлық сілтеменің бір уақыт мезетіндегі келісімді күйін ұсыну үшін бүкіл репозиторий бойынша үйлестіру қажет. Барлық сілтеме жаңартуларын ортақ ретке келтіретін жүйеде өзара байланыссыз тармақтарға өзгеріс жіберу операциялары бір үйлестіру нүктесіне таласады.
Әр клиентке жеке пакет файлдары: Жергілікті тарихы әртүрлі екі клиент бір тармақты алса, оларда бар объектілерді қайта жібермеу үшін серверге әрқайсысына бөлек пакет жасау қажет болуы мүмкін. Мұндай жауаптарды дайындау процессор ресурсы мен дискілік енгізу-шығару операцияларын қажет етеді. Бұл дерек оқитын клиенттер саны артқанда масштабтауды қиындатады.
Оның орнына Pando жазуды масштабтау үшін жеңілдетілген келісімділік модель (себептік келісімділікті) қолданады, ал оқуды масштабтау үшін пакет файлдарын қайта пайдаланады.
Клиент тармаққа өзгеріс жібергенде, Pando келген пакет файлын блоб қоймасында өзгермейтін блоб ретінде сақтайды. Тармақ ілгерілеген сайын, Pando метадеректер қоймасына жаңа ұштық коммитті, оны жеткізген пакетті және сол пакет тәуелді болатын бұрынғы сілтеме нұсқаларын қамтитын сілтеме нұсқасын жазады. Блоб қоймасын да, метадеректер қоймасын да көлденең масштабтауға болады.
Pando жүйесінен коммит не сілтеме алу үшін клиентке сілтеме нұсқаларының (пакет файлдарының) жиынын ретімен жіберу қажет. Осылайша алынатын сілтеме нұсқасын жасаған клиенттің күйі қалпына келтіріледі. Бұл бүкіл репозиторий деңгейінде келісімділіктің әлсіздеу түрін береді, ал жеке сілтемелердің жаңартулары бірінен соң бірі орындалғандай нәтиже береді. Клиенттер бір сілтемеге бір мезгілде өзгеріс жібергенде ғана қақтығысады. Бірнеше тармақты оқитын клиент алынған деректер бүкіл репозиторийдің бір уақыт мезетіндегі күйін көрсетеді деп есептей алмайды.
Негізгі тармаққа өзгеріс жіберілгенде, бір не бірнеше коммиті бар инкременттік пакет қосылады. Қосалқы тармаққа өзгеріс жіберілген сайын, тақырыптық тармақтың бұрынғы коммиттері қайта қамтылады. Осылайша негізгі тармақтың жарияланған нұсқасы бар клиент тақырыптық тармақты бір пакетпен ала алады.
Бұл — себептік келісімділіктің бір түрі. Сілтемені алу кезінде деректерді алатын клиент сол сілтемені жасаған клиенттің өзгерістер тарихын көреді. Өзгеріс жіберу барысында Pando клиент пен сервердің қандай ортақ тарихты негізге алатынын басқарады. Соның арқасында клиенттер басқа клиенттермен оңай бөлісуге болатын пакет файлдарын жасайды.
Сондықтан Pando Git операциялары кезінде барлық сілтеменің бір уақыт мезетіндегі күйін де, клондау не алу шеңберінде сілтеме жаңартуларының ортақ ретін де қамтамасыз етпейді. Мысалы, толық клондауды келісу барысында foo және bar тармақтарының екеуі де жаңартылды делік. Келісу кезінде бір клиент foo тармағының 1-нұсқасын және bar тармағының 2-нұсқасын көруі мүмкін, ал екіншісі foo тармағының 2-нұсқасын және bar тармағының 1-нұсқасын көреді. Іс жүзінде пайдаланушылар мен агенттер сілтеме жаңартуларының жалпы ретіне емес, жеке сілтеменің жаңартылу ретіне сүйенеді.
Үш келісімділік модель салыстыратын осы симуляцияда 1000 клиенттің әрқайсысы бөлек тармақты таңдап, оған бірегей коммиттерді қайта-қайта жіберетіндей етіп баптаймыз. Біз операциялардың орындалуына кеткен нақты жалпы уақытты және өзгеріс жіберілген сәттен оны алуға болатын сәтке дейінгі кідірісті өлшейміз. Соңғы көрсеткіш жұмыс жүктемелері үшін маңызды, өйткені ол пайдаланушылар мен агенттердің бірлесіп жұмыс істеуіне немесе нұсқаларды басқаруға сүйенетін басқа жүйелерді пайдалануына қажет толық айналым уақытын сипаттайды. Симуляцияда қарапайым жабдықтан жоғары өнімді виртуалды машиналарға дейінгі есептеу ресурстары мен блоб сақтау жүйелері үлгіленеді. Бұл симуляцияда үш фазалы бекіту үлгісіне қойылатын бүкіл репозиторий бойынша келісімділік талабын жеңілдеттік.
Simulating Git Server Implementations
Follow each writer through repeated pushes, and separately measure when an independent reader can check out each commit.
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.
Агент файлдарды өңдеп, жергілікті коммит жасайды да, git push пәрменін орындайды. Ол тармақты жаңарту үшін сол өзгерістерден пакет файлын жасайды. Pando пакетті қабылдап, оны блоб қоймасына ағынмен жібереді. Келген өзгерісті бір өтімді декодтау арқылы тексерген соң, Pando бірнеше кілтті қамтитын транзакциямен метадеректер қоймасына сілтеме нұсқасын жазып, сілтеме көрсеткішін атомарлы түрде жаңартады. Осылайша Pando «өзің жазғанды оқу» келісімділігін қамтамасыз етеді. Осы жазу операциясының бәрі метадеректерді рет оқу мен жазуды қажет етеді.
Басқа клиент тармақты алғанда, Pando клиентте бар тарихқа сүйеніп, сақталған пакеттер жиынын таңдайды. Бұл операция метадеректерді рет оқуды қажет етеді. Мұндағы — клиентте бар күй мен оған қажет күй арасындағы сілтеме нұсқаларымен өлшенген ең қысқа қашықтық. Сервер пакет файлдарының URI мекенжайларын қайтарады, ал клиент оларды аймақтық кэштерде сақтайтын Express қызметі арқылы жүктеп алады.
Бұл құрылым Pando архитектурасының үш негізгі қызметіне сүйенеді: жіберу, алу және ықшамдау.
Клиент өзгеріс жібергенде, дәстүрлі Git сервері барлық картасын ашқан покер ойыншысындай өзіндегі бүкіл тармақты клиентке көрсетеді. Содан кейін клиент коммиттерді, ағаштарды және блобтарды жинап, серверде бар екені белгілі объектілерді қоспайтын пакет файлын жасайды.
Көбірек сілтеме жариялау жіберілетін дерек көлемін азайта алады. Бірақ бұл пакетті қайта пайдалануды қиындатуы да мүмкін, өйткені басқа клиентте жазушы клиент қоспаған объектілер болмауы ықтимал.
Pando басқа тәсілді қолданады. Барлық картасын ашудың орнына, ол клиентке таңдалған тармақтар жиынын ғана жариялайды. Мұның екі себебі бар:
Әр сілтеменің келісімді күйін ұсыну көп ресурс қажет етеді. Миллиондаған тармақ болғанда, сілтемелер туралы жарияланатын ақпараттың өзі 100 MiB-тан асып кетуі мүмкін. Мұны қамтамасыз ету үшін әр сервер не сілтемелердің ағымдағы мәндерін көрсететін кестені үнемі жаңартып отыруы керек, бұл едәуір үйлестіру шығынын тудырады, не орындалу шығыны сілтемелер санына қарай өсетін дерекқор сұрауын орындауы керек.
Клиентке сілтемелердің бір бөлігі ғана ұсынылса, ол сервер қоспауға нақты рұқсат берген объектілерге ғана тәуелді пакет жасайды. Тәуелділіктерді қадағалау арқылы Pando клиент бір жіберуде жасаған пакет файлын кейінгі алу сұрауына жауап ретінде қайта пайдалана алады.
Git сервері неғұрлым көп сілтеме жарияласа, өзгеріс жіберетін клиенттер соғұрлым көп көздегі объектілерді пакеттен шығарып тастай алады. Бұл шағын пакеттер жасауға мүмкіндік береді. Алайда осы пакет файлдарын қайта пайдалану үшін сервер алушы клиенттерде барлық тәуелділіктің бар екенін дәлелдей алуы керек. Әйтпесе пакет файлында клиентке қажет объектілер болмай қалуы мүмкін.
Ал Git сервері ешбір сілтеме жарияламаса, клиент репозиторийдің толық тарихын қамтитын пакет файлын жасайды. Ондай пакетті кез келген басқа клиент пайдалана алады. Бірақ мұның шығыны үлкен: кез келген тармақты алу іс жүзінде толық клондауға айналады.
Көбірек сілтеме жарияланса, пакет файлдары кішірейеді. Көлемнің негізгі азаюына бір ғана сілтемені жариялау жеткілікті болуы мүмкін.
Әдепкіде клиент жаңа функцияға арналған тармаққа өзгеріс жібергенде, Pando негіз ретінде белгіленген негізгі тармақты ғана жариялайды. Репозиторийдегі тармақ саны артса да, жарияланатын ақпарат көлемі өзгермейді. Алайда бұл тәсілдің кемшіліктері де бар. Инженер бір тармаққа бірнеше рет өзгеріс жіберсе немесе бір функцияға арналған тармақты екіншісінің негізінде құрса, клиент негізгі тармақта жоқ деректердің бәрін қайта жіберуге мәжбүр болады.
Сондықтан тармаққа кезекті жіберулердің көлемі ұлғайып, қайталануы мүмкін объектілерді қамтиды және клиенттің қосымша желі ресурсын жұмсайды. Монорепозиторийімізде осылай жасалған пакет файлдарының медианалық көлемі 20 KiB-тан, ал 99-процентилі 3 MiB-тан төмен болды. Бұл біз үшін орынды ымыра болды: негізгі тармақтың жарияланған тарихы бар оқушы клиент тармақты сол бір пакет файлымен ала алады.
Клиентке жарияланатын сілтемелер жиынын таңдаған соң, Pando жіберілген өзгерісті қабылдап, метадеректер қоймасын жаңартады. Pando метадеректерді жаңартуды синхронды және асинхронды бөліктерге бөледі. Метадеректердің синхронды жаңартылуы клиенттерге жаңа коммитті бірден алуға мүмкіндік береді. Бұл кезде жаңа сілтеме нұсқасы жазылып, сілтеме көрсеткіші соған бағытталады. Нұсқада жаңа ұштық коммит, пакет файлын келісуге пайдаланылған тәуелділіктер және жіберілген пакет файлына сілтеме сақталады.
Сонымен бірге сол транзакцияда ықшамдауды жоспарлау сияқты асинхронды жұмыстар да тіркеледі. Өте үлкен көлемде өзгеріс жіберілгенде, коммиттердің бір бөлігі ғана синхронды жазылады. Осылайша жіберу көлеміне қарамастан, метадеректер қоймасына оқу және жазу операцияларының тұрақты саны ғана қажет болады.
Маңыздысы — Pando серверлері өзара байланыссыз сілтемелерге жіберілген өзгерістерді тәуелсіз қабылдай алады. Талас туындайтын жалғыз кілт — сілтеме көрсеткіші. Оны атомарлы салыстыру және алмастыруға ұқсас операциямен қорғаймыз. Pando серверлерін, метадеректер қоймасының масштабтау бірліктерін немесе блоб қоймаларын қосу арқылы жазудың өткізу қабілетін арттыра аламыз.
Клиент алу операциясын орындағанда, серверге протоколда have және want деп аталатын коммит ID мәндерінің екі жиынын береді. Дәстүрлі 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.
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 деңгейіне дейінгі пакет файлдары топтары қолданылады.
Бұл топтар екі міндет атқарады. Топ жеткілікті толған соң, ықшамдау процесі оны өңдеуге алып, бір пакет файлын жасайды. Пакет ішіндегі объектілерді қайта реттеу сығу коэффициентін жақсартады. Сонымен қатар бұл топтар сілтеме нұсқаларына арналған skip list құрылымы ретінде жұмыс істеп, деректерді алу кезіндегі келісу процесін жылдамдатады. Әр деңгейдегі индекстерді бір мезгілде қарап шығу арқылы Pando клиентке жіберілетін пакеттер жиынын логарифмдік уақытта таңдай алады. Қайта пакеттелгеніне қарамастан, пакет файлдарының бұл топтары деректерді алуды тиімдірек жоспарлауға мүмкіндік беріп, Pando жүйесіне қойылатын өткізу қабілеті мен кідіріс талаптарын төмендетеді.
Compaction in Pando
Small packfiles are grouped into larger covers across levels, improving compression and speeding up fetches.
Ықшамдау көптеген сілтеме нұсқасының пакет файлдарын фондық режимде біріктіріп, азырақ файлмен тиімдірек алуға мүмкіндік береді.
Көптеген Git серверінен айырмашылығы — пакет файлдары әр деңгейде сақталады, тасталмайды және пайдаланылмайтын дерек ретінде тазаланбайды. Клиенттердің алу сұрауындағы have және want мәндеріне қарай, барлық деңгейдегі пакеттер оларға қызмет көрсету үшін үздіксіз қолданылады. Pando жүйесін API ретінде қолданатын клиенттер үшін пакеттен кез келген объектіні оқу L4-пен салыстырғанда L0 деңгейінде әдетте азырақ дерек оқуды қажет етеді, өйткені оның сығылған болу ықтималдығы төменірек.
Pando жүйесіндегі ықшамдау клиенттерге жіберілетін деректердің жалпы көлемін едәуір азайтады. Сонымен қатар клиенттің соңғы нұсқадан қаншалықты артта қалғанына қарай пакеттерді жоспарлауға жұмсалатын есептеу шығыны сызықтықтан баяу өсетіндей масштабтауға мүмкіндік береді. Бұл әсіресе көлемі үлкен әрі жылдам өзгеретін репозиторийлер үшін маңызды. Біздіңше, мұндай репозиторийлер бағдарламалық жасақтама әзірлеуде қалыпты құбылысқа айналады.
Біз Pando жүйесін Codex көмегімен небәрі 10 аптада жасап, жобаны бастаудан өндірістік ортаға енгізуге дейін жеткіздік. Pando өзегін бір инженер жобалады, агенттер топтары іске асырды, ал бірнеше инженер қолданысқа енгізді. Pando биыл сәуірде өндірістік трафикке қызмет көрсете бастады. Ол — OpenAI қолданатын бастапқы кодты басқару құралдарының үлкен жүйесінің бір бөлігі.
Pando құрылымын тексеру кезінде сан алуан тәсілді қолдандық. Біз бағдарламалық жасақтамаға қауіпсіздеу негіз құру қағидаларымызды қолдандық. Жоба нөлден басталғандықтан, Pando жүйесін Rust тілінде, ескі жүйелерге тәуелділіксіз жасауды таңдадық. Агенттер өз өзгерістерін Git-тің стандартты жұмыс тәртібімен салыстырып тексере алуы үшін сәйкестік тестілерінің жиынтығын жаздық. Сондай-ақ жүйенің инварианттары мен қасиеттерін тексеруге мүмкіндік беретін детерминдік симуляциялық тестілеу тапсырма ортасының кешендерін әзірледік. Олар келісу мен пакеттерді жоспарлаудағы байқалуы қиын жарыс жағдайлары мен регрессияларды анықтап, олардың әсерін азайтуға көмектесті.
Бұл жүйеге көптеген модель үлес қосты; жаңа модельдер қолжетімді болған сайын, оларды Pando өнімділігі мен сенімділігін жақсартуға қолдандық. GPT‑6 Astra көмегімен агенттер «Pando теориясын» формалдау үшін Lean және TLA+ кодын жазды. Оны іске асырудағы қателерді тауып түзетуге және жүйе қасиеттерін дәлелдеуге пайдаландық. Бірнеше үздіксіз сессия жүздеген сағат бойы Pando жүйесіндегі шеткі жағдайларды тауып, түзетумен айналысты. Сондай-ақ Daybreak мүмкіндіктері бар модельдерді пайдаланып, Git пен Pando осалдықтарын шабуыл тұрғысынан тексеретін агенттерді тәулік бойы іске қосамыз.
Бастапқыда Pando жүйесін қолданыстағы бастапқы кодты басқару жүйесіне оқу және жазу операцияларын өткізіп отыратын прокси ретінде іске қостық. Бұл Pando мен бұрынғы жүйенің деректерін синхронды сақтауға, соның нәтижесінде қызметті тоқтатпай, трафикті Pando жүйесіне қауіпсіз көшіруге мүмкіндік берді.
Кэштеу құрылымының бір бөлігі ретінде Pando сұрауларды әрі қарай өткізбес бұрын қайталанатындарын алып тастап, біріктіре де алады. Соның арқасында жүйелерді Pando жүйесіне біртіндеп көшіргенде, бұрынғы құралдарымыздың тұрақты жұмысын сақтадық. Pando жүйесіне көбірек жұмыс жүктемесін көшірген сайын, олардың жіберген деректері Pando кэшін толтырып, бұрынғы серверлік жүйенің сенімділігін арттырды.
Pando қолдану кезіндегі өнімділікті оңтайландыру үшін өзіміздің жалпыға қолжетімді Git дистрибутивін әзірлеушілердің компьютерлеріне және ChatGPT жұмыс үстелі қолданбасына жеткізе бастадық. Клиенттерді Pando жүйесіне кезең-кезеңімен көшіру үшін Git CLI-ді пайдалануға арналған ішкі қабықшаны қолдандық. Өзгеріс сұрауларын өңдеуге, кодты тексеруге арналған көптеген басқа құралды, сондай-ақ автоматтандыруға арналған API интерфейстерін жасадық. Git трафигімен бірге бұрынғы API интерфейстеріне, вебхуктарға және репозиторийді жүктеп алуға тәуелді жүздеген интеграцияны көшірдік.
Әзірлеушілер мен командалардың жаңа жүйеге көшуіне Codex-тің өзі көмектесті. Қолданыстағы жұмыс көшірмелерін дайындауға және агенттерді жаңа жүйені пайдалануға бағыттауға арналған арнайы дағды модульдерін (skills) әзірледік. Соның арқасында әзірлеушілер Codex-тен әзірлеу орталары мен қызметтерін жаңа жүйеге көшіруді жай ғана сұрай алатын болды.
Pando жүйесіне ауысу біріктіру сенімділігін арттырып, жіберудің медианалық кідірісін 80%-ға жуық азайтты.
Pando небәрі бірнеше процессор ядросымен күніне бір петабайт Git дерегін жеткізе алады. Pando бір сағатта 57 терабайттан астам Git пакетін жеткізді; сол байттардың 99%-дан астамы жергілікті диск кэшінен берілді.
Пакеттерді қайта пайдалану көптеген клиентке бір репозиторий тарихын қызмет көрсететін түйіндерде аз есептеу шығынымен жүктеп алуға мүмкіндік береді. Бұл мысалда бір репозиторий көрсетілген, бірақ Pando әлдеқайда көп репозиторийді қолдауға арналған. Сұраныс өскен сайын, дерек жеткізу мен Git келісуін бір-бірінен тәуелсіз масштабтай аламыз.
Pando жүйесін Git протоколы мен клиенті негізінде жасау Git-тің өзіндегі қателерді және өнімділігін жақсарту мүмкіндіктерін анықтауға көмектесті.
Мысалы, Pando қайта пайдаланылатын пакеттерді клиенттерге тікелей береді. Сондықтан оларды жүктеп алу мен индекстеу жүйенің жылдам әрі сенімді жұмыс істеуінің негізгі бөлігіне айналды. Бұл жұмыс қатар жүктеп алуда, үзілген тасымалдан кейін тазалауда және аяқталып қойған жүктеулерді қайта жалғастыруда шеткі жағдайларды анықтады. Біз сол орындалу жолдарын түзетіп, алу операциясы үшін бар пакетті қабылдау кезінде тексерулер қостық және осы жұмысты негізгі жобаға ұсындық.
Сондай-ақ уақыт пен желі ресурсының қайда жұмсалатынын көру қажет болды. Сондықтан packfile-uri жүктеулерін трассалауды және пакет жасау кезіндегі байт есебін қостық. Бұл баяу алу операциясының уақытын пакет жасауға ма, әлде тасымалдауға ма жұмсап жатқанын анықтауды жеңілдетті.
OpenAI Git құрастырылымында(жаңа терезеде ашылады) клиент бір-бірінен тәуелсіз пакеттерді қатар жүктеп алып, индекстей алады. Сервер тармақтың ағымдағы соңғы коммитін өзгеріс жіберетін клиент пакетіне қоспауы мүмкін тарихтан бөлек жариялай алуы үшін «explicit haves» («бар екені нақты көрсетілген коммиттер») ұғымын енгіздік. Pando жүйесінде осының арқасында клиенттер --force-with-lease параметрі арқылы функцияға арналған тармақтың өзгермегенін тексеріп, пакетті тек негізгі тармақтың тарихына сүйеніп жасай алады. Содан кейін негізгі тармақтың сол тарихы бар кез келген клиент осы пакетті пайдаланып, аталған тармақты ала алады.
Бұл жетілдірулердің бірнешеуі Git-тің негізгі жобасына енді, ал басқаларының көбі ашық репозиторийімізде бар. Бұл жетілдірулер Pando-дан тыс жерде де пайдалы болуы үшін Git қауымдастығымен жұмыс істеуді жалғастырып жатырмыз. Осы жұмысты ашық түзетулер трекерімізден(жаңа терезеде ашылады) бақылай аласыз.
Git репозиторийлерін масштабтау туралы қалыптасқан түсініктерді қайта қарау арқылы Pando инженерлеріміз бен агенттеріміз қолданып жүрген Git жұмыс процестерін өзгертпей, монорепозиторийімізді масштабтауға мүмкіндік береді. Pando монорепозиторийімізде қатар орындалатын жұмыс көлемін арттырып, біріктіру сенімділігін жақсартты және код өзгерістерін жариялау уақытын қысқартты. Монорепозиторийден бөлек, OpenAI ішінде Pando жүйесін қолданудың басқа жолдарын да зерттеп жатырмыз. Соның ішінде көптеген агент ортақ Git репозиторийінде бірлесіп жұмыс істеуі қажет жүктемелер бар.
Инженерлер мен агенттер көбірек бағдарламалық жасақтама әзірлеген сайын, OpenAI-дан тыс көбірек команда да бастапқы кодты басқаруда біз кездескен шектеулерге тап болады. Қазір Pando жүйесінің жұмысын қамтамасыз ететін технологияны пайдаланушыларымызбен бөлісу жолдарын қарастырып жатырмыз.
Pando Git репозиторийлерін пайдаланушылар мен операторлардың жиырма жылдық тәжірибесіне сүйенеді. Pando жүйесін дамытуды жалғастырып, Git пайдаланушыларының кең тобына пайдалы жетілдірулермен бөлісу үшін Git-тің ашық бастапқы код қауымдастығымен жұмыс істейміз.


