OpenAI

23 ოქტომბერი, 2026

ინჟინერია

ონლაინ საცავის სწრაფი ზრდა ChatGPT‑ის მილიარდზე მეტი მომხმარებლისთვის (ნაწილი II)

როგორ გავაუმჯობესეთ Azure Cosmos DB ჩვენი აპლიკაციების შენახვის პლატფორმა Habitat-ში უპრეცედენტო ზრდის სამართავად.

ავტორები: ჯონ ლი, ჰრაჩია ჰაკობიანი და ჩაომინ იუ — ტექნიკური გუნდის წევრები

იტვირთება…

OpenAI-ს ყველა პროდუქტს მონაცემებზე სწრაფი, საიმედო წვდომა სჭირდება, რასაც ჩვენი შენახვის პლატფორმა Habitat უზრუნველყოფს. მან 40 გეოგრაფიულ რეგიონში მილიარდზე მეტ მომხმარებელს მილიწამებში უნდა უპასუხოს. ჩვენი ინფრასტრუქტურა განსაკუთრებული გამოწვევის წინაშე იდგა: მხარი დაეჭირა სწრაფი ზრდისა და ახალი სცენარებისთვის და ამავდროულად გაეუმჯობესებინა საიმედოობა, წარმადობა და პროდუქტის დეველოპერების მუშაობის ტემპი. ამის გადასაჭრელად ჩვენი ონლაინ შენახვის პლატფორმის არქიტექტურისა და ოპერირების ხელახლა გააზრება დაგვჭირდა. მუდმივად ვაფასებდით კომპრომისებს და ასეთი თანმიმდევრობით ვმოქმედებდით: ჯერ საკმარისი საიმედოობა პროდუქტების კრიტიკული ტრაფიკისთვის, შემდეგ საკმარისი სისწრაფე გლობალური მომხმარებლებისთვის და ბოლოს — გამართული მუშაობა უზარმაზარ მასშტაბზე.

ამ ორნაწილიან სერიაში ვხსნით, როგორ ვაქციეთ Habitat მარტივი კლიენტური ბიბლიოთეკისა და მონაცემთა ბაზისგან გლობალურად განაწილებულ შენახვის პლატფორმად, რომელიც 500 პეტაბაიტზე მეტ მონაცემს ემსახურება. I ნაწილი ეხებოდა Habitat-ის გარდაქმნას Python-ის კლიენტიდან სერვისად. მასში ასევე განვიხილეთ მეთოდები, რომლებმაც Python-ზე დაფუძნებული სერვისის ბევრისთვის პრაქტიკულად წარმოუდგენელ მასშტაბამდე განვითარება შეგვაძლებინა.

ამ პოსტში, II ნაწილში, განვიხილავთ, როგორ გავზარდეთ შენახვის საბაზისო კომპონენტის — Azure Cosmos DB-ის — მასშტაბი. Azure-ის გუნდთან მჭიდრო თანამშრომლობით მივიღეთ ერთობლივად მართული კონტეინერების ეფექტური მრავალმოიჯარიანი მიდგომა, რომელიც უზარმაზარ, გლობალურ მასშტაბზე წაკითხვის შესანიშნავ წარმადობას უზრუნველყოფს.

სურათი 01 · რა არის Habitat?

ონლაინ საცავის პლატფორმა

Habitat არის ონლაინ საცავის პლატფორმა, რომელიც OpenAI-ის პროდუქტებისთვის საჭირო ინფორმაციაზე სწრაფი და საიმედო წვდომის უზრუნველსაყოფად შევქმენით.

  • მოთხოვნა
  • პასუხი
  • ცვლილებები (CDC)

კლიენტები

ონლაინ საცავის პლატფორმა

საცავის რესურსები

  • ChatGPT
  • API
  • Codex
  • შიდა სერვისები
  • და სხვა

Habitat

  • კეშირებაკეშები
  • ACL-ის პოლიტიკებიავტორიზაცია
  • განთავსება და მონაცემთა ადგილმდებარეობამონაცემთა ადგილმდებარეობა
  • დაშიფვრამონაცემთა უსაფრთხოება
  • იზოლაციამრავალმომხმარებლიანობა
  • სიხშირის შეზღუდვამოთხოვნების ფორმირება
  • მარშრუტიზაციასქემის მოძიება · მონაცემთა ადგილმდებარეობა
  • Azure Cosmos DBონლაინ საცავი
  • Nanobaseონლაინ საცავი
  • Valkeyკეშები
  • ობიექტების საცავისაცავის რესურსები
CDC სერვისებიცვლილებების მონაცემთა აღრიცხვა
  • Databricks
  • Rockset
  • Kafka
  • და სხვა

მრავალმოიჯარიანობის საიმედოობის უზრუნველყოფა დიდ მასშტაბზე

კომპანიების ზრდასთან ერთად ინფრასტრუქტურის გუნდები ხშირად ერთმოიჯარიანი სისტემებიდან მრავალმოიჯარიან სისტემებზე გადადიან. ერთმოიჯარიანი მიდგომა, როცა პროდუქტის თითოეული ნაწილის გუნდი საკუთარ სისტემას მართავს, ამცირებს შეფერხებების გავრცელებას, მარტივად მიჯნავს პასუხისმგებლობებს და უზრუნველყოფს დატვირთვების იზოლაციას. გუნდებისა და პროდუქტის ნაწილების ზრდასთან ერთად ასეთი სისტემების შენახვა ძვირდება. ერთმოიჯარიანი მიდგომისას რესურსების დაგეგმვა თითოეული პროდუქტის გუნდს ევალება, რაც ხშირად საჭიროზე გაცილებით მეტი რესურსის გამოყოფას იწვევს.

ამის საპირისპიროდ, მრავალმოიჯარიანი მიდგომა მართვას მონაცემთა ბაზის ცენტრალურ გუნდს აბარებს, რომელსაც რესურსების გამოყოფის უკეთესი ცოდნა და გამოცდილება აქვს. თუმცა მრავალმოიჯარიანობას თავისი პრობლემები აქვს, მაგალითად, ხმაურიანი მეზობლები: ერთი მოიჯარე რესურსების უჩვეულოდ დიდ წილს მოიხმარს სხვების საზიანოდ.

