تقارن هذه المقالة نماذج الإيجار Postgres الأكثر توثيقًا (المخطط المشترك، لكل قاعدة مستأجر، مجموعة مخصصة، وتسمى أيضًا قاعدة بيانات لكل مستأجر مقابل قاعدة البيانات المشتركة)، وتشرح آلية noisy neighbor، ثم توضح بالتفصيل كيفية تنفيذ Aurabase لنموذجها الخاص ذي المستويين، والذي تم التحقق منه في كود الموفر. للتعرف على المنهجية التي نطبقها قبل نشر رقم الأداء، راجع منهجية قياس الأداء الخلفية .
إذا كنت تبحث عن مسألة تسرب البيانات بين عميلين (RLS، السياسات، service_role)، فهذه ليست زاوية هذه المقالة: مقارنة RLS وقاعدة البيانات المخصصة حسب المشروع تغطي هذا العزل المنطقي بالتفصيل. نحن هنا نتحدث عن الموارد المادية: وحدة المعالجة المركزية، الإدخال والإخراج، الاتصالات، ذاكرة التخزين المؤقت.
الأساسيات
- قاعدة البيانات المشتركة ليست بالضرورة مخططًا مشتركًا: تمنح Aurabase كل مشروع قاعدة بيانات Postgres الخاصة به، حتى على مستوياته القياسية، من خلال مشاركة المجموعة فقط.
noisy neighborيحط من الموارد المادية (وحدة المعالجة المركزية، IOPS، الاتصالات، الفراغ التلقائي)، وليس سرية البيانات: RLS لا يحلها، وهذا ليس دورها.- يوجه مزود Aurabase إلى بنيتين بالضبط، تم التحقق منهما في التعليمات البرمجية:
FullyDedicated(مجموعة CNPG بأكملها محجوزة لمشروع، على مستوى المؤسسة) أوSharedClusterDedicated(قاعدة مخصصة لمجموعة CNPG الخاصة بالمؤسسة، ولم يتم مشاركتها مطلقًا مع مؤسسة أخرى). - تتمتع مجموعة أسطول Aurabase بحد قدرة افتراضي ملحوظ يبلغ 1000 قاعدة لكل مجموعة، وهو قابل للتكوين، وبعد ذلك يوصى بالانتقال إلى مجموعة مخصصة.
- يعتمد الاختيار الصحيح على قيودك الحقيقية (الامتثال، والقدرة على التنبؤ بحركة المرور، والميزانية)، وليس على رد الفعل "المخصص هو الأفضل دائمًا".
ثلاثة نماذج لإدارة Postgres، من الأكثر مشاركة إلى الأكثر عزلة
تميز وثائق Microsoft الرسمية حول بنية تطبيقات SaaS متعددة المستأجرين بين ثلاثة نماذج للإيجار، تسمى عمومًا Silo (موارد مخصصة لكل مستأجر)، وPool (موارد مشتركة بالكامل)، وBridge (خليط من الاثنين، بعض المستأجرين المعزولين، والبعض الآخر مشترك). تنطبق هذه النماذج الثلاثة مباشرة على Postgres، على المخطط أو قاعدة البيانات أو على مستوى المجموعة بأكملها.
بشكل ملموس، بالنسبة لواجهة Postgres الخلفية، فإن هذا يعطي ثلاثة أبنية متميزة. يعد المخطط المشترك (قاعدة واحدة، عمود tenant_id، سياسات RLS التي تقوم بتصفية الصفوف) هو نموذج التجمع الأكثر شيوعًا في أدلة المستأجرين المتعددين: اقتصادي، ولكن الحدود بين عميلين تصبح تعبير SQL يتم تقييمه جدولاً بجدول. قاعدة لكل مستأجر في مجموعة مشتركة هي نموذج جسر وسيط: كل مستأجر لديه قاعدة Postgres الخاصة به (أمر CREATE DATABASEحقيقي)، ولكن تتعايش عدة قواعد في نفس المجموعة الفعلية، وبالتالي تتشارك وحدة المعالجة المركزية (CPU) والإدخال والإدخال والاتصالات. مجموعة المخصصة بالكامل لكل مستأجر هي نموذج Silo الكامل: موارد وحدة المعالجة المركزية (CPU) وذاكرة الوصول العشوائي (RAM) وإدخال المعلومات (IO) المعزولة تمامًا، والمخصصة بشكل عام للمستأجرين الذين لديهم مشكلات عالية في الامتثال أو التحميل.
| نموذج | عزل الموارد | عزل التخزين | الجهد التشغيلي |
|---|---|---|---|
| المخطط المشترك (tenant_id + RLS) | لا شيء | لا شيء (طاولة مشتركة) | الحد الأدنى (قاعدة واحدة للتشغيل) |
| لكل مستأجر، مجموعة مشتركة | جزئي (وحدة المعالجة المركزية/الإدخال/الإدخال المجمعة) | المجموع (على أساس خاص) | معتدل (قواعد N، مجموعة واحدة) |
| مجموعة مخصصة بالكامل لكل مستأجر | المجموع | المجموع | عالية (مجموعة واحدة لكل مستأجر) |
مصطلحات Silo/Pool/Bridge: وثائق Microsoft الرسمية، وأنماط هندسة SaaS متعددة المستأجرين (مركز Azure Architecture).
غالبًا ما يكون النموذج الوسيط، وهو قاعدة لكل مستأجر في مجموعة مشتركة، غائبًا عن الأدلة التي تقدم الاختيار على أنه ثنائي بين "قاعدة واحدة للجميع" و"خادم واحد لكل عميل". ومع ذلك، هذا هو الخيار الذي تستخدمه Aurabase افتراضيًا، وهو ما هو مفصل أدناه.
ينشأ الاختيار بين هذه النماذج الثلاثة مع كل قرار يتعلق بالبنية متعددة المستأجرين، وليس فقط مع موفر BaaS: الفريق الذي يبني واجهة SaaS الخلفية الخاصة به على Postgres المُدارة (RDS أو Cloud SQL أو مثيل مستضاف ذاتيًا) يقوم بالضبط بنفس التحكيم، مع تشغيل نفس آليات التنافس بمجرد وضع العديد من العملاء على نفس المثيل الفعلي.
الجار الصاخب: ما يتدهور عند تقاسم الموارد
noisy neighbor (الجار المزعج) هو مستأجر يستهلك حصة غير متناسبة من الموارد المشتركة للبنية التحتية، على حساب المستأجرين الآخرين على نفس الخادم. يأتي المصطلح من السحابة العامة، ولكنه ينطبق مباشرة على مجموعة Postgres المشتركة: يمكن لقاعدة بيانات واحدة أن تخفض أداء الآخرين دون المساس ببياناتهم على الإطلاق.
تظهر ست آليات في أغلب الأحيان في الإنتاج:
- تنافس وحدة المعالجة المركزية: استعلام مكلف (انضمام بدون فهرس، فرز ضخم) يستهلك دورات وحدة المعالجة المركزية التي تشاركها النواة بين جميع قواعد البيانات النشطة في المجموعة.
- تنافس IOPS: النسخ الاحتياطي،
VACUUM FULLأو الاستيراد الضخم يشبع إنتاجية قرص المجموعة، مما يؤدي إلى إبطاء القراءة والكتابة إلى قواعد البيانات الأخرى. - استنفاد الاتصال:
max_connectionsيحدد عدد الاتصالات النشطة على مستوى المجموعة بالكامل، وليس لكل قاعدة. القاعدة التي تفتح كثيرًا تقلل من هامش الآخرين. - تنافس الفراغ التلقائي: يعمل الفراغ التلقائي مع عدد محدود من العمال لكل مجموعة؛ يمكن أن تؤدي قاعدة البيانات ذات معدل الكتابة المرتفع إلى تأخير تنظيف جداول قاعدة بيانات أخرى.
- إخلاء ذاكرة التخزين المؤقت:
shared_buffersهي ذاكرة واحدة للمجموعة بأكملها؛ يمكن لقاعدة البيانات التي تحتوي على مجموعة عمل كبيرة إزالة الصفحات المخزنة مؤقتًا لقاعدة بيانات مجاورة أصغر. - نوافذ الصيانة المشتركة: يتم تطبيق النسخ الاحتياطي أو تجاوز فشل النسخة المتماثلة أو الترقية الرئيسية على المجموعة بأكملها، وليس على أساس كل قاعدة.
رسم تخطيطي هيكلي، وليس نتيجة قياس: لم يتم نشر أرقام أداء مقارنة حتى الآن لهاتين الطوبولوجيتين.
غالبًا ما تكون ميزانية الاتصال هي العرض الأكثر وضوحًا في الإنتاج، حتى قبل زمن الوصول. هذا هو الموضوع التفصيلي لدليل ضبط max_connections ومقارنة PgBouncer وSupavisor وPgCat.
يخفف مجمّع وضع المعاملة (PgBouncer، وSupavisor، وPgCat) من استنفاد الاتصال، ولكنه لا يزيل تنافس وحدة المعالجة المركزية أو IOPS: فهو يعيد استخدام اتصالات الخادم الحالية، ولا يضيف مراكز إضافية لوحدة المعالجة المركزية أو إنتاجية القرص إلى المجموعة. مقالتنا حول وضع تجميع المعاملات توضح بالتفصيل ما يتغير هذا الوضع فعليًا، وما لا يتغير.
RLS يعزل البيانات، وليس الموارد
يعمل الأمان على مستوى الصف على حل مشكلة مختلفة: فهو يمنع الاستعلام من قراءة أو تعديل صفوف مستأجر آخر، على المستوى المنطقي. فهو لا يحتفظ بدورة وحدة المعالجة المركزية، ولا فتحة اتصال، ولا إنتاجية القرص لمستأجر معين.
يمكن أن يكون لدى اثنين من المستأجرين سياسات RLS مانعة لتسرب الماء تمامًا ويحط من قدر بعضهما البعض في نفس الوقت: الجار المزعج هو مشكلة موارد مادية، وليس حقوق الوصول. يؤدي الخلط بين الاثنين إلى شعور زائف بالأمان التشغيلي بمجرد إنشاء EPIRB.
للحصول على العزل المنطقي (سياسات RLS، service_role، الحدود بين المشاريع على الجانب الأمني)، راجع مقالتنا المخصصة: RLS وقاعدة مخصصة لكل مشروع، اختيار العزل متعدد المستأجرين من Aurabase. وتبقى هذه المقالة على مستوى الإمكانيات المادية.
نموذج Aurabase، تم التحقق منه بالرمز
يوثق كود التوفير (aura-provisioner) معماريتين محتملتين لمشروع Postgres نشط، من توحيد التوفير الذي يشير إليه الكود بالمهمة 12: FullyDedicated و SharedClusterDedicated. تمت إزالة النماذج القديمة ذات تفاصيل المخطط من مسار التزويد.
يقوم مستوى enterprise بتشغيل FullyDedicated: مجموعة CNPG كاملة، محجوزة لهذا المشروع الفردي. جميع المستويات الأخرى (مجانية، احترافية، جماعية) تتجه إلى SharedClusterDedicated: قاعدة بيانات Postgres project_<uuid> كاملة، في مجموعة CNPG الخاصة بمؤسسة المشروع. لذلك فهي ليست مخططًا مشتركًا: حتى في الخطة القياسية، تكون قاعدة البيانات الخاصة بك عبارة عن قاعدة بيانات Postgres كاملة، وليست سطرًا واحدًا من بين سطر آخر في جدول مشترك. ما تتم مشاركته هو المجموعة (وحدة المعالجة المركزية، ذاكرة الوصول العشوائي، القرص، الاتصالات)، وليس القاعدة نفسها.
يتم إنشاء مجموعة CNPG الخاصة بالمؤسسة عندما يتم توفير أول مشروع Postgres لها ولا تستضيف مطلقًا مشروعًا من مؤسسة أخرى، وهو خيار تصميم مقفل على مستوى الكود (org_cluster.rs، قفل استشاري Postgres بواسطة المؤسسة عند الإنشاء). وبالتالي فإن الجار الوحيد المحتمل المزعج في منطقة هبوط Aurabase المشتركة هو مشروع آخر لمؤسستك الخاصة، وليس مشروعًا لعميل خارجي على الإطلاق.
تدير Aurabase مواصفات بنية مجموعة PostgreSQL.
هذه العتبة البالغة 1000 قاعدة لكل مجموعة ليست حدًا صارمًا: فهي معيار قابلية للملاحظة يؤدي إلى توصية بالانتقال إلى FullyDedicated، وليس كتلة تلقائية. لم يعد هذا الأمر يحرك أي قرارات بشأن التنسيب، حيث أصبح من الممكن الآن إنشاء مجموعة واحدة فقط لكل مؤسسة.
تعرض كل مجموعة، مخصصة أو أسطول، مجمع CNPG (PgBouncer) الذي يمتص جزءًا من الضغط على الاتصالات النشطة، في كلا الهيكلين. ما الذي يغيره هذا المجمع فعليًا فيما يتعلق بالتنافس على الموارد موضح أدناه بالتفصيل.
كما أن حجم وحدة المعالجة المركزية/ذاكرة الوصول العشوائي للمجموعة المشتركة ليس موحدًا بين المؤسسات: فهو مشتق من مستوى المؤسسة عبر وظيفة مخصصة (FleetSizing::from_org_plan، تم التحقق منه في org_cluster.rs)، وليس من حجم واحد مطبق على جميع المستويات. لا تقوم المؤسسة على مستوى الفريق بتحديد حجم مجموعتها بنفس الطريقة التي تقوم بها المؤسسة على المستوى الحر.
تعمل هاتان البنيتان على PostgreSQL 16، وليس الإصدار 17، ويتم التحقق منهما في ملف Dockerfile لصورة CNPG المستخدمة في الإنتاج. هذا الاختيار للإصدار له آثار ضبط خاصة به، مفصلة في مقارنة Postgres 16 vs 17 vs 18.
عندما يكون التجميع كافيًا، عندما يصبح التكريس ضروريًا
التجميع ليس حلا وسطا رخيصا. وهو يتوافق مع حركة الغالبية العظمى من المشاريع قيد التطوير أو الإطلاق أو النمو المعتدل، حيث ستكون المجموعة المخصصة تكلفة إضافية دون فائدة قابلة للقياس.
| إشارة | المشتركة تكفي | مخصص الموصى بها |
|---|---|---|
| الامتثال الرسمي للعزل الجسدي (الصحة، الموارد البشرية، القطاع العام) | لا | نعم |
| حركة مرور يمكن التنبؤ بها، قمم معتدلة | نعم | |
| حمل الذروة المستمر وغير المتوقع | خطر ضبط النفس | نعم |
| ميزانية محدودة، المنتج في مرحلة التحقق | نعم | |
| شرط العقد (DPA) الذي يتطلب العزل الموثق | لا | نعم |
بالنسبة للمشاريع الخاضعة لالتزام تعاقدي للعزل المادي الموثق، فإن صفحات DPA والخاصة بالامتثال توضح بالتفصيل ما يغطيه كل مستوى.
الجانب السلبي لنموذج كل قاعدة على حدة، والذي تم تسليط الضوء عليه من خلال العديد من أدوات إدارة ترحيل المخطط مثل Bytebase، هو الجانب التشغيلي وليس الفني: يجب تطبيق كل عملية ترحيل والتحقق منها على كل قاعدة، واحدة تلو الأخرى، حتى عندما تتواجد في نفس المجموعة. إن المجموعة المخصصة بالكامل لا تلغي هذه التكلفة، بل إنها تضيفها: عملية ترحيل واحدة لكل مجموعة للمراقبة بشكل مستقل، بدلاً من عملية ترحيل واحدة فقط.
الموارد المتخصصة في هندسة البرمجيات متعددة المستأجرين، مثل CodeOpinion، تقدم بانتظام هذا النهج الوسيط (على أساس كل مستأجر على البنية التحتية المشتركة) كحل وسط معقول بين المخطط المشترك والمجموعة المخصصة بالكامل، بدلاً من الاختيار الثنائي بين النقيضين.
لا يتطلب الانتقال من مشترك إلى مخصص إعادة كتابة المخطط أو تغيير المحركات: في كلتا الحالتين، هو Postgres، بنفس سلسلة pg_dump / pg_restore كما هو موضح في دليل ترحيل Supabase إلى Aurabase. ويظل تغيير المستوى بمثابة عملية تبديل، وليس إعادة كتابة التطبيق.
الأسئلة المتداولة
ماذا تتذكر
لا تتعارض القاعدة المخصصة والقاعدة المشتركة في أمان البيانات: يمكن لكلا النموذجين عزل مستأجر واحد عن الآخر بشكل صحيح على المستوى المنطقي. إنهم يعارضون بعضهم البعض على الموارد المادية (وحدة المعالجة المركزية، IOPS، الاتصالات، ذاكرة التخزين المؤقت، نوافذ الصيانة). هذه الخطة هي التي تحدد الجار المزعج، وليست سياسة RLS مكتوبة بشكل سيء.
يحتفظ نموذج Aurabase، الذي تم التحقق منه في كود الموفر، بحل وسط افتراضيًا: قاعدة بيانات Postgres مخصصة لكل مشروع، على مجموعة مشتركة ولكنها محفوظة بشكل صارم لمؤسسة واحدة، مع مجموعة مخصصة بالكامل محجوزة لمستوى الأعمال. يعتمد الاختيار الصحيح على القيود الحقيقية التي تواجهك، وليس على رد الفعل حيث سيكون الخيار الأفضل دائمًا.