تخطي إلى المحتوى الرئيسي
OpenAI

22 يناير 2026

الهندسة

توسيع نطاق PostgreSQL لدعم 800 مليون مستخدم لـ ChatGPT

إعداد: بوهان تشانغ، أحد أعضاء الفريق التقني

جاري التحميل...

لطالما كان PostgreSQL لسنوات عديدة الركيزة الأساسية في البنية التحتية لأنظمة البيانات التي تشغّل منتجاتنا الأساسية، مثل برنامج ChatGPT وواجهة OpenAI API. وبسبب الازدياد الكبير في أعداد المستخدمين، ارتفعت الضغوط على قواعد بياناتنا بشكل مضاعف، إذ شهد العام المنصرم نموًا في حجم الأحمال على نظام PostgreSQL تجاوز عشرة أضعاف حجمه السابق، مع استمرار هذا الارتفاع بوتيرة متسارعة.

وبينما كنا نعمل على الارتقاء ببنيتنا التحتية لتستمر في دعم هذا النمو، توصلنا إلى استنتاج جديد: وهو أن PostgreSQL يمتلك مرونة كافية للتوسع ودعم أعباء القراءة المكثفة بمستويات موثوقية كانت تُعتبر مستحيلة في السابق. هذا النظام (الذي ابتكره علماء في جامعة كاليفورنيا بيركلي) أتاح لنا التعامل مع حركة مرور عالمية واسعة النطاق من خلال خادم أساسي واحد من نوع Azure PostgreSQL flexible server(يفتح في نافذة جديدة) ونحو 50 نسخة قراءة فرعية (read replicas) موزعة عالميًا. نروي هنا قصة نجاحنا في OpenAI في الوصول بنظام PostgreSQL إلى مستوى يدعم ملايين الطلبات في الثانية الواحدة لخدمة 800 مليون مستخدم عبر تحسينات برمجية دقيقة وهندسة احترافية؛ مع استعراض أبرز النتائج والخبرات التي اكتسبناها خلال هذه التجربة.

جوانب القصور في نموذج تصميمنا الأول

منذ انطلاق ChatGPT، تضاعف حجم زيارات الموقع بمعدلات قياسية، مما دفعنا إلى إجراء تحسينات شاملة وسريعة في برمجة التطبيق وهيكلية قواعد بيانات PostgreSQL. تضمنت استراتيجيتنا التوسع الرأسي بزيادة حجم وكفاءة الأجهزة، والتوسع الأفقي بنشر المزيد من نسخ القراءة (read replicas). لقد أدت هذه المنظومة دورها بامتياز لفترة طويلة، وهي تواصل اليوم، من خلال التحديثات المستمرة، توفير آفاق رحبة وقدرات تشغيلية كافية لمواجهة أي نمو مستقبلي.

إن فكرة اعتماد نظام بحجم OpenAI على خادم أساسي واحد قد تبدو غير منطقية للبعض، لكن الحفاظ على كفاءة هذا النظام يتطلب هندسة دقيقة للغاية. لقد تسببت الأحمال الزائدة على Postgres في وقوع حوادث تقنية كبرى، وغالبًا ما تبدأ بمشكلة في المراحل الأولية تؤدي إلى ضغط مفاجئ على قاعدة البيانات؛ سواء كان ذلك بسبب "إخفاقات التخزين المؤقت" الناتجة عن تعطل طبقة التخزين المؤقت، أو تكدس عمليات الانضمام المعقدة التي تستهلك قدرات وحدة المعالجة المركزية بالكامل، أو حتى ضغط عمليات الكتابة المكثف عند تدشين خصائص جديدة. هذا الارتفاع في استهلاك الموارد يؤدي لبطء الاستجابة وفشل الطلبات، لتبدأ عمليات إعادة المحاولة التلقائية في مضاعفة الضغط، مما يخلق حلقة مفرغة قد تؤدي في النهاية إلى تدهور أداء منصة ChatGPT وخدمات واجهة API بشكل كامل.

مخطط توسيع نطاق التحميل