Habitat-ში ყველა ეს კომპრომისი უნდა შეგვეფასებინა, რათა დიდი მასშტაბისთვის საიმედო და ეფექტიანი შენახვის სისტემა შეგვექმნა. დღეს Habitat OpenAI-ს მრავალი პროდუქტისთვის მონაცემთა ბაზის მრავალმოიჯარიანი შრეა, თუმცა წრე შემოვიარეთ: Azure Cosmos DB-ის ერთი მრავალმოიჯარიანი კონტეინერიდან ერთმოიჯარიანი საცავის კონტეინერებზე გადავედით, შემდეგ კი ნაგულისხმევ ვარიანტად ისევ მრავალმოიჯარიანი კონტეინერი დავაბრუნეთ. Habitat-ში მრავალმოიჯარიანობის განვითარების ჯერ კიდევ საწყის ეტაპზე ვართ: უამრავ სცენარს ვემსახურებით, თუმცა ამ სფეროში ინვესტიციის გადადება შევძელით Azure Cosmos DB-ის ჩაშენებული მექანიზმების ყველგან გამოყენებით, სადაც ეს შესაძლებელი იყო.

Azure Cosmos DB-ის კონტეინერების მოკლე მიმოხილვა

სანამ Azure Cosmos DB-სთან ჩვენს გამოცდილებას განვიხილავთ, რამდენიმე ძირითადი ცნება:

  • Azure Cosmos DB-ის ანგარიში განსაზღვრავს კონტეინერების ნაკრებსა და რეპლიკაციის პოლიტიკას

  • თითოეულ კონტეინერს გამოეყოფა მწარმოებლურობის გარკვეული მოცულობა, რომელიც იზომება მოთხოვნის ერთეულებით წამში (RU/s)

  • თითოეულ კონტეინერში მონაცემები ჩვეულებრივ, მითითებული ლოგიკური დანაყოფის გასაღებით ნაწილდება. თითოეულ ასეთ გასაღებს საცავისა და მწარმოებლურობის დოკუმენტირებული ლიმიტები აქვს

  • Azure Cosmos DB ლოგიკური დანაყოფის გასაღებებს უფრო მცირე რაოდენობის ფიზიკურ დანაყოფებზე ანაწილებს. იგი ფიზიკურ დანაყოფებს ყოფს, როცა საცავი ზღვარს აჭარბებს ან კონტეინერს გამოყოფილი მწარმოებლურობის შესანარჩუნებლად მეტი ფიზიკური დანაყოფი სჭირდება

I ეტაპი: Azure Cosmos DB-ის ჩაშენებულ მექანიზმებზე დაყრდნობა

თავდაპირველად კლიენტების ნებისმიერ დატვირთვას ვატარებდით და მის შესაკავებლად თითო ლოგიკური დანაყოფის გასაღებზე დეკლარირებულ 10 ათ. RU/s ლიმიტს ვეყრდნობოდით. დასაწყისში თითოეულ ანგარიშში Azure Cosmos DB-ის მხოლოდ ერთ ნაგულისხმევ კონტეინერს ვიყენებდით. ეს საკმაოდ კარგად მუშაობდა, თუმცა რამდენიმე მიზეზით პრობლემური აღმოჩნდა:

ლოგიკური დანაყოფის გასაღების ლიმიტები

API-ის საწყისი დიზაინის გამო ლოგიკური დანაყოფის გასაღების არჩევის შესაძლებლობა პირდაპირ კლიენტებს მივეცით. შედეგად, სხვადასხვა პროდუქტულ სცენარში ხშირად ემთხვევა ფართოდ გამოყენებული დანაყოფის გასაღებები, მაგალითად, user_id ან workspace_id. რადგან ეს სცენარები ერთი და იმავე ლოგიკური დანაყოფის გასაღებებზე Azure Cosmos DB-ის ლიმიტებს იზიარებდა, ასეთი დიზაინი კონკრეტული მომხმარებლისთვის ჯამურ მწარმოებლურობას ზღუდავდა.

Habitat-სა და Azure Cosmos DB-ზე გადასვლამდე Postgres-ის მასშტაბირებისას ხშირი პრობლემა იყო ის, რომ ძლიერ დატვირთული ორგანიზაციის ან გასაღების უამრავ მოთხოვნას — ერთი მოიჯარის არაპროპორციულად მაღალ დატვირთვას — მთელი მონაცემთა ბაზის მწყობრიდან გამოყვანა შეეძლო. მნიშვნელოვანი ერთობლივი ძალისხმევა მოხმარდა ამ გასაღებების ქეშირებასა და ქეშში მონაცემების არყოფნისას დროებითი ექსკლუზიური უფლებების მექანიზმის დანერგვას, რათა ქეშის აცდენებით წარმოქმნილ დატვირთვას საბაზისო მონაცემთა ბაზა არ გადაეტვირთა.

Figure 02a · Logical partition key limits

Different clients, the same partition key

Cosmos DB containerPhysical partitionPK: user-id-28104CapacityMemory / dreaming : capacity usedMemory / dreaming : capacity usedMemory / dreaming : capacity usedMemory / dreaming : capacity usedMemory / dreaming : capacity usedMemory / dreaming : capacity usedMemory / dreaming : capacity usedMemory / dreaming : capacity usedMemory / dreaming : capacity usedMemory / dreaming : capacity usedConversationsSuccess rateResponses returned in this animation loop—AuthSuccess rateResponses returned in this animation loop—Memory / dreamingSuccess rateResponses returned in this animation loop—

ხმაურიანი მეზობლები

მართალია, დოკუმენტაციაში მონაცემთა მოცულობისა და მწარმოებლურობის ლიმიტები ლოგიკური დანაყოფის გასაღებებს ეხება, მაგრამ რეალურად ეს ლიმიტები ფიზიკური დანაყოფის დონეზე მოქმედებს. პრაქტიკაში ეს ნიშნავს, რომ ლოგიკური დანაყოფები 10 000 RU/s-ს ვერ აღწევს. ამის ნაცვლად, ისინი ფიზიკური დანაყოფის ლიმიტებს იმავე დანაყოფზე განთავსებულ ყველა სხვა ლოგიკური დანაყოფის გასაღებთან იზიარებენ.

ამის გამო ხმაურიანი მეზობლები მრავალ დაუკავშირებელ ლოგიკური დანაყოფის გასაღებზე ახდენდნენ გავლენას: პროდუქტის ნიშური ფუნქციების მონაცემებზე მომუშავე დატვირთვები შესვლისა და რეგისტრაციის ძირითად პროცესებს აფერხებდა.

