PostgreSQL-ի մասշտաբավորում՝ 800 մլն օգտատերերին սպասարկելու
Բոհան Ժանգ, տեխնիկական անձնակազմի անդամ
Տարիներ շարունակ PostgreSQL-ը եղել է ամենակարևոր, գաղտնի տվյալների համակարգերից մեկը, որը սնուցում է ChatGPT‑ի և OpenAI-ի API-ի նման հիմնական պրոդուկտները։ Քանի որ մեր օգտատերերի բազան արագ աճում է, մեր տվյալների բազաների նկատմամբ պահանջները նույնպես էքսպոնենցիալ կերպով աճում են։ Անցած տարվա ընթացքում մեր PostgreSQL ծանրաբեռնվածությունն աճել է ավելի քան 10 անգամ, և այն շարունակում է արագորեն աճել։
Մեր արտադրական ենթակառուցվածքը կատարելագործելու մեր ջանքերը՝ այս աճը պահպանելու համար, բացահայտեցին նոր պատկերացում. PostgreSQL-ը կարող է մասշտաբավորվել՝ հուսալիորեն աջակցելու շատ ավելի մեծ ընթերցման ծանրաբեռնվածություններին, քան շատերը նախկինում հնարավոր էին համարում։ Համակարգը (սկզբնապես ստեղծվել է Բերկլիի Կալիֆոռնիայի համալսարանի գիտնականների թիմի կողմից) մեզ հնարավորություն է տվել աջակցելու մեծածավալ գլոբալ տրաֆիկին՝ օգտագործելով Azure PostgreSQL ճկուն սերվերի մեկ հիմնական օրինակ(բացվում է նոր պատուհանում) և աշխարհի տարբեր տարածաշրջաններում տարածված գրեթե 50 ընթերցված կրկնօրինակներ։ Սա պատմությունն է այն մասին, թե ինչպես ենք OpenAI-ում մասշտաբավորել PostgreSQL-ը՝ խիստ օպտիմալացումների և ամուր ինժեներական աշխատանքի միջոցով՝ վայրկյանում միլիոնավոր հարցումներ ապահովելու համար 800 միլիոն օգտատերերի համար։ Մենք նաև կներկայացնենք մեր սովորած հիմնական եզրակացությունները։
ChatGPT‑ի գործարկումից հետո այցելությունների թիվը աննախադեպ աճեց։ Այն աջակցելու համար մենք արագորեն իրականացրեցինք լայնածավալ օպտիմալացումներ թե՛ ծրագրային, թե՛ PostgreSQL տվյալների բազայի շերտերում, մեծացրինք մասշտաբը՝ մեծացնելով օրինակի չափը և ավելացնելով ավելի շատ ընթերցված կրկնօրինակներ։ Այս ճարտարապետությունը երկար ժամանակ մեզ լավ է ծառայել։ Շարունակական բարելավումների շնորհիվ այն շարունակում է ապահովել բավարար հիմք ապագա աճի համար։
Կարող է զարմանալի թվալ, որ մեկ առաջնային ճարտարապետությունը կարող է բավարարել OpenAI-ի մասշտաբի պահանջները, սակայն գործնականում այն աշխատեցնելը հեշտ չէ։ Մենք տեսել ենք Postgres-ի գերբեռնվածության պատճառով առաջացած մի քանի SEV սխալներ, և դրանք հաճախ հետևում են նույն օրինաչափությանը. վերին հոսանքի հանգույցում առկա խնդիրը հանգեցնում է տվյալների բազայի ծանրաբեռնվածության հանկարծակի աճի, ինչպիսիք են քեշի զանգվածային բացթողումները քեշավորման մակարդակի ձախողման պատճառով, թանկարժեք բազմակողմանի միացումների պայթյունը, որը ծանրաբեռնում է պրոցեսորը կամ գրառման հոսքը՝ նոր գործառույթի ակտիվացման պատճառով։ Ռեսուրսների օգտագործման աճի հետ մեկտեղ հարցումների հապաղումը մեծանում է, և հարցումները սկսում են ժամանակի սահմանափակման պատճառով ձախողվել։ Կրկնափորձերը հետագայում էլ ավելի են մեծացնում ծանրաբեռնվածությունը՝ առաջացնելով արատավոր շրջան, որը կարող է վատթարացնել ամբողջ ChatGPT‑ի և API ծառայությունների աշխատանքը։
Չնայած PostgreSQL-ը լավ է մասշտաբավորվում մեր ընթերցման վրա ծանրաբեռնված աշխատանքային հոսքերի համար, մենք դեռ բախվում ենք մարտահրավերների՝ գրառումների բարձր թրաֆիկի ժամանակահատվածներում։ Սա մեծապես պայմանավորված է PostgreSQL-ի բազմատարբերակ միաժամանակյա վերահսկման (MVCC) իրականացմամբ, ինչը այն դարձնում է ավելի քիչ արդյունավետ գրառումների ծանրաբեռնված աշխատանքային բեռների համար։ Օրինակ, երբ հարցումը թարմացնում է զույգ կամ նույնիսկ մեկ դաշտ, ամբողջ տողը պատճենվում է՝ նոր տարբերակ ստեղծելու համար։ Գրառումների մեծ ծանրաբեռնվածության պայմաններում սա հանգեցնում է գրառումների զգալի ամպլիֆիկացիայի։ Սա նաև մեծացնում է ընթերցման աճը, քանի որ հարցումները պետք է սկանավորեն tuple-ների (ոչ ակտիվ tuples) բազմաթիվ տարբերակներ՝ ամենավերջինը ստանալու համար։ MVCC-ն առաջացնում է լրացուցիչ մարտահրավերներ, ինչպիսիք են աղյուսակի և ինդեքսի ուռչելը, ինդեքսի սպասարկման ծախսերի ավելացումը և բարդ ինքնավակուումային կարգավորումը։ (Դուք կարող եք գտնել այս հարցերի վերաբերյալ խորը ուսումնասիրություն իմ բլոգում, որը գրել եմ Կարնեգի Մելոն համալսարանի պրոֆեսոր Էնդի Պավլոյի հետ՝ PostgreSQL-ի այն մասը, որը մենք ամենաշատն ենք ատում(բացվում է նոր պատուհանում) վերնագրով, որը մեջբերված է(բացվում է նոր պատուհանում) PostgreSQL-ի Վիքիպեդիայի էջում։)
Այս սահմանափակումները մեղմելու և գրելու ճնշումը նվազեցնելու համար մենք տեղափոխել ենք և շարունակում ենք տեղափոխել բաժանվող (այսինքն՝ ծանրաբեռնվածություններ, որոնք կարող են հորիզոնական բաժանվել, գրառումների ինտենսիվ ծանրաբեռնվածություններ՝ շարդավորված համակարգերի համար, ինչպիսիք են Azure Cosmos DB-ը, օպտիմալացնելով հավելվածի տրամաբանությունը՝ ավելորդ գրառումները նվազագույնի հասցնելու համար։ Մենք այլևս թույլ չենք տալիս ընթացիկ PostgreSQL տեղակայումում նոր աղյուսակներ ավելացնել։ Նոր ծանրաբեռնվածությունները կանխադրված են շարդավորված համակարգերում։
Նույնիսկ մեր ենթակառուցվածքի զարգացմանը զուգընթաց, PostgreSQL-ը մնացել է չշերտավորված՝ ունենալով մեկ հիմնական օրինակ, որը սպասարկում է բոլոր գրառումները։ Հիմնական հիմնավորումն այն է, որ առկա ծրագրային բեռների մասնատումը կլինի չափազանց բարդ և ժամանակատար, պահանջելով փոփոխություններ հարյուրավոր ծրագրային վերջնակետերում և հնարավոր է՝ տևի ամիսներ կամ նույնիսկ տարիներ։ Քանի որ մեր ծանրաբեռնվածությունները հիմնականում ընթերցման վրա են հիմնված, և մենք իրականացրել ենք լայնածավալ օպտիմալացումներ, ներկայիս ճարտարապետությունը դեռևս ապահովում է բավարար պահուստ՝ շարունակական այցելութունները սպասարկելու համար։ Թեև մենք չենք բացառում PostgreSQL-ի մասնատումը ապագայում, դա մոտակա հեռանկարում առաջնահերթություն չէ՝ հաշվի առնելով ներկա և ապագա աճի համար մեր ունեցած բավարար հնարավորությունները։
Հաջորդ բաժիններում մենք մանրամասն կներկայացնենք մեր հանդիպած խնդիրները և դրանք լուծելու և ապագա խափանումները կանխելու համար իրականացված լայնածավալ օպտիմալացումները՝ PostgreSQL-ը հասցնելով իր սահմաններին և այն մասշտաբավորելով վայրկյանում միլիոնավոր հարցումների (QPS):
Խնդիր. միայն մեկ գրողի դեպքում, մեկ գլխավոր կոնֆիգուրացիան թույլ չի տալիս մասշտաբավորել գրառումների ծավալները։ Գրառումների մեծ կտրուկ աճը կարող է արագ ծանրաբեռնել հիմնական և ազդեցիկ ծառայությունները, ինչպիսիք են ChatGPT‑ը և մեր API-ը։
Լուծում. Մենք նվազագույնի ենք հասցնում հիմնական սերվերի ծանրաբեռնվածությունը՝ թե՛ ընթերցման, թե՛ գրելու գործողությունները, որպեսզի ապահովենք, որ այն բավարար թողունակություն ունի գրելու գագաթնակետային ծանրաբեռնվածությունը կառավարելու համար։ Ընթերցման տրաֆիկը հնարավորության դեպքում բաշխվում է կրկնօրինակների վրա։ Այնուամենայնիվ, որոշ ընթերցման հարցումներ պետք է մնան առաջնայինում, քանի որ դրանք գրելու գործարքների մաս են կազմում։ Դրանց համար մենք կենտրոնանում ենք ապահովել, որ դրանք արդյունավետ լինեն և խուսափեն դանդաղ հարցումներից։ Գրելու տրաֆիկի համար մենք բաժանվող, գրելու վրա ծանրաբեռնված աշխատանքային բեռները տեղափոխել ենք բաժանված համակարգեր, ինչպիսիք են Azure CosmosDB-ը։ Աշխատանքային բեռները, որոնք ավելի դժվար է բաժանել, բայց դեռևս ստեղծում են մեծ ծավալի գրառումներ, ավելի երկար ժամանակ են պահանջում միգրացիայի համար, և այդ գործընթացը դեռ շարունակվում է։ Մենք նաև ագրեսիվ կերպով օպտիմալացրել ենք մեր հավելվածները՝ նվազեցնելու գրառումների բեռը. օրինակ՝ մենք շտկել ենք հավելվածի սխալները, որոնք առաջացնում էին կրկնվող գրառումներ, և ներդրել ենք «ծույլ գրառումներ» (lazy writes), որտեղ դա տեղին էր, որպեսզի հարթեցնենք տրաֆիկի կտրուկ աճերը։ Բացի այդ, աղյուսակի դաշտերը լրացնելիս մենք սահմանում ենք խիստ արագության սահմանափակումներ՝ կանխելու համար չափազանց մեծ գրառումների ճնշումը։
Խնդիր. մենք PostgreSQL-ում հայտնաբերել ենք մի քանի թանկարժեք հարցումներ։ Անցյալում այս հարցումներում ծավալի հանկարծակի աճերը սպառում էին մեծ քանակությամբ CPU, ինչը դանդաղեցնում էր ինչպես ChatGPT‑ը, այնպես էլ API հարցումները։
Լուծում. մի քանի թանկարժեք հարցումներ, օրինակ՝ այն հարցումները, որոնք միավորում են բազմաթիվ աղյուսակներ, կարող են զգալիորեն վատթարացնել կամ նույնիսկ շարքից հանել ամբողջ ծառայությունը։ Մենք պետք է անընդհատ օպտիմալացնենք PostgreSQL հարցումները՝ դրանց արդյունավետությունն ապահովելու և առցանց գործարքների մշակման (OLTP) հակաօրինաչափություններից խուսափելու համար։ Օրինակ՝ մենք մի անգամ հայտնաբերել ենք չափազանց ծախսատար հարցում, որը միացնում էր 12 աղյուսակներ, և այս հարցման գագաթնակետերը պատասխանատու էին նախկին բարձր ծանրության SEV-ների համար։ Մենք պետք է հնարավորության դեպքում խուսափենք բարդ բազմաաղյուսակային միացումներից։ Եթե միացումները անհրաժեշտ են, մենք սովորել ենք դիտարկել հարցման մասնատումը և բարդ միացման տրամաբանությունը տեղափոխել հավելվածի շերտ։ Այս խնդրահարույց հարցումներից շատերը գեներացվում են Օբյեկտ-հարաբերական քարտեզագրման (ORM) շրջանակների կողմից, ուստի կարևոր է ուշադիր վերանայել նրանց ստեղծած SQL-ը և համոզվել, որ այն գործում է սպասվածի պես։ PostgreSQL-ում նույնպես հաճախ կարելի է հանդիպել երկարատև անգործուն հարցումների։ Համակարգի ավտոմատ մաքրման արգելափակումը կանխելու համար անհրաժեշտ է սահմանել ժամանակի սահմանափակումներ, ինչպիսիք են idle_in_transaction_session_timeout-ը։
Խնդիր. եթե ընթերցման ռեպլիկան խափանվի, տրաֆիկը դեռ կարող է ուղղորդվել դեպի այլ ռեպլիկաներ։ Սակայն մեկ գրողի վրա հենվելը նշանակում է ունենալ մեկ խափանման կետ՝ եթե այն խափանվի, ամբողջ ծառայությունը կտուժի։
Լուծում․ ամենակարևոր հարցումները հիմնականում ներառում են միայն ընթերցման հարցումներ։ Հիմնական սերվերի խափանման հավանականությունը նվազագույնի հասցնելու համար մենք ընթերցման գործողությունները գրելու սերվերից տեղափոխեցինք կրկնօրինակներ՝ ապահովելով, որ այդ հարցումները կարողանան շարունակել մշակվել նույնիսկ հիմնական սերվերի խափանման դեպքում։ Թեև գրելու գործողությունները դեռևս կձախողվեն, ազդեցությունը նվազում է. դա այլևս SEV0 չէ, քանի որ ընթերցումները մնում են հասանելի։
Հիմնական սերվերի խափանումները նվազագույնի հասցնելու համար մենք օգտագործում ենք բարձր մատչելիության (HA) ռեժիմ՝ պահուստային սերվերով, որը մշտապես համաժամեցված է և միշտ պատրաստ է ստանձնել երթևեկությունը։ Եթե հիմնական սերվերը խափանվի կամ անհրաժեշտ լինի այն սպասարկման նպատակով օֆլայն հանել, մենք կարող ենք արագորեն առաջ մղել պահեստային սերվերը՝ նվազեցնելու դադարը։ Azure PostgreSQL թիմը զգալի աշխատանք է կատարել՝ ապահովելու համար, որ այս ձախողումները մնան անվտանգ և հուսալի նույնիսկ շատ բարձր ծանրաբեռնվածության դեպքում։ Կարդալու ռեպլիկաների ձախողումները կառավարելու համար մենք յուրաքանչյուր տարածաշրջանում տեղակայում ենք մի քանի ռեպլիկա՝ բավարար հզորության պահուստով՝ ապահովելով, որ մեկ ռեպլիկայի ձախողումը չհանգեցնի տարածաշրջանային անջատման։
Խնդիր. մենք հաճախ հանդիպում ենք իրավիճակների, երբ որոշ հարցումներ PostgreSQL-ի օրինակներում սպառում են ռեսուրսների անհամաչափ մեծ քանակ։ Սա կարող է հանգեցնել նույն օրինակների վրա աշխատող այլ աշխատանքային բեռների կատարողականության նվազմանը։ Օրինակ՝ նոր գործառույթի գործարկումը կարող է ներմուծել անարդյունավետ հարցումներ, որոնք մեծապես սպառում են PostgreSQL-ի պրոցեսորի ռեսուրսները՝ դանդաղեցնելով այլ կարևոր գործառույթների հարցումները։
Լուծում․ «Աղմկոտ հարևանի» խնդիրը մեղմելու համար մենք ծանրաբեռնվածությունները մեկուսացնում ենք հատուկ ինստանսների վրա՝ ապահովելու համար, որ ռեսուրսատար հարցումների հանկարծակի պիկերը չազդեն այլ երթևեկության վրա։ Մասնավորապես, մենք հարցումները բաժանում ենք ցածր և բարձր առաջնահերթության մակարդակների և դրանք ուղղորդում ենք առանձին ինստանսների։ Այս կերպ, նույնիսկ եթե ցածր առաջնահերթության ծանրաբեռնվածությունը դառնա ռեսուրսատար, այն չի վատթարացնի բարձր առաջնահերթության հարցումների կատարողականությունը։ Մենք նույն ռազմավարությունն ենք կիրառում տարբեր արտադրանքների և ծառայությունների համար, որպեսզի մեկ արտադրանքի գործունեությունը չազդի մյուսի կատարողականության կամ հուսալիության վրա։
Խնդիր. յուրաքանչյուր օրինակ ունի կապերի առավելագույն սահմանաչափ (5000 Azure PostgreSQL-ում)։ Հեշտ է սպառել կապերը կամ կուտակել չափազանց շատ անգործուն կապեր։ Մենք նախկինում ունեցել ենք միջադեպեր, որոնք առաջացել են կապի փոթորիկների հետևանքով, որոնք սպառել են բոլոր հասանելի կապերը։
Լուծում․ մենք տեղակայեցինք PgBouncer-ը որպես միջնորդ շերտ՝ տվյալների բազայի միացումները խմբավորելու համար։ Այն գործարկելով հայտարարության կամ գործարքների միավորման ռեժիմով, մենք կարող ենք արդյունավետորեն վերօգտագործել կապերը, զգալիորեն նվազեցնելով ակտիվ հաճախորդների կապերի քանակը։ Սա նաև նվազեցնում է կապի հաստատման հապաղումը՝ մեր չափորոշիչ փորձարկումներում միջին միացման ժամանակը 50 միլիվայրկյանից (մվ) նվազել է մինչև 5 մվ։ Միջտարածաշրջանային կապերը և հարցումները կարող են թանկ լինել, ուստի մենք պրոքսին, հաճախորդներին և կրկնօրինակները համատեղ տեղակայում ենք նույն տարածաշրջանում՝ ցանցային հավելյալ ծախսերը և կապի օգտագործման ժամանակը նվազագույնի հասցնելու համար։ Ավելին, PgBouncer-ը պետք է մանրակրկիտ կարգավորվի։ Անգործության ժամանակի սահմանափակումների նման կարգավորումները կարևոր են՝ միացումների սպառումը կանխելու համար։
Յուրաքանչյուր ընթերցված կրկնօրինակ ունի իր սեփական Kubernetes տեղակայումը, որն աշխատում է բազմաթիվ PgBouncer պոդերի վրա։ Մենք միևնույն Kubernetes Service-ի հետևում գործարկում ենք մի քանի Kubernetes տեղակայումներ, որը բաշխում է բեռը պոդերի միջև։
Խնդիր. քեշի բացթողումների հանկարծակի աճը կարող է առաջացնել ընթերցումների կտրուկ աճ PostgreSQL տվյալների բազայում՝ հագեցնելով պրոցեսորը և դանդաղեցնելով օգտատերերի հարցումները։
Լուծում. PostgreSQL-ի վրա ընթերցման ծանրաբեռնվածությունը նվազեցնելու համար մենք օգտագործում ենք քեշավորման շերտ՝ ընթերցման տրաֆիկի մեծ մասը սպասարկելու համար։ Սակայն, երբ քեշի հիթերի ցուցանիշները անսպասելիորեն նվազում են, քեշի բացթողումների հոսքը կարող է մեծ քանակությամբ հարցումներ ուղիղ փոխանցել PostgreSQL-ին։ Տվյալների բազայի ընթերցումների այս հանկարծակի աճը սպառում է զգալի ռեսուրսներ՝ դանդաղեցնելով ծառայությունը։ Քեշի բացթողումների փոթորիկների ժամանակ գերբեռնվածությունը կանխելու համար մենք կիրառում ենք քեշի կողպման (և վարձակալության) մեխանիզմ, որպեսզի միայն տվյալ բանալու բացթողում ունեցող ընթերցողը PostgreSQL-ից բերի տվյալները։ Երբ մի քանի հարցումներ բաց են թողնում նույն քեշի բանալու վրա, միայն մեկ հարցում է կողպեքը վերցնում և շարունակում տվյալները ստանալ ու քեշը վերալցնել։ Մնացած բոլոր հարցումները սպասում են, մինչև քեշը թարմացվի, այլ ոչ թե բոլորը միանգամից PostgreSQL-ին դիմեն։ Սա զգալիորեն նվազեցնում է տվյալների բազայի կրկնվող ընթերցումները և պաշտպանում է համակարգը կասկադային բեռնվածության կտրուկ աճերից։
Խնդիր. հիմնական հոսքը Write Ahead Log (WAL) տվյալները փոխանցում է յուրաքանչյուր կարդացված կրկնօրինակին։ Քանի որ ռեպլիկաների քանակը մեծանում է, հիմնական հանգույցը պետք է WAL-ը ուղարկի ավելի շատ ինստանսների, ինչը մեծացնում է թե՛ ցանցի թողունակության, թե՛ CPU-ի վրա ճնշումը։ Սա առաջացնում է ավելի մեծ և ավելի անկայուն կրկնօրինակման ուշացում, ինչը համակարգը դարձնում է ավելի դժվար հուսալիորեն մասշտաբավորել։
Լուծում․ mենք աշխատում ենք մոտ 50 ընթերցման կրկնօրինակներ տարբեր աշխարհագրական տարածաշրջաններում՝ հապաղումը նվազեցնելու համար։ Այնուամենայնիվ, ընթացիկ ճարտարապետության դեպքում հիմնականը պետք է WAL-ը հոսքագրի յուրաքանչյուր կրկնօրինակի։ Թեև այն ներկայումս լավ է մասշտաբավորվում շատ մեծ օրինակների տեսակների և բարձր ցանցային թողունակության դեպքում, մենք չենք կարող անվերջ շարունակել կրկնօրինակներ ավելացնել՝ առանց ի վերջո գերբեռնելու առաջնայինը։ Այս խնդիրը լուծելու համար մենք համագործակցում ենք Azure PostgreSQL թիմի հետ կասկադային ռեպլիկացիայի(բացվում է նոր պատուհանում) վրա, որտեղ միջանկյալ ռեպլիկաները փոխանցում են WAL-ը ներքևի ռեպլիկաներին։ Այս մոտեցումը թույլ է տալիս մեզ մասշտաբավորել մինչև հարյուրից ավելի կրկնօրինակներ՝ առանց ծանրաբեռնելու առաջնայինը։ Այնուամենայնիվ, այն նաև ներմուծում է լրացուցիչ գործառնական բարդություններ, մասնավորապես՝ ձախողման կառավարման հարցում։ Գործառույթը դեռ փորձարկման փուլում է. մենք կապահովենք, որ այն ամուր է և կարող է անվտանգ անցնել այլ համակարգ՝ նախքան այն արտադրական միջավայրում գործարկելը։
Խնդիր. հանկարծակի թրաֆիկի աճը որոշակի վերջնակետերում, թանկարժեք հարցումների ալիքը կամ կրկնափորձերի փոթորիկը կարող են արագ սպառել կարևոր ռեսուրսները, ինչպիսիք են CPU-ն, I/O-ն և կապերը, ինչը հանգեցնում է ծառայության լայնածավալ վատթարացման։
Լուծում. մենք իրականացրել ենք արագության սահմանափակում մի քանի շերտերում՝ հավելվածում, կապերի փուլի կառավարիչում, պրոքսիում և հարցումներում, որպեսզի կանխենք հանկարծակի թրաֆիկի աճը, որը կարող է գերծանրաբեռնել տվյալների բազայի ինստանսները և առաջացնել շղթայական խափանումներ։ Կարևոր է նաև խուսափել չափազանց կարճ կրկնափորձի միջակայքերից, որոնք կարող են առաջացնել կրկնափորձերի փոթորիկներ։ Մենք նաև բարելավեցինք ORM շերտը՝ արագության սահմանափակման աջակցություն ապահովելու և անհրաժեշտության դեպքում՝ որոշակի հարցման դայջեստներ ամբողջությամբ արգելափակելու համար։ Բեռնաթափման այս նպատակային ձևը թույլ է տալիս արագ վերականգնվել թանկարժեք հարցումների հանկարծակի աճերից։
Խնդիր. նույնիսկ սխեմայի փոքր փոփոխությունը, օրինակ՝ սյունակի տեսակի փոփոխությունը, կարող է առաջացնել ամբողջ աղյուսակի վերաշարադրում(բացվում է նոր պատուհանում)։ Այդ պատճառով մենք սխեմայի փոփոխությունները կիրառում ենք զգուշությամբ՝ սահմանափակելով դրանք թեթև գործողություններով և խուսափելով այնպիսիքներից, որոնք վերաշարադրում են ամբողջ աղյուսակները։
Լուծում. թույլատրվում են միայն թեթև սխեմայի փոփոխություններ, օրինակ՝ որոշ սյունակների ավելացում կամ հեռացում, որոնք չեն առաջացնում ամբողջ աղյուսակի վերաշարադրում։ Մենք սխեմայի փոփոխությունների համար կիրառում ենք խիստ 5-վայրկյանանոց ժամանակային սահմանափակում։ Ինդեքսների զուգահեռ ստեղծելն ու ջնջելը թույլատրվում է։ Սխեմայի փոփոխությունները սահմանափակվում են միայն առկա աղյուսակներով։ Եթե նոր ֆունկցիան պահանջում է լրացուցիչ աղյուսակներ, դրանք պետք է լինեն այլընտրանքային շարդավորված համակարգերում, օրինակ՝ Azure CosmosDB-ում, այլ ոչ թե PostgreSQL-ում։ Աղյուսակի դաշտը հետլրացնելիս մենք կիրառում ենք խիստ սահմանաչափեր՝ կանխելու գրառումների կտրուկ աճը։ Թեև այս գործընթացը երբեմն կարող է տևել մեկ շաբաթից ավելի, այն ապահովում է կայունություն և խուսափում է արտադրության վրա որևէ ազդեցություն ունենալուց։
Այս ջանքը ցույց է տալիս, որ ճիշտ նախագծման և օպտիմալացումների դեպքում Azure PostgreSQL-ը կարող է մասշտաբավորվել՝ սպասարկելու արտադրական ամենամեծ աշխատանքային ծանրաբեռնվածությունները։ PostgreSQL-ը կարդալու ծանրաբեռնված աշխատանքային բեռների համար մշակում է միլիոնավոր QPS՝ ապահովելով OpenAI-ի ամենակարևոր պրոդուկտների աշխատանքը, ինչպիսիք են ChatGPT‑ը և API հարթակը։ Մենք ավելացրեցինք գրեթե 50 ընթերցման կրկնօրինակ՝ միաժամանակ պահպանելով կրկնօրինակման լագը զրոյի մոտ, պահպանելով ընթերցման ցածր լատենտությունը աշխարհագրականորեն բաշխված տարածաշրջաններում և ստեղծելով բավարար հզորության տարածք ապագա աճը ապահովելու համար։
Այս մասշտաբավորումը գործում է՝ միաժամանակ նվազեցնելով հապաղումը և բարելավելով հուսալիությունը։ Մենք արտադրական միջավայրում հետևողականորեն ապահովում ենք ցածր երկնիշ միլիվայրկյան p99 հաճախորդի կողմի հապաղում և հինգ իննանոց հասանելիություն։ Եվ վերջին 12 ամիսների ընթացքում մենք ունեցել ենք ընդամենը մեկ SEV-0 PostgreSQL միջադեպ (այն տեղի է ունեցել ChatGPT ImageGen-ի վիրուսային մեկնարկի(բացվում է նոր պատուհանում) ժամանակ, երբ գրառման տրաֆիկը հանկարծակի աճեց ավելի քան 10 անգամ, քանի որ մեկ շաբաթվա ընթացքում գրանցվեց ավելի քան 100 միլիոն նոր օգտատեր։)
Թեև մենք գոհ ենք PostgreSQL-ի հետ մեր ձեռքբերումներից, մենք շարունակում ենք ընդլայնել դրա հնարավորությունները՝ ապահովելու համար, որ մենք ունենք բավարար հնարավորություններ ապագա աճի համար։ Մենք արդեն տեղափոխել ենք բաժանվող, գրառումների մեծ ծավալ ունեցող աշխատանքային բեռները մեր մասնատված համակարգեր, ինչպիսին է CosmosDB-ը։ Մնացած գրելաժամանակ պահանջող առաջադրանքներն ավելի դժվար է բաժանել. մենք դրանք նույնպես ակտիվորեն տեղափոխում ենք՝ PostgreSQL գլխավոր սերվերից գրելու բեռը հետագայում նվազեցնելու համար։ Մենք նաև համագործակցում ենք Azure-ի հետ՝ կասկադային ռեպլիկացիա ապահովելու համար, որպեսզի կարողանանք անվտանգ կերպով մասշտաբավորվել՝ զգալիորեն ավելացնելով ընթերցման ռեպլիկաների քանակը։
Առաջիկայում մենք կշարունակենք ուսումնասիրել լրացուցիչ մասշտաբավորման մոտեցումներ, ներառյալ՝ մասնատված PostgreSQL-ը կամ այլընտրանքային բաշխված համակարգերը, մեր ենթակառուցվածքային կարիքների աճին զուգընթաց։
Հեղինակ
Շնորհակալագրեր
Հատուկ շնորհակալություն Ջոն Լիին, Սիչենգ Լյուին, Չաոմին Յուին և Չենգլոնգ Հաոյին, ովքեր նպաստել են այս գրառմանը, ինչպես նաև ամբողջ թիմին, որը օգնեց մասշտաբավորել PostgreSQL-ը։ Մենք նույնպես ցանկանում ենք շնորհակալություն հայտնել Azure PostgreSQL թիմին՝ նրանց ամուր համագործակցության համար։