بينما يتفوق PostgreSQL في دعم أعباء القراءة الضخمة، تظهر نقاط ضعفه بوضوح خلال ذروة عمليات الكتابة؛ والسبب الرئيسي يعود إلى تطبيق آلية MVCC (التحكم في التزامن متعدد النسخ)، الذي يفتقر للكفاءة المطلوبة في أعباء العمل كثيفة الكتابة. على سبيل المثال، يؤدي تحديث أي حقل داخل صف إلى نسخ الصف بالكامل لإنشاء نسخة جديدة، مما يسبب تضخمًا هائلًا في عمليات الكتابة في ظل أحمال الكتابة الثقيلة. ولا يقتصر الضرر على ذلك، بل يمتد ليشمل تضخم القراءة أيضًا، إذ تضطر الاستعلامات للمرور عبر نسخ متعددة مهملة (dead tuples) للوصول للبيانات الأحدث. كما تتسبب آلية MVCC في مشكلات أخرى، مثل تضخم الجداول والفهارس، ورفع تكلفة صيانة الفهارس، وصعوبة ضبط عمليات التنظيف التلقائي. (يمكنكم الاطلاع على تحليل معمّق لهذه المشكلات في مدونة كتبتها مع البروفيسور "آندي بافلو" من جامعة Carnegie Mellon University بعنوان "The Part of PostgreSQL We Hate the Most(يفتح في نافذة جديدة)"، والمشار إليها(يفتح في نافذة جديدة) في صفحة ويكيبيديا الخاصة بنظام PostgreSQL).

الارتقاء بنظام PostgreSQL لدعم ملايين الطلبات في الثانية

سعيًا وراء تجاوز هذه القيود وتخفيف العبء عن خلال عمليات الكتابة، باشرنا عملية ترحيل مستمرة للمشاريع التي تعتمد بكثافة على الكتابة ويمكن تقسيم بياناتها أفقيًا إلى أنظمة "تجزئة البيانات" مثل Azure Cosmos DB، بالتوازي مع تطوير الأكواد البرمجية لتقليص عمليات الكتابة غير الضرورية. ومن ناحية أخرى، وضعنا سياسة تمنع إضافة جداول جديدة إلى بيئة PostgreSQL المتاحة حاليًا، مع جعل الأنظمة المجزأة هي الأساس لأي مشاريع أو أعباء عمل مستحدثة.

حتى مع تطور بنيتنا التحتية، استمر العمل بنظام PostgreSQL دون اللجوء للتجزئة، حيث تدار جميع عمليات الكتابة من خلال خادم أساسي واحد فقط. والدافع وراء هذا القرار هو أن عملية تجزئة بيانات التطبيقات الحالية ستكون في غاية التعقيد، وستتطلب إعادة صياغة مئات نقاط النهاية في التطبيقات، مما قد يستنزف سنوات من العمل الهندسي. وبما أن معظم عملياتنا هي عمليات قراءة مكثفة، ومع التحسينات الكبيرة التي أجريناها، فإن النظام الحالي لا يزال يمتلك قدرة استيعابية كبيرة لدعم تدفق البيانات المتزايد. ونحن لا نستبعد خيار التجزئة مستقبلًا، لكنه ليس أولوية قريبة المدى، خاصة وأن لدينا ما يكفي من الإمكانيات لدعم تطلعاتنا الحالية والمستقبلية للنمو.

سنتناول بالتفصيل في الأجزاء القادمة التحديات الهندسية التي تصدينا لها، والتحسينات الشاملة التي طبقناها لتجاوزها وتفادي أي أعطال مستقبلية؛ وهو ما مكننا من استغلال كامل قدرات PostgreSQL والارتقاء بأدائه ليدعم ملايين الطلبات في الثانية الواحدة.

تخفيف الأحمال عن الخادم الأساسي

التحدي: تفتقر هيكلية الخادم الأساسي الواحد للقدرة على توسيع عمليات الكتابة نظرًا لاعتمادها على مصدر كتابة وحيد؛ وهذا يعني أن أي طفرة كبيرة في ضغط الكتابة قد تتسبب في تحميل الخادم الأساسي فوق طاقته بشكل مفاجئ، وهو ما يهدد استقرار خدمة ChatGPT ومنصة واجهة API.

الحل: لمواجهة هذا العائق، اتبعنا سياسة صارمة لتقليل العبء على الخادم الأساسي لضمان جاهزيته الدائمة لأي طفرات كتابة مفاجئة. بدأنا بنقل حركة القراءة إلى النسخ المتماثلة حيثما كان ذلك ممكنًا، باستثناء الاستعلامات التي تتطلب وجودها ضمن "معاملات الكتابة" على الخادم الأساسي، والتي أخضعناها لعمليات تحسين دقيقة، مع الحرص التام على رفع كفاءتها ومنع البطء في استجابتها. أما المهام التي ترهق النظام بعمليات الكتابة، فقد رحلنا ما كان منها قابلًا للتجزئة إلى منصات مثل Azure Cosmos DB، في حين لا نزال نعمل على ترحيل المهام الأصعب. بينما تستمر جهودنا لترحيل المهام الأكثر تعقيدًا في التجزئة، وهي العملية التي ستستغرق وقتًا أطول. ومن جانب آخر، سعينا بقوة لتحسين تطبيقاتنا لخفض أعباء الكتابة؛ فشمل ذلك معالجة الثغرات التي تسبب تكرار الكتابة، واعتماد أسلوب "الكتابة الكسولة" (lazy writes) لتنظيم تدفق البيانات. وأخيرًا، وضعنا ضوابط مشددة على سرعة معالجة البيانات عند تحديث بيانات الجداول (backfilling) لضمان عدم تجاوز حدود قدرة النظام على التحمل.