Figure 02b · Noisy neighbors

Different users, the same physical partition

Cosmos DB containerPhysical partitionPKs: user-id-28104, user-id-10384Conversations user-id-28104: capacity usedConversations user-id-28104: capacity usedConversations user-id-28104: capacity usedConversations user-id-28104: capacity usedConversations user-id-28104: capacity usedConversations user-id-28104: capacity usedConversations user-id-28104: capacity usedConversations user-id-28104: capacity usedConversations user-id-28104: capacity usedConversations user-id-28104: capacity usedConversationsuser-id-28104Success rateResponses returned in this animation loop—Conversationsuser-id-10384Success rateResponses returned in this animation loop—

სუსტი დანაყოფები

ფიზიკური დანაყოფის მწარმოებლურობის ლიმიტიც ცვალებადია და Azure Cosmos DB-ის კონტეინერისთვის გამოყოფილ ჯამურ მწარმოებლურობაზეა დამოკიდებული. კონტეინერისთვის გამოყოფილი მწარმოებლურობა მის ფიზიკურ დანაყოფებს შორის დაახლოებით თანაბრად ნაწილდება.

მონაცემთა მოცულობის ზრდისას ფიზიკური დანაყოფები იყოფა და მათი საერთო რაოდენობა იზრდება, ჯამური გამოყოფილი მწარმოებლურობა კი უცვლელი რჩება. შედეგად, მონაცემთა მოცულობის ზრდასთან ერთად მცირდება თითოეული დანაყოფის მწარმოებლურობის რეალური ლიმიტი.

დიდი მოცულობის, blob-ის მსგავსი მონაცემების შენახვისას ეს წარმოშობს პრობლემას: მხოლოდ საცავის ზრდაც კი ამცირებს აქტიური დატვირთვებისთვის ხელმისაწვდომ მწარმოებლურობას, მაშინაც, როცა მოთხოვნების სიხშირე და გამოყენება სტაბილურია.

Figure 02C · Weak partitions

The limit falls below demand

A partition splits when it reaches its storage limit. Each child receives half the throughput capacity.

Before split: 10K RU/s capacity

After split: 5K RU/s capacity × 2 partitions

RU/s05K6K10K200200429

II ეტაპი: დატვირთვების იზოლაციისა და ერთმოიჯარიანი მიდგომის გამოცდა

ცალკეული კონტეინერები ნაწილობრივ გვარდება დანაყოფის გასაღების ლიმიტებისა და ხმაურიანი მეზობლების პრობლემა. ცალკე კონტეინერების გამოყენებისას თითოეულს საკუთარი, დამოუკიდებელი ფიზიკური დანაყოფები შეიძლება გამოეყოს. ამ შემთხვევაში ხმაურიანი მეზობლები ან დანაყოფის გასაღებთა სივრცეში გადაფარვა მხოლოდ ამავე კონტეინერის დატვირთვებს შორისაა შესაძლებელი. ნაკლოვანება ისაა, რომ ახალი კონტეინერების გამოყოფა დამატებით შრომას მოითხოვს — თითოეულის რესურსები ცალ-ცალკე უნდა დაიგეგმოს. ამიტომ კონტეინერის შექმნა მხოლოდ სერვისის ან გამოყენების სცენარის ლოგიკურ საზღვარზე გვსურს.

ყველაზე კრიტიკული ახალი სცენარებისთვის, რომლებსაც მკაცრი იზოლაცია სჭირდებოდა, Azure Cosmos DB-ის ცალკე კონტეინერების გამოყენება დავიწყეთ. ამასთან ერთად გამოვიყენეთ სუსტი დანაყოფების სამართავი სკრიპტი, რომელიც თითოეული კონტეინერის ჯამურ გამოყოფილ მწარმოებლურობას მისი ფიზიკური დანაყოფების რაოდენობას უსადაგებდა. ასე არსებული პრობლემების უმეტესობა ავიცილეთ.

თუმცა, რადგან მუშაობა ნაგულისხმევი კონტეინერით დავიწყეთ, ბევრი ძველი, კრიტიკული სცენარი სამწუხაროდ იქვე დარჩა — მათ გადასატანად მონაცემთა მიგრაცია იყო საჭირო. კრიტიკული სერვისების დასაცავად, რომლებიც კვლავ საზიარო ნაგულისხმევ კონტეინერში შენახულ მონაცემებს იყენებდა, გუნდებს ხშირად ვურჩევდით, ახალი სერვისების ან პროდუქტის მსხვილი ფუნქციებისთვის ცალკე კონტეინერები შეექმნათ. მასშტაბის ზრდასთან ერთად ნაგულისხმევ კონტეინერზე დატვირთვაც იზრდებოდა და სამუშაო გარემოში ინციდენტებიც ხშირდებოდა. ნებისმიერი ახალი სერვისის ან პროდუქტის მსხვილი ფუნქციისთვის კონტეინერების გამოყოფა დავიწყეთ, მხოლოდ იმისთვის, რომ ნაგულისხმევი კონტეინერი დამატებითი დატვირთვისგან დაგვეცვა.

ამან მთლიანი საიტის მრავალი გათიშვა აგვარიდა და პრობლემების გავლენა ცალკეული ფუნქციის ან სერვისის შეფერხებამდე შეამცირა. თუმცა ახალი კონტეინერების გამოყოფის დამატებითმა ტვირთმა საბოლოოდ თავი იჩინა:

სტაბილური ჯამური ზრდის არარსებობა

ძველ საზიარო ნაგულისხმევ კონტეინერში რომელიმე ახალი სცენარის 0-დან 1 მილიონ QPS-მდე ზრდა ნაკლებად სავარაუდო იყო, რომ ჯამურ გამოყენებას მნიშვნელოვნად შეცვლიდა. იზოლირებულ კონტეინერში კი ახალი სცენარის 0-დან 1 მილიონ QPS-მდე ზრდა შესაძლოა 1 000-ჯერ მეტ დატვირთვას ნიშნავდეს იმ საწყის დონესთან შედარებით, რომელსაც მხოლოდ შიდა ტესტირება ქმნიდა.