تحسين أداء الاستعلامات

التحدي: حددنا عددًا من الاستعلامات التي تتطلب موارد ضخمة داخل PostgreSQL؛ حيث كانت الطفرات المفاجئة في وتيرة هذه الاستعلامات سابقًا تستنزف موارد وحدة المعالجة المركزية (CPU) بشكل كبير، وهو ما انعكس سلبًا على سرعة استجابة ChatGPT ومنصة واجهة API.

الحل: إن الاستعلامات التي تتطلب موارد ضخمة، خاصة تلك التي تتضمن عمليات ربط معقدة بين الجداول، تمتلك القدرة على شل حركة الخدمة بالكامل. ومن هنا تنبع ضرورة التحسين المستمر لاستعلامات PostgreSQL والابتعاد عن الأخطاء الشائعة في تصميم أنظمة معالجة المعاملات عبر الإنترنت (OLTP). لقد اكتشفنا في إحدى المرات استعلامًا مكلفًا يربط 12 جدولًا ببعضها، وكان هو المسبب الرئيسي لعدة حوادث تقنية كبرى واجهناها. القاعدة الآن هي تجنب الربط المتعدد للجداول كلما أمكن؛ وفي حال تعذر ذلك، نلجأ لتجزئة الاستعلام ونقل منطق الربط ليعالج برمجيًا في طبقة التطبيق. وغالبًا ما تكون أطر عمل "رسم الخرائط المرتبطة للكائنات" (ORM) هي المصدر لهذه الاستعلامات المعقدة، مما يفرض علينا فحص لغة SQL الناتجة عنها بدقة والتأكد من أنها تعمل كما هو متوقع. وعلاوة على ذلك، ولمعالجة مشكلة الاستعلامات الخاملة التي تطول مدتها في PostgreSQL، نعتمد على ضبط إعدادات المهلة مثل idle_in_transaction_session_timeout لضمان عدم إعاقة أداة التنظيف التلقائي عن أداء مهامها.

استراتيجيات التخفيف من مخاطر "نقطة الفشل الواحدة"

التحدي: في حال توقف إحدى النسخ للقراءة عن العمل، يمكن إعادة توجيه حركة البيانات إلى النسخ الأخرى. ومع ذلك، فإن الاعتماد على وحدة كتابة واحدة فقط يعني وجود "نقطة فشل واحدة"؛ فإذا توقفت هذه الوحدة عن العمل، فإن الخدمة بأكملها ستتأثر وتتوقف عن الاستجابة.

الحل: نظرًا لأن معظم الطلبات الحيوية تقتصر على استعلامات القراءة فقط، فقد عملنا على تخفيف مخاطر "نقطة الفشل الواحدة" في الخادم الأساسي عبر نقل أعباء القراءة تلك من وحدة الكتابة إلى النسخ المتماثلة؛ مما يضمن استمرارية تلبية هذه الطلبات حتى في حال توقف الخادم الأساسي عن العمل. ورغم أن عمليات الكتابة ستظل معرضة للفشل في هذه الحالة، إلا أن حجم التأثير سيكون محدودًا؛ إذ لن تُصنف الحادثة بعد الآن على أنها "حادثة تقنية كبرى" بفضل بقاء خدمات القراءة متاحة.

للتخفيف من آثار أعطال الخادم الأساسي، نقوم بتشغيل هذا الخادم وفق نمط "التوافر العالي" مع وجود نظام "بديل جاهز"، وهو عبارة عن نسخة متماثلة تتم مزامنتها باستمرار وتكون مستعدة دائمًا لتولي مهام إدارة حركة البيانات. وفي حال تعطل الخادم الأساسي أو الحاجة لإيقافه عن العمل من أجل الصيانة، يمكننا ترقية هذا البديل بسرعة لتقليل فترات التوقف إلى أدنى حد. وقد بذل فريق Azure PostgreSQL جهودًا كبيرة لضمان بقاء عمليات "تبديل الخدمة عند الفشل" آمنة وموثوقة حتى في ظل الأحمال العالية جدًا. أما بالنسبة للتعامل مع أعطال نسخ القراءة، فإننا ننشر نسخًا متعددة في كل منطقة جغرافية مع توفير مساحة استيعابية إضافية كافية، مما يضمن أن فشل نسخة واحدة لن يؤدي إلى انقطاع الخدمة على مستوى المنطقة بأكملها.