გამოყოფილი კონტეინერების გამოყენებისას გუნდებს უნდა ხსომებოდათ, რომ გაშვებისთვის მოსალოდნელი მწარმოებლურობა წინასწარ გამოეყოთ. პროდუქტის გუნდები ხშირად უშვებდნენ ფუნქციებს სამუშაო გარემოში და ავიწყდებოდათ რესურსების წინასწარ გაზრდა. გაშვების დღეს კი ინციდენტებზე რეაგირების შეხვედრებზე ბოლო წუთს ვცდილობდით კონტეინერების მასშტაბის გაზრდას.

დატვირთვების გაერთიანება მრავალმოიჯარიანი სისტემების ერთ-ერთი მთავარი უპირატესობაა, რომელსაც კონტეინერების ამ სტრატეგიით უკეთესი იზოლაციის სანაცვლოდ ვკარგავთ.

Figure 03 · Lack of stable aggregate growth

The same workload, different headroom

1K RU/s during load testing → 1M RU/s at launch

Shared container

100M RU/s capacity · 80% utilized

Load test

1K20M=

0.005%

of headroom

Launch

1M20M=

5%

of headroom

New dedicated container

10K RU/s capacity · no other workloads

Load test

1K10K=

10%

of headroom

Launch

1M10K=

10,000%

of headroom

რესურსების დაგეგმვა

დროთა განმავლობაში გამოყოფილი კონტეინერების გამოყენების მონიტორინგიც პროდუქტის სიღრმისეულ ცოდნას მოითხოვდა — როდის შეიცვლებოდა ან გაიზრდებოდა ტრაფიკი.

შეგვიძლია შევთავაზოთ მართვის შრის მარტივი სკრიპტი, რომელიც ზრდის ტენდენციების მიხედვით თითოეული კონტეინერის გამოყოფილ მწარმოებლურობას გაზრდის. თუმცა სტაბილური ჯამური ზრდის გარეშე სწორი მასშტაბირებისთვის რესურსების დაგეგმვაში OpenAI-ს თითქმის ყველა პროდუქტის გუნდის ჩართვა გახდა საჭირო.

ორგანიზაციული მასშტაბის ზრდას ამ მიდგომამ ვერ გაუძლო: სერვისებზე პასუხისმგებელი გუნდები Azure Cosmos DB-ის რესურსების გამოყოფას ძალიან განსხვავებული გულმოდგინებით ეკიდებოდნენ.

III ეტაპი: ნაგულისხმევად მრავალმოიჯარიანობა, მონაცემთა გადაადგილების შესაძლებლობით

ორგანიზაციის ზრდასთან ერთად ამ საოპერაციო პრობლემების მართვა სულ უფრო რთულდებოდა. დაგეგმვაზე პასუხისმგებელი ერთი ცენტრალური გუნდის არარსებობის გამო ბევრი გუნდი რესურსებს არასათანადოდ გეგმავდა. შედეგად, ისევ მრავალმოიჯარიან გადაწყვეტას დავუბრუნდით და Azure-ის გუნდთან მჭიდრო თანამშრომლობით, საზიარო მოიჯარეობის არქიტექტურაში ჩვენი საწყისი პრობლემების გამოსწორებაზე ვიმუშავეთ:

ძლიერ დატვირთული გასაღებების შეზღუდვა

ყველაზე დატვირთული გასაღებების პირველ რიგში შეზღუდვა ხელს უშლის ხმაურიან მეზობლებს, ფიზიკური დანაყოფის მთელი ხელმისაწვდომი მწარმოებლურობა მოიხმარონ. ეს ამცირებს ხმაურიანი მეზობლის ეფექტს, როცა ერთმა დატვირთულმა გასაღებმა შეიძლება მთელ საიტზე იმოქმედოს.

მომსახურების ხარისხი (QoS)

ანალოგიურად, მოთხოვნების დონეებად დაყოფაზე დაფუძნებული QoS ხელს უშლის ოფლაინ დატვირთვებს, მაგალითად, მასობრივ ჩასმას ან მონაცემების ამოღებას, ფიზიკური დანაყოფის მთელი მწარმოებლურობა მოიხმარონ. ამ დატვირთვების მოთხოვნებს დაბალ პრიორიტეტს ვანიჭებთ, ამიტომ ჯერ ისინი იზღუდება. ამით თავიდან ვიცილებთ უფრო მაღალი პრიორიტეტის ინტერაქტიული მოთხოვნების შეზღუდვას, რომლებიც საბოლოო მომხმარებლებს ემსახურება.

უსერვერო რეჟიმი

Azure Cosmos DB-ს უკვე ჰქონდა უსერვერო რეჟიმი, რომელიც წინასწარ გამოყოფილი რესურსების რეჟიმში წარმოქმნილ სუსტი დანაყოფების პრობლემას მოაგვარებდა. თუმცა მას მნიშვნელოვანი ნაკლი ჰქონდა: მასშტაბი მხოლოდ საცავის გამოყენების მიხედვით იზრდებოდა, ხოლო RU-ის გამოყენება თითო ფიზიკურ დანაყოფზე 5 ათ. RU/s-ით იზღუდებოდა. ეს სუსტი დანაყოფების პრობლემას მოაგვარებდა, მაგრამ RU-ზე დიდი მოთხოვნის მქონე სცენარების მასშტაბირებას შეგვიზღუდავდა.

Azure Cosmos DB-ის გუნდმა ჩვენთვის შექმნა გაუმჯობესებული უსერვერო რეჟიმი: თითოეული ფიზიკური დანაყოფი 10 ათ. RU/s-მდე მასშტაბირდება, ხოლო საცავის გამოყენებაზე დაფუძნებულ გაყოფას დაემატა RU-ის გამოყენებაზე დაფუძნებული გაყოფაც. ამან კონტეინერების ხელით მონიტორინგისა და მასშტაბირების საჭიროება მოგვიხსნა.

ამ ცვლილებებით ისევ ერთი საზიარო კონტეინერის გამოყენებას დავუბრუნდით. ამან პროდუქტის გუნდებს მნიშვნელოვნად გაუმარტივა რესურსების როგორც წინასწარი, ისე მიმდინარე დაგეგმვა და ამავდროულად დატვირთვებს შორის იზოლაცია შეინარჩუნა. მომდევნო თვეებში რესურსების გამოყოფასთან ან ხმაურიან მეზობლებთან დაკავშირებული ინციდენტები არ გვქონია, მიუხედავად პროდუქტის განვითარების დაჩქარებისა.

მეტი საიმედოობა ერთობლივი მართვით

როცა კომპანიები OpenAI-ს მასშტაბს აღწევს, მართული სერვისები ნაკლებად „მართული“ ხდება. ბევრი დატვირთვა ღრუბლოვანი პროვაიდერის ინფრასტრუქტურისთვის უჩვეულო შემთხვევად იქცევა. როცა OpenAI Azure Cosmos DB-ის ერთ-ერთი უმსხვილესი მომხმარებელი გახდა, მისი წარმატებული ოპერირებისთვის სხვა მიდგომა დაგვჭირდა: საერთო ტესტები და მონიტორინგის პანელები, ინჟინრებს შორის პირდაპირი კავშირი და ერთობლივი პასუხისმგებლობა იმ გაუმართაობებზე, რომლებიც მხოლოდ ჩვენს მასშტაბზე ჩნდება. დღეს Azure Cosmos DB-ის ჩვენი უდიდესი ანგარიში ათეულობით პეტაბაიტ მონაცემს ინახავს და 20 მილიონ QPS-ზე მეტს ემსახურება. ჩვენი ინფორმაციით, ერთადერთი კომპანია ვართ, რომელმაც Azure Cosmos DB ამ მასშტაბზე დანერგა.

2024 წლის ბოლოს რეგიონულმა შეფერხებამ ნათლად დაგვანახა, რატომ იყო ასეთი თანამშრომლობა აუცილებელი. მაშინ ელექტროენერგია გაითიშა Azure-ის იმ ძირითად რეგიონში, სადაც Azure Cosmos DB-ის ჩვენი ერთ-ერთი უდიდესი ანგარიში იყო განთავსებული. სარეზერვო რეგიონზე გადართვისას აღმოვაჩინეთ, რომ ჩვენი უდიდესი ანგარიშების მეორეულ რეგიონში გადატანას რამდენიმე საათი დასჭირდებოდა — ჩვენს მასშტაბზე ეს არც ჩვენს გუნდს ჰქონდა გამოცდილი და არც Azure Cosmos DB-ის გუნდს.

დაახლოებით ერთი თვის შემდეგ, ამ ანგარიშების თავდაპირველ რეგიონში დაბრუნებისას, კიდევ ერთი სერიოზული შეფერხება გამოვიწვიეთ. თავდაპირველ რეგიონთან კავშირების ერთბაშად დამყარებამ ამ რეგიონის Azure Cosmos DB-ის კარიბჭე გადატვირთა. კარიბჭის რეჟიმში მომუშავე Azure Cosmos DB-ის კლიენტის გადართვის მექანიზმის თავისებურების გამო ყველა კლიენტი დაუყოვნებლივ ამყარებდა კავშირს თავდაპირველ რეგიონთან და იქ მოთხოვნებს გზავნიდა, მიუხედავად იმისა, რომ რეგიონში ფიზიკური დანაყოფების მხოლოდ ნაწილი იყო დაბრუნებული.

ყოველი შეფერხებისას OpenAI და Azure ინციდენტების მართვის საკუთარ პროცედურებს მიჰყვებოდნენ; გამოვავლინეთ ძირეული მიზეზები და დავნერგეთ შესწორებები. თუმცა ეს შეფერხებები უფრო ფართო სისტემური პრობლემის ნიშნები იყო — ჩვენი და Azure Cosmos DB-ის გუნდების მუშაობისა და ტესტირების მიდგომებს შორის. თავდაპირველად მართული სერვისების გამოყენება სწრაფ მუშაობასა და ბიზნესმიზნებზე კონცენტრირებაში გვეხმარებოდა. დიდ მასშტაბზე მართული სერვისები ნაკლებად მართული ხდება და პროვაიდერთან ღრმა ინტეგრაციას მოითხოვს ყველა დონეზე — დიზაინიდან ოპერირებამდე.

დღეს Habitat-ისა და Azure-ის საინჟინრო გუნდები ერთობლივად აკვირდებიან Habitat-ის ყველა შრეს — ჩვენი სერვისებიდან Azure Cosmos DB-ის ფიზიკური საცავის შრეებამდე. ცვლილებებს ვამუშავებთ და ვტესტავთ Azure Cosmos DB-ის ანგარიშზე, რომელიც სამუშაო გარემოს მასშტაბისაა, თუმცა თავად სამუშაო გარემოს არ წარმოადგენს. ერთობლივად ვტესტავთ და ვხვეწთ SDK-ებს, ასევე ვადგენთ Azure Cosmos DB-ის ანგარიშების მასშტაბისა და ზომის განსაზღვრის საუკეთესო პრაქტიკებს. ჩვენს ინჟინრებს Teams-ით ერთმანეთთან პირდაპირი კავშირი აქვთ; ასევე შეგვიძლია მორიგე ინჟინრებს უშუალოდ გავუგზავნოთ საგანგებო შეტყობინება, მხარდაჭერის საფეხურების გავლის გარეშე.

გასულ წელს ერთობლივად ბევრი ვიმუშავეთ Azure Cosmos DB-ის მართვის შრისა და კარიბჭის მასშტაბირებადობის გასაუმჯობესებლად. მეტამონაცემების დანაყოფის დასაცავად კარიბჭეს დავუმატეთ დატვირთვისგან დაცვა და Azure Cosmos DB-ის სხვადასხვა მეტამონაცემის ქეშირება. კავშირების პულითა და მათი უფრო ხშირი ხელახალი გამოყენებით შევამცირეთ Python-ზე მომუშავე habitat-service პროცესებისგან მომდინარე დატვირთვა; სადაც შესაძლებელი იყო, დატვირთვები ერთად განვათავსეთ, კრიტიკული დატვირთვები კი სხვადასხვა VPC-ით გამოვყავით ოფლაინ დატვირთვებისგან.

გასულ წელს ამ დონის ერთობლივ საინჟინრო მუშაობას გადამწყვეტი მნიშვნელობა ჰქონდა ჩვენი Azure Cosmos DB-ის სტაბილურობისთვის. ნებისმიერი საკმარისად დიდი ან კრიტიკული სისტემა ასეთ გუნდურ მუშაობას მოითხოვს: პასუხისმგებლობის სფეროებს შორის ბარიერების მოშლასა და ორგანიზაციულ საზღვრებს მიღმა თანამშრომლობას.

წარმადობის გაუმჯობესება გლობალური მასშტაბით

როგორც I ნაწილში აღვნიშნეთ, ჩვენი ძირითადი პრინციპია: ჯერ აამუშავე, შემდეგ ააჩქარე, ბოლოს გააიაფე. ჯერ საიმედოობა, შემდეგ წარმადობა, ბოლოს კი ეფექტიანობა. Habitat OpenAI-სთვის კრიტიკულ ინფრასტრუქტურად იქცა, ამიტომ პირველი პრიორიტეტი მისი საიმედოობის უზრუნველყოფა იყო. 2025 წელს, სისტემის დასტაბილურებისა და OpenAI-ს გლობალური გაფართოების კვალდაკვალ, მომხმარებლებისა და პროდუქტის გუნდებისთვის შემდეგ დაბრკოლებად დაყოვნება იქცა.

გამოთვლითი და საცავის რესურსები ხშირად სხვადასხვა რეგიონში იყო განთავსებული, ამიტომ რეგიონთაშორისი მოთხოვნები გარდაუვალი იყო.

Figure 04 · Improving performance at a global scale

Global traffic

Compute and storage capacity were often located in different regions, making cross-region requests unavoidable.

ComputeStorageIllustrative routes · Longer journeys take more time

გამოთვლითი რესურსებისა და საცავის გეოგრაფიული მდებარეობები მხოლოდ საილუსტრაციოდ არის ნაჩვენები.

დაყოვნება მნიშვნელოვნად იცვლებოდა იმის მიხედვით, სად ინახებოდა მონაცემები და სად მუშავდებოდა მოთხოვნა. Habitat-ის მოთხოვნების დასაჩქარებლად პროდუქტის დეველოპერები იყენებდნენ დამატებით ქეშირებას კლიენტის მხარეს, მოთხოვნების დაჯგუფებას, მონაცემთა ბაზაში წაკითხვისა და ჩაწერის მინიმუმამდე შემცირებას და, სადაც შესაძლებელი იყო, სამუშაოს კრიტიკული გზიდან გატანას. ამან წარმოშვა საინტერესო პროდუქტული მიდგომები, რომლებიც მონაცემთა ბაზის პრობლემებისადმი უფრო მდგრადი იყო. თუმცა პროდუქტები გართულდა და მათი დახვეწა შენელდა: ვერ შესრულდა Habitat-ის მიზანი — ხელი შეეწყო პროდუქტის სწრაფი განვითარებისთვის მონაცემთა ბაზის სიღრმისეული ცოდნის საჭიროების გარეშე.

2026 წელს ამას დიდ ყურადღებას ვუთმობთ. შევიმუშავეთ მრავალშრიანი სტრატეგია წაკითხვის წარმადობის გასაუმჯობესებლად — წაკითხვაზე Habitat-ის მოთხოვნების 90%-ზე მეტი მოდის:

მონაცემები მომხმარებლებთან ახლოს შეინახეთ, როცა რესურსები ამის საშუალებას იძლევა

მომხმარებლებისთვის, რომლებსაც მონაცემთა ადგილმდებარეობის მოთხოვნები აქვთ, Azure Cosmos DB-ის რამდენიმე ანგარიში გვაქვს მსოფლიოს სხვადასხვა Azure რეგიონში. მომხმარებელთან ახლოს მონაცემების განთავსება დაყოვნებას ამცირებს და გამოყენების გამოცდილებას აუმჯობესებს მაშინაც, როცა მონაცემთა ადგილმდებარეობის მკაცრი მოთხოვნები არ არსებობს.

პრაქტიკაში, მონაცემთა ადგილმდებარეობის მოთხოვნებით გათვალისწინებული შემთხვევების გარდა, ამას ფართოდ ვერ ვახერხებთ, რადგან განთავსებას ღრუბლოვანი ინფრასტრუქტურის ფიზიკური რესურსები ზღუდავს. ჩვენი მონაცემების მოცულობის გამო, ბევრ რეგიონში ვერ ეტევა უზარმაზარი საცავი, რომელიც მომხმარებელთა ტრაფიკის შესაბამის წილს სჭირდება.

რეგიონებში, სადაც მონაცემთა ცენტრების რესურსები, ელექტროენერგია ან გაგრილება შეზღუდულია, ზოგჯერ პირდაპირი არჩევანის წინაშე ვდგებით: რესურსი ახლოს განთავსებული საცავისთვის გამოვყოთ და Habitat-ის დაყოვნება შევამციროთ, თუ დამატებითი გამოთვლებისთვის გამოვიყენოთ და საცავის მოთხოვნები უფრო შორს გავგზავნოთ.

შედეგად, განთავსების გადაწყვეტილებები ხშირად პროდუქტულ კომპრომისს გულისხმობს: ა) სხვადასხვა პროდუქტისთვის და მომხმარებელთა ჯგუფისთვის დაყოვნების ოპტიმიზაციასა და ბ) საცავისა და გამოთვლითი რესურსების მოცულობას შორის.

ფართოდ გაამრავლეთ მხოლოდ ყველაზე მცირე და დაყოვნებისადმი ყველაზე მგრძნობიარე მონაცემთა ნაკრებები

იმ დატვირთვებისთვის, სადაც დაყოვნებას გადამწყვეტი მნიშვნელობა აქვს — მაგალითად, ყოველი მოთხოვნისთვის საჭირო ავთენტიფიკაციის მეტამონაცემებისთვის — გამოთვლით რესურსებსა და Habitat-ს შორის RTT-ს ვამცირებთ Azure Cosmos DB-ის ანგარიშებით, რომლებსაც მრავალ მეორეულ რეგიონში აქვთ რეპლიკები. ზოგი ანგარიშის რეპლიკაცია Azure-ის ყველა იმ 40 რეგიონში ხდება, სადაც ტრაფიკს ვემსახურებით; სხვებისა — თითო კონტინენტზე სულ მცირე ერთ რეგიონში.

Habitat-ში სასურველზე ადრე მოგვიწია მონაცემთა გადაადგილებისა და მარშრუტიზაციის მომხმარებლისთვის შეუმჩნეველი შრის შექმნა, რათა მონაცემთა ნაკრებები განსხვავებული რეპლიკაციის ტოპოლოგიის მქონე ანგარიშებს შორის გადაგვეტანა.

თუმცა ეს მიდგომაც საბოლოოდ რესურსებით იზღუდება და ამიტომ მხოლოდ რამდენიმე საგანგებოდ შერჩეულ მონაცემთა ნაკრებს მოიცავს.

დანარჩენისთვის ინტეგრირებულ ქეშირებას დაეყრდენით

Habitat-ის დატვირთვებში წაკითხვა მკვეთრად ჭარბობს: აპლიკაციები მუდმივად იღებენ პარამეტრებს, მდგომარეობასა და სხვა თვისებებს. ტრაფიკის არაპროპორციულად დიდი წილი ხშირად გამოყენებული ტიპების შედარებით მცირე სამუშაო ნაკრებზე მოდის. ამიტომ სისტემა განსაკუთრებით კარგად ერგება განაწილებულ ქეშირებას. ქეშირება ერთ რეგიონშიც აუმჯობესებს წარმადობას, მაგრამ რამდენიმე რეგიონში მუშაობისას სარგებელი კიდევ უფრო იზრდება, რადგან მას რეგიონთაშორისი დაყოვნების „დამალვა“ შეუძლია.

Habitat-ში განაწილებული გვერდითი ქეშირების შრე ჩავაშენეთ. იგი ახლახან გამოყენებული ობიექტებისა და კავშირების ასლებს ინახავს Valkey-ის სერვერებზე, რომლებიც ჩვენს ინფრასტრუქტურაში მომხმარებელთა მოთხოვნების დამუშავების ადგილებთან ახლოსაა განთავსებული. როგორც წესი, ასეთი ქეშები იყენებს TTL-ს, რომელიც ქეშში მოხვედრის სიხშირესა და მონაცემთა მოძველებას შორის კომპრომისს განსაზღვრავს. მოკლე TTL ამცირებს მოძველებას, მაგრამ ასუსტებს ქეშირების სარგებელს: ელემენტებს ქეშში ვადა სწრაფად გასდის და მათი ხელახლა მიღება უფრო ხშირად ხდება საჭირო. ხანგრძლივი TTL ზრდის ქეშში მოხვედრის სიხშირეს, მაგრამ მოძველებული მონაცემები უფრო დიდხანს გაიცემა, რაც გამოყენების გამოცდილებას აუარესებს და პროდუქტის ქცევას არაპროგნოზირებადს ხდის.

სხვა მიდგომაა ქეშის აშკარა გაუქმება მაშინ, როცა აპლიკაცია იმავე საბაზისო მონაცემებზე ჩაწერის ოპერაციებს ასრულებს. ეს მნიშვნელოვნად აუმჯობესებს ქეშირებული მონაცემების აქტუალურობას, თუმცა სწორად დანერგვა რთული შეიძლება იყოს. ამ შემთხვევაშიც რჩება გამონაკლისები, მაგალითად, ნაწილობრივი გაუმართაობა, რის გამოც ქეში მოძველებული რჩება. მრავალრეგიონული განთავსება პრობლემებს ამძაფრებს: რეგიონთაშორისი ქსელები ნაკლებად საიმედოა, ქეშის განახლება და საბაზისო საცავის რეპლიკაცია კი ერთმანეთს ეჯიბრება. TTL-ის დამატება მოძველების მაქსიმალურ ხანგრძლივობას ზღუდავს, თუმცა ზემოთ აღწერილი კომპრომისი კვლავ რჩება.

ქეშის გაუქმებისთვის უფრო დახვეწილი მიდგომა ავირჩიეთ, Meta-ს TAO-ს მსგავსი სისტემების მაგალითზე. Habitat-ის ინტეგრირებული ქეში Azure Cosmos DB-ის ცვლილებათა ნაკადით მონაცემთა ცვლილებების აღრიცხვას (CDC) იყენებს და გაუქმების შეტყობინებებს გლობალურად წამებში ავრცელებს. ასე ქეშში მოხვედრის სიხშირე მაღალია, მოძველება კი — მცირე. ჩვენი ინფრასტრუქტურის სერვისი ამ ცვლილებათა ნაკადს კითხულობს და საბაზისო მონაცემების განახლებისას ადგილობრივ ქეშებში შესაბამის ჩანაწერებს აუქმებს. ამიტომ შემდეგი წაკითხვისას მონაცემი ქეშში აღარ ხვდება და ქეში მისი უახლესი ვერსიით ივსება.

პროქსის ზედნადები დანახარჯის შემცირება Rust-ით

დაყოვნება მნიშვნელოვნად შევამცირეთ თავად Habitat-ის სერვისშიც: კოდი Rust-ზე გადავწერეთ, რომელიც თავდაპირველ Python-ზე სწრაფია, და ამით ზედნადები დანახარჯი მოვხსენით.

ამ ცვლილებებმა ერთობლივად შეამცირა წაკითხვის გლობალური p50 დაახლოებით 120 მწმ-დან 10 მწმ-მდე — 12-ჯერ გააუმჯობესა მაჩვენებელი მას შემდეგ, რაც ამ წლის დასაწყისში წარმადობაზე გავამახვილეთ ყურადღება.

Figure 05 · Improving performance at a global scale

p50 latency for reads

Three major design changes improved read latency

roughly 120 ms → roughly 10 ms

12x improvement

Milliseconds020406080100120140160დრო123
  1. critical data replicated into nearby geos
  2. in-region caching launched
  3. rust rewrite launched

ქეშირებამ მედიანური დაყოვნება მკვეთრად შეამცირა, თუმცა ყველაზე ნელ მოთხოვნებს კვლავ სჭირდება არაქეშირებული მონაცემების საბაზისო საცავიდან მიღება, ხშირად შორეული რეგიონებიდან. რესურსების მატებასა და საცავის ეფექტიანობის გაუმჯობესებასთან ერთად უფრო ფუნდამენტური გამოწვევის გადაჭრას ვგეგმავთ: მონაცემების თავიდანვე ახლოს განთავსებას იმ ადგილთან, საიდანაც მათზე წვდომა მოხდება.

მონაცემთა ცვლილებების აღრიცხვის მასშტაბირება

საიმედო და მასშტაბირებადი CDC — მონაცემთა ბაზაში მომხდარი ცვლილებების სხვა სისტემებში გავრცელება — კრიტიკულად მნიშვნელოვანია არა მხოლოდ Habitat-ის ქეშირების სტრატეგიისთვის. ათასობით კონტეინერსა და მილიონობით დანაყოფში წამში აღრიცხული მილიონობით ცვლილება Kafka-ს ასზე მეტ თემაში გადის. ეს ცვლილებები ასევე უზრუნველყოფს მონაცემთა საბოლოო თანხვედრის პრინციპით მოქმედი მეორეული ინდექსების, მონაცემთა გადატანის პროცესების, ოფლაინ ანალიტიკისა და რეალურ დროში მოქმედი სხვა პროდუქტული ფუნქციების მუშაობას.ჩვენი საბაზისო ინფრასტრუქტურის გლობალურ ზრდასთან ერთად სტრიქონების ცვლილებებისთვის თვალყურის დევნება სულ უფრო რთულდება. თუ კლიენტს სურს, დაარეგისტრიროს ფუნქცია, რომელიც მისთვის საჭირო ტიპის სტრიქონების ყოველი ცვლილებისას გამოიძახება, ჯერ უნდა დაადგინოს, რომელ Cosmos ანგარიშებსა და კონტეინერებში ინახება მისი მონაცემები და შესაბამის რეგიონებში გაშვებული CDC სერვისებიდან რომელი აკვირდება ამ კონტეინერებს. ასევე, დატვირთვას სათანადოდ უნდა მოარგოს CDC-ის სამუშაო პროცესების, Kafka-სა და მონაცემთა მიმღები საკუთარი პროცესის რესურსები.ჩვენი CDC პლატფორმის მიზანია, პროდუქტის დეველოპერებს ეს სირთულეები აარიდოს და მარტივი ინტერფეისი შესთავაზოს: კლიენტი არეგისტრირებს ფუნქციას, რომელიც მისი მონაცემების სტრიქონების ცვლილებისას უნდა გამოიძახოს სისტემამ, საჭირო ტექნიკურ ინფრასტრუქტურასა და მასშტაბირებას კი ჩვენ ვუზრუნველყოფთ.

შიდა მართვის შრე მუდმივად უზრუნველყოფს ყველა საჭირო კონტეინერის ცვლილებათა აღრიცხვას, ირჩევს წასაკითხ Cosmos რეგიონებს და სამუშაოს ეფექტიანად ანაწილებს ათასობით სამუშაო პროცესს შორის რამდენიმე გეოგრაფიულ რეგიონში. რეპლიკის რეგიონებისა და ნაკადის დაბალპრიორიტეტიანი წაკითხვის გამოყენება Habitat-ის დაყოვნებისადმი მგრძნობიარე ტრაფიკს ცვლილებათა ფონური აღრიცხვის დატვირთვისგან იცავს. ასეთი ზომის სისტემაში მუდმივად ხდება სამუშაო პროცესების ავარიული შეწყვეტა, კონტეინერის პრობლემები, დროებითი უფლებების საცავის შეცდომები, არასწორი კონფიგურაცია და მიმღები სისტემების გაუმართაობა. გავამყარეთ CDC-ის სამუშაო პროცესების სასიცოცხლო ციკლისა და დროებითი უფლებების მართვა, ნაკადებს შორის გაუმართაობები გამოვაცალკევეთ და კონფიგურაციის ცვლილებებისა და დანერგვის დამცავი მექანიზმები შევქმენით. მიუწოდებელი შეტყობინებების რიგებს ვიყენებთ, რათა მიწოდების მუდმივმა შეცდომებმა რიგის დასაწყისი არ დაბლოკოს. რეგიონული გათიშვისას მკითხველ პროცესებს Cosmos-ის ალტერნატიულ რეგიონებზე ვრთავთ. ჩვენს მასშტაბზე Azure-ის CDC SDK-ის შეცვლაც კი დაგვჭირდა საკონტროლო წერტილების შენახვის გასაუმჯობესებლად: მათ მეხსიერებაში ვაჯგუფებთ და საცავში მხოლოდ პერიოდულად ვწერთ.

მართალია, Habitat-ში Azure Cosmos DB-ის შიდა გამოყენება რთულია, მაგრამ მისი მთავარი ღირებულება ყოველთვის იყო პროდუქტის დეველოპერებისთვის ინფრასტრუქტურის დეტალების დაფარვა, რათა განვითარება დაჩქარებულიყო. ჩვენი CDC პლატფორმაც იმავე მიზანს ემსახურება.

სამომავლო გეგმები

მცირე გუნდმა სწრაფად მზარდი შენახვის პლატფორმის მხარდაჭერა შეძლო: შენახვის API განზრახ შეზღუდული დატოვა, განაგრძო Python-ის სერვისის მასშტაბირება და პრიორიტეტი ყველაზე გადაუდებელ საინჟინრო გამოწვევებს მიანიჭა. ჯერ პროდუქტების კრიტიკული ტრაფიკის საიმედოობაზე გავამახვილეთ ყურადღება, შემდეგ — გლობალური მომხმარებლებისთვის წაკითხვის წარმადობაზე, ბოლოს კი — დიდ მასშტაბზე საოპერაციო ეფექტიანობაზე. ამ მიდგომამ სწრაფი ზრდა და ახალი სცენარების მხარდაჭერა გახადა შესაძლებელი და ამავდროულად გააუმჯობესა საიმედოობა, წარმადობა და პროდუქტის განვითარების ტემპი.

Habitat-ისა და საუბრების საცავის მომდევნო მილიარდ მომხმარებელზე გასაფართოებლად უნდა გადავჭრათ ჩვენს ინფრასტრუქტურაში მონაცემების კიდევ უფრო დიდ მასშტაბზე რეპლიკაციის სირთულე. ამისთვის წინასწარ ვემზადებით: თავად ვქმნით ექსაბაიტური მასშტაბის ონლაინ შენახვის სისტემას, რომელიც Habitat-ის დიდი მოცულობის მონაცემთა ტიპებისთვისაა ოპტიმიზებული. ეს ჯერ კიდევ შემუშავების პროცესში მყოფი სისტემა Rockset-ის RocksDB Cloud ბირთვს Raft-ზე დაფუძნებულ რეპლიკაციასთან აერთიანებს. იგი იყენებს დოკუმენტების იმავე მოდელს, რასაც Azure Cosmos DB, მაგრამ განცალკევებული საცავითა და ფიზიკური რეპლიკაციით ამცირებს საჭირო ფლეშმეხსიერების მოცულობას უფრო დაბალი პიკური qps-ის სანაცვლოდ.

თუ მონაცემთა ინფრასტრუქტურის ასეთ პროექტებზე ტექნოლოგიური შესაძლებლობების ზღვარზე მუშაობა გაინტერესებთ, გაეცანით ჩვენს ვაკანსიებს⁠.

ავტორი

OpenAI