عزل أعباء العمل

التحدي: نصطدم أحيانًا بطلبات تستنزف موارد نظام PostgreSQL بصورة مفرطة وتفوق حجمها الفعلي، وهو ما ينعكس سلبًا على جودة أداء بقية المهام المشتركة في ذات الموارد. ومن الأمثلة على ذلك، أن تدشين خاصية جديدة قد يتضمن استعلامات تفتقر للكفاءة وتنهك وحدة المعالجة المركزية، مما يتسبب في عرقلة وبطء الاستجابة للخدمات والميزات الجوهرية الأخرى في النظام.

الحل: نقوم بتشغيل ما يقرب من 50 نسخة قراءة متماثلة عبر مناطق جغرافية متعددة لتقليل زمن التأخير. ومع ذلك، في ظل المعمارية الحالية، يجب على الخادم الأساسي بث سجلات WAL إلى كل نسخة متماثلة. ورغم أن النظام يتوسع حاليًا بشكل جيد بفضل استخدام أنواع مثيلات ضخمة جدًا ونطاق عرض شبكة مرتفع، إلا أننا لا نستطيع الاستمرار في إضافة النسخ إلى ما لا نهاية دون أن يتسبب ذلك في النهاية في تحميل الخادم الأساسي فوق طاقته. ولمعالجة هذه المشكلة، نحن نتعاون مع فريق Azure PostgreSQL لتطبيق تقنية "النسخ المتماثل المتسلسل(يفتح في نافذة جديدة)"، حيث تقوم نسخ متماثلة وسيطة بنقل سجلات WAL إلى النسخ المتماثلة التالية لها. يتيح لنا هذا النهج إمكانية التوسع لما قد يزيد عن مائة نسخة دون إنهاك الخادم الأساسي. ومع ذلك، فإن هذه التقنية تفرض تعقيدات تشغيلية إضافية، لا سيما فيما يتعلق بإدارة تبديل الخدمة في حالات الفشل. لا تزال هذه الميزة قيد الاختبار؛ وسوف نتأكد من موثوقيتها وقدرتها على الانتقال للبديل بأمان قبل طرحها في بيئة الإنتاج.

مخطط النسخ المتماثل المتسلسل لـ postgreSQL

تحديد المعدل

التحدي: يمكن أن يؤدي الارتفاع المفاجئ في حركة البيانات على نقاط نهاية معينة، أو تدفق الاستعلامات التي تتطلب موارد ضخمة، أو وقوع "موجة من محاولات إعادة الاتصال"، إلى استنزاف الموارد الحيوية بسرعة مثل وحدة المعالجة المركزية، وعمليات الإدخال والإخراج (I/O)، والاتصالات؛ مما يتسبب في تدهور واسع النطاق في أداء الخدمة.

الحل: قمنا بتنفيذ آليات "تحديد معدل العمليات" عبر طبقات متعددة، تشمل التطبيق، ومجمع الاتصالات، والوكيل، والاستعلامات، لمنع طفرات حركة البيانات المفاجئة من إنهاك مثيلات قاعدة البيانات والتسبب في انهيارات متتالية. كما يعد تجنب فترات إعادة المحاولة القصيرة للغاية أمرًا بالغ الأهمية لتفادي حدوث "موجات إعادة المحاولة". وعلاوة على ذلك، قمنا بتحسين طبقة الـ ORM لدعم تحديد المعدل، وعند الضرورة، نقوم بحظر أنماط استعلامات محددة بالكامل. إن هذا الشكل الموجه من "تخفيف الأحمال" يتيح لنا التعافي السريع من الارتفاعات المفاجئة في الاستعلامات التي تتطلب موارد ضخمة.

إدارة المخطط

التحدي: يمكن لأي تغيير بسيط في مخطط البيانات، مثل تعديل نوع أحد الأعمدة، أن يتسبب في إعادة كتابة الجدول بالكامل(يفتح في نافذة جديدة). لذلك، فإننا نطبق التغييرات على المخطط بحذر شديد، حيث نقتصر على العمليات "خفيفة الوزن" ونتجنب أي عمليات تتطلب إعادة كتابة الجداول بأكملها.

الحل: تقتصر سياستنا على السماح بتعديلات المخطط البسيطة التي لا تستدعي إعادة كتابة الجدول بالكامل، كإضافة أو حذف بعض الأعمدة. ولضمان عدم تعثر النظام، نفرض مهلة زمنية لا تتجاوز 5 ثوانٍ لتنفيذ هذه التعديلات على المخطط، مع إتاحة إضافة الفهارس وحذفها بالتوازي. وتنحصر هذه التعديلات في الجداول القائمة فقط؛ أما في حال الحاجة لجداول جديدة لدعم ميزات مستحدثة، فيتم توجيهها إلى لأنظمة المجزأة مثل Azure Cosmos DB بدلًا من PostgreSQL. وعند القيام بملء حقول الجداول بالبيانات، فإننا نعتمد ضوابط مشددة لمعدل نقل البيانات لتفادي إجهاد الخادم بعمليات كتابة مفاجئة. وبالرغم من أن إتمام هذه المهام قد يمتد لأكثر من أسبوع، إلا أن الأولوية تظل للحفاظ على ثبات الأداء ومنع أي اضطراب في بيئة الإنتاج.

النتائج ورسم ملامح الطريق نحو المستقبل

لقد برهنت رحلتنا في تطوير البنية التحتية أن نظام Azure PostgreSQL، عند اقترانه بالبنية الهندسية والتحسينات الملائمة، قادر على استيعاب أكبر أعباء العمل التشغيلية. إن القدرة على معالجة ملايين الاستعلامات في الثانية (QPS) لعمليات القراءة المكثفة هي ما يمنح القوة اليوم لمحركات OpenAI الحيوية مثل ChatGPT ومنصة واجهة API. ومن خلال إضافة نحو 50 نسخة متماثلة، استطعنا القضاء تقريبًا على مشكلة التأخير في النسخ، وتأمين وصول سريع للبيانات في جميع المناطق الجغرافية، مع توفير سعة احتياطية واسعة تضمن لنا الجاهزية التامة للمستقبل وما يحمله من نمو مطرد.

يتحقق هذا التوسع الهائل دون المساومة على سرعة الاستجابة أو موثوقية النظام؛ حيث ننجح باستمرار في تقديم زمن تأخير p99 لا يتجاوز بضع عشرات من الملي ثانية من جهة العميل، مع الحفاظ على معدل توافر يصل إلى 99.999%. وخلال الاثني عشر شهرًا الماضية، سجلنا حادثة تقنية كبرى واحدة فقط تتعلق بـ PostgreSQL، وذلك خلال الإطلاق الضخم(يفتح في نافذة جديدة) لخدمة ChatGPT ImageGen، حيث تضاعفت حركة بيانات الكتابة حينها بأكثر من عشر مرات بالتزامن مع انضمام ما يزيد عن 100 مليون مستخدم في أسبوع واحد.

بينما نعتز بالنتائج التي وصلنا إليها باستخدام PostgreSQL، فإننا مستمرون في اختبار أقصى طاقاته لضمان استدامة قدرتنا على التوسع مستقبلًا. لقد أتممنا ترحيل المهام كثيفة الكتابة التي تدعم التجزئة إلى أنظمة مثل CosmosDB، ونبذل جهودًا حثيثة لترحيل ما تبقى من أعباء العمل المعقدة التي يصعب تجزئتها، بهدف تخفيف ضغط عمليات الكتابة عن الخادم الرئيسي في PostgreSQL. وبموازاة ذلك، نعمل مع فريق Azure لتطبيق تقنية "النسخ المتماثل المتسلسل"، مما سيسمح لنا برفع عدد النسخ المتماثلة للقراءة إلى مستويات أعلى بكثير وبموثوقية تامة.

واستشرافًا للمرحلة المقبلة، سنستمر في البحث عن سبل جديدة لتعزيز قدرات التوسع، سواء عبر اعتماد أنظمة PostgreSQL المجزأة أو من خلال التوجه نحو أنظمة موزعة بديلة، وذلك لمواكبة الاحتياجات المتزايدة والمتسارعة لبنيتنا التحتية.

المؤلف

Bohan Zhang

الشكر والتقدير

نتوجه بخالص الشكر إلى جون لي، وسيتشينغ ليو، وتشاو مين يو، وتشنغ لونغ هاو لمساهماتهم القيمة في هذا المقال، وإلى كافة أعضاء الفريق الذين بذلوا جهودًا في تطوير وتوسيع بنية PostgreSQL. كما نعرب عن تقديرنا لفريق Azure PostgreSQL على تعاونهم الوثيق معنا.