PostgreSQL مقابل CockroachDB للتوفر متعدد المناطق
PostgreSQL مقابل CockroachDB: مقارنة عملية حول الاتساق، الزمن، تغييرات المخطط، والتكاليف التشغيلية الحقيقية للانتقال متعدد المناطق مبكرًا.

ما المشكلة التي تحاول حقًا حلها؟
مصطلح "التوفر متعدد المناطق" يُستخدم للإشارة إلى أهداف مختلفة. خلط هذه الأهداف هو سبب اختيار الفرق قاعدة بيانات غير مناسبة.
قبل مقارنة PostgreSQL و CockroachDB، اكتب (1) الفشل المحدد الذي تريد تحمله و(2) ما الذي يجب أن يراه المستخدمون أثناء حدوث هذا الفشل.
معظم الفرق تسعى لمزيج من الأهداف التالية:
- زيادة وقت التشغيل عند تعطل منطقة (التبديل في حالات الفشل)
- استجابات أسرع للمستخدمين البعيدين عن منطقتك الرئيسية (تقليل زمن الوصول)
- قواعد بيانات مرتبطة بالجغرافيا (محلية أو امتثال لإقامة البيانات)
- سلوك متوقع تحت الحمل، وليس فقط في اختبارات المسار السعيد
الهدف المشترك واضح: يجب أن يحصل العميل في قارة أخرى على نتائج سريعة وصحيحة.
الصعوبة أن "سريع" و"صحيح" قد يتعارضان بمجرد أن توزّع الكتابات عبر المناطق. الاتساق الأقوى عادة يعني مزيدًا من التنسيق بين المناطق، وهذا يزيد الزمن. تقليل الزمن غالبًا يعني القراءة من نسخة قريبة أو استخدام تكرار لا متزامن، مما قد يؤدي إلى قراءات قديمة أو ضرورة إدارة تضارب الآن.
مثال ملموس: يقوم مستخدم في ألمانيا بتحديث عنوان الشحن ثم يكمل عملية الدفع فورًا. إن قرأت عملية الدفع من نسخة في الولايات المتحدة تتأخر بثوانٍ، فقد يستخدم الطلب العنوان القديم. بعض المنتجات تتحمل ذلك مع واجهة مستخدم واضحة ومحاولات إعادة، وأخرى (المدفوعات، المخزون، الامتثال) لا يمكنها ذلك.
لا توجد إجابة عالمية. الجواب الصحيح يعتمد على ما يجب ألا يخطئ أبدًا، وما يمكن أن يتأخر قليلًا، وكم تعقيدًا تشغل به فريقك يوميًا.
نهجان لـ "التوفر في عدة مناطق"
عند مقارنة PostgreSQL و CockroachDB لاستخدام متعدد المناطق، غالبًا ما تقارن بين تصميمين مختلفين.
مع PostgreSQL، الإعداد الأكثر شيوعًا هو مفتاح واحد (single-primary). توجد منطقة واحدة هي "المنزل" حيث تحدث الكتابات. تعمل المناطق الأخرى كنسخ قراءة تنسخ التغييرات من المفتاح الأساسي. إذا تعطلت المنطقة الأساسية، تروّج نسخة وتوجه التطبيق إليها. إذا أُدير الأمر جيدًا، يمكن أن يعمل هذا بشكل رائع، لكن النظام منظم حول مكان كتابة رئيسي واحد وخطة فشل مقصودة.
مع نظم SQL الموزعة مثل CockroachDB، تم تصميم قاعدة البيانات لتوزيع البيانات والمسؤولية عبر المناطق منذ البداية. تُنسَخ البيانات إلى عدة عقد، ويتفق الكل على ترتيب الكتابات. يمكنك غالبًا وضع بيانات معينة أقرب للمستخدمين في مناطق مختلفة مع الحفاظ على قاعدة بيانات منطقية واحدة.
ما يتغير لفريق التطبيق أقل تعلقًا بصيغة SQL وأكثر تعلقًا بالتوقعات:
- الكتابات: كتابات PostgreSQL تكون الأسرع قرب المفتاح الأساسي. كتابات CockroachDB غالبًا تتطلب اتفاقًا من نسخ متعددة، والذي قد يشمل تأكيدًا عبر المناطق.
- القراءات: PostgreSQL يمكنها خدمة القراءات المحلية من النسخ (مع مقايضة التأخر). CockroachDB يمكنها تقديم قراءات متسقة، لكنها قد تدفع تكلفة التنسيق اعتمادًا على مكان وضع البيانات.
- الأعطال: فشل PostgreSQL عبارة عن تبديل تديره وتفعّله. CockroachDB مصممة للاستمرار خلال بعض أعطال المناطق، لكن فقط ضمن قواعد النسخ والأغلبية (quorum).
المتطلب المخفي هو الصحة أثناء الأعطال. إذا كنت تستطيع تحمل قراءات قديمة مؤقتًا، أو توقفًا قصيرًا للكتابة أثناء التبديل، فقد يناسبك PostgreSQL بمفتاح واحد. إذا كنت تحتاج النظام ليبقى صحيحًا وقابلاً للكتابة أثناء تعطل منطقة، فأنت تقبل تكلفة التنسيق في قاعدة موزعة.
ضمانات الاتساق: على ماذا يمكنك الاعتماد
الاتساق، ببساطة: عندما يحدث تحديث لسجل، يجب أن يرى الجميع نفس الحقيقة.
مع PostgreSQL، الاتساق القوي أبسط عندما يتصل التطبيق بمفتاح واحد. تحدث القراءات والكتابات في مكان واحد، لذا المعاملات تتصرف بتوقعية. يمكنك إضافة نسخ لتسريع القراءة في مناطق أخرى، لكن عليك حينها تحديد متى تقبل قراءة بيانات قديمة قليلًا.
مع CockroachDB وغيرها من نظم SQL الموزعة، الاتساق القوي ممكن أيضًا، لكنه يصبح أكثر كلفة كلما باعدت المسافات بين المناطق. الكتابات التي يجب أن تكون متسقة عبر المناطق تتطلب تنسيقًا بين العقد. كلما كانت المناطق أبعد، زاد زمن هذا التنسيق. ستشعر غالبًا ببطء أكبر في الكتابات والمعاملات، خاصة عندما تلمس المعاملة صفوفًا تعيش في مناطق مختلفة.
كلتا النظامين يمكنهما دعم معاملات قابلية التسلسل (serializable)، والفرق هو أين يتم بذل الجهد: PostgreSQL يدفع معظم التكلفة داخل منطقة واحدة، بينما النظام الموزع قد يدفعها عبر المناطق.
بعض الأسئلة التي توضح المقايضات:
- هل يمكن أن يرى المستخدمون قراءات قديمة ولو لثوانٍ؟
- هل يمكن لمنطقتين قبول الكتابات بشكل مستقل، أم يجب أن تتفق كل الكتابات عالميًا؟
- ماذا يحدث إذا حرّر شخصان نفس السجل في الوقت نفسه؟ هل تسمح بالتضارب؟
- أي إجراءات يجب أن تكون صحيحة دائمًا (المدفوعات، الصلاحيات) مقابل ماذا يمكن أن يكون "حسنًا في النهاية" (التحليلات)؟
- هل تحتاج حقيقة عالمية واحدة، أم تقبل "حقيقة محلية" لبعض البيانات؟
توقعات زمن الاستجابة: ما الذي سيشعر به المستخدمون
نموذج مفيد: المسافة تضيف زمنًا، والتنفيذ المتزامن يزيد زمنًا آخر. المسافة مسألة فيزيائية. التنسيق هو انتظار قاعدة البيانات موافقة العقد الأخرى قبل القول "تمت".
في إعداد PostgreSQL بمنطقة واحدة، يحدث معظم العمل معًا. عادة تكمل القراءات والكتابات في رحلة ذهاب وإياب واحدة من تطبيقك إلى قاعدة البيانات. إذا وضعت نسخة قراءة في منطقة أخرى، قد تكون القراءات محلية، لكن الكتابات لا تزال تذهب للمفتاح الأساسي والنسخ دائمًا متأخرة على الأقل بقليل.
في نظام موزع مثل CockroachDB، توزع البيانات عبر المناطق. هذا قد يجعل بعض القراءات سريعة عندما تكون البيانات المطلوبة قريبة. لكن العديد من الكتابات يجب أن تؤكد بواسطة أغلبية النسخ. إذا كانت بياناتك مكررة عبر قارات، حتى كتابة بسيطة قد تحتاج تأكيدات عبر المناطق.
لا تحكم من خلال زمن الاستجابة المتوسط. انظر إلى زمن p95 (أبطأ 5% من الطلبات). المستخدمون يلاحظون تلك التقطعات. صفحة عادةً تُحمّل في 120 ملّي ثانية ولكنها تصل إلى 800 ملّي ثانية عدة مرات في اليوم تبدو غير مستقرة، حتى لو كان المتوسط جيدًا.
ماذا يعني "سريع" يعتمد على حمل العمل. التطبيقات التي تعتمد على الكتابة تشعر بتكلفة التنسيق أكثر. التطبيقات التي تعتمد على القراءة تعمل جيدًا عندما تكون القراءات محلية. المعاملات الكبيرة، تدفقات العمل متعددة الخطوات، والصفوف "الساخنة" (التي يحدث عليها تحديث كثير من المستخدمين) تزيد من تأثير الزمن.
عند تقييم PostgreSQL مقابل CockroachDB، ارسم أهم إجراءات المستخدمين (تسجيل، دفع، بحث، تحديثات إدارية) وحدد أين تعيش البيانات وكم عدد المناطق التي يجب أن توافق على كل معاملة. هذا التمرين يتنبأ بما سيشعر به المستخدمون أفضل من مقارنات معيارية عامة.
مقايضات التشغيل: ما الذي ستديره يوميًا
قوائم الميزات أقل أهمية من ما يوقظك عند منتصف الليل وما الذي يجب على فريقك فعله كل أسبوع.
تشغيل PostgreSQL مألوف ومتوقع. تعدُّد المناطق عادة يعني أيضًا تشغيل مكونات داعمة: نسخ، أدوات تبديل الفشل، أو عناقيد إقليمية منفصلة مع توجيه على مستوى التطبيق. العمل غالبًا في إثبات أن الخطة تعمل (تدريبات الفشل، الاستعادة) بدلًا من ضبط الاستعلامات اليومي.
CockroachDB يضع جانبًا أكبر من قصة تعدد المناطق داخل قاعدة البيانات نفسها. هذا قد يقلل عدد المكونات الإضافية حول قاعدة البيانات، لكنه يعني أيضًا ضرورة فهم نظام موزع: صحة العقد، النسخ، إعادة التوازن، وما يفعله الكتستر تحت الضغط.
عمليًا، الفرق تنتهي إلى أداء نفس المهام الأساسية في أي إعداد:
- تخطيط التحديثات والتحقق من المحركات والمراقبة والأتمتة
- أخذ نسخ احتياطية وتجربة الاستعادة (ليس فقط التحقق من وجود النسخ)
- ممارسة التبديل في حالات الفشل وكتابة خطوات التشغيل بالضبط
- التحقيق في الاستعلامات البطيئة وفصل "الاستعلام السيئ" عن زمن العبور بين المناطق
- مراقبة نمو التخزين وسلوك الدمج طويل الأمد
أوضاع الفشل تبدو مختلفة. مع PostgreSQL، تعطل منطقة غالبًا يسبب تبديلًا مخططًا. قد تقبل فترة وضع للقراءة فقط، زمن متزايد، أو وظائف محدودة. في قاعدة موزعة، الحالة الأصعب غالبًا هي الانقسام الشبكي. قد تحمي النظام الاتساق برفض بعض الكتابات حتى يتوفر quorum.
الملاحظة أيضًا تتغير. مع مفتاح واحد، تسأل غالبًا: "لماذا هذا الاستعلام بطيء؟" مع كتستر موزع، تسأل أيضًا: "أين استقرت هذه البيانات، ولماذا عبر المناطق؟"
التكاليف ترتفع بطرق واضحة وغير واضحة. إضافة منطقة ثانية تزيد عدد العقد، لكنها أيضًا تزيد المراقبة، وتعقيد الحوادث، والوقت الذي تقضيه في شرح سلوكيات التأخير والفشل لفرق المنتج.
تغييرات المخطط والترحيلات في بيئة موزعة
تغيير المخطط هو أي تحديث لشكل بياناتك: إضافة عمود لميزة، إعادة تسمية حقل، تغيير نوع (من int إلى string)، إضافة فهرس، أو إدخال جدول جديد.
في PostgreSQL، الترحيلات قد تكون سريعة، لكن الخطر غالبًا هو زمن القفل وعرقلة الكتابات. بعض التغييرات تعيد كتابة جدول كامل أو تحتجز أقفالًا أطول مما توقعت، مما قد يحول نشرًا عاديًا إلى حادث إذا حدث أثناء ذروة المرور.
في قاعدة موزعة، ينتقل الخطر. حتى عندما تدعم التغييرات أثناء التشغيل، يجب أن يتم الاتفاق عبر العقد والتكرار عبر المناطق. التغيير "البسيط" قد يستغرق وقتًا أطول للنشر والقيام بالتحقق. قد تنتهي نشر العملية وما تزال تراقب التأخر، النقاط الساخنة، ومفاجآت خطة الاستعلام في كل منطقة.
بعض العادات تجعل الترحيلات مملة:
- فضّل التغييرات الإضافية أولًا (عمود جديد، جدول جديد). غيّر القراءة والكتابة بعد ذلك. أزل الحقول القديمة لاحقًا.
- اجعل كل ترحيل صغيرًا بما يكفي للعودة عنه بسرعة.
- تجنّب تغيير الأنواع في المكان إن أمكن. املأ عمودًا جديدًا لاحقًا.
- عامل الفهارس كإطلاق ميزة، لا كتعديل سريع.
- مارس الترحيلات بأحجام بيانات واقعية، لا قواعد بيانات اختبار فارغة.
مثال: تضيف preferred_language للمستخدمين في الاتحاد الأوروبي. أضف العمود، اكتب كلا الحقلين لإصدار واحد، حدّث الواجهة لقراءة الحقل الجديد، ثم نظّف القديم لاحقًا. في الإعدادات متعددة المناطق، الترحيلات المرحلية تقلل المفاجآت عندما تلحق المناطق بسرعات مختلفة.
التكلفة الحقيقية للذهاب للتوزيع مبكرًا
الاختيار بين PostgreSQL و CockroachDB مبكرًا ليس مجرد قرار قاعدة بيانات. يغير مدى سرعتك في الإطلاق، عدد مفاجآت الإنتاج، وكم من وقت فريقك يقضيه للحفاظ على استقرار النظام بدلًا من بناء ميزات.
إذا استطعت تحقيق أهدافك بمنطقة رئيسية واحدة، فالبساطة عادة تفوز في المراحل المبكرة. تحصل على أجزاء أقل متحركة، إخفاقات أوضح، وتصحيح أسرع. التوظيف أيضًا أسهل لأن خبرة PostgreSQL واسعة، والتطوير المحلي وCI أبسط.
الفرق تبقى مركزة أولًا لأن ذلك يدعم تكرارًا أسرع، تراجعات أبسط، وأداء أكثر توقعًا. التحمل عند الاستدعاء أسهل عندما يكون النظام أبسط.
الانتقال للتوزيع مبكرًا قد يكون الخيار الصحيح حين تكون المتطلبات حقيقية ولا تفاوض فيها: أهداف توافر صارمة عبر المناطق، احتياجات إقامة بيانات قانونية، أو قاعدة مستخدمين عالمية حيث الزمن يؤثر مباشرة على الإيرادات.
ضريبة التعقيد تظهر بطرق صغيرة تتراكم: العمل على الميزة يستغرق وقتًا أطول لأن عليك مراعاة السلوك متعدد المناطق، الاختبارات تحتاج تغطية أوضاع فشل أكثر، والحوادث تستغرق وقتًا أطول لأن أسباب الجذر قد تكون توقيتًا أو تكرارًا أو توافقًا بدلًا من "قاعدة البيانات معطلة". حتى تغييرات المخطط الأساسية تتطلب حذرًا أكبر.
قاعدة إبهام مفيدة: تحقق الطلب أولًا، ثم وزّع عندما تصبح المشكلة قابلة للقياس. محفزات شائعة هي فشل SLO مستمر في منطقة، تراجع مستخدمين ثابت بسبب التأخير، أو متطلبات امتثال تمنع إبرام صفقات.
إذا كنت تبني باستخدام أداة مثل AppMaster، يمكن أن يساعدك البدء بنشر أبسط بينما تصقل سير العمل ونماذج البيانات، ثم الانتقال إلى خطة متعدد المناطق بعد إثبات المنتج وأنماط المرور.
طريقة خطوة بخطوة للاختيار بينهما
"متعدد المناطق" يتضح عندما تحول الأمر إلى أرقام قليلة وتدفقات مستخدمين قليلة.
خطوة بخطوة
- اكتب RPO و RTO بكلمات بسيطة. مثال: "إذا ماتت منطقة، يمكن أن نفقد حتى دقيقة من البيانات (RPO)، ويجب أن نعود خلال 15 دقيقة (RTO)." إذا لم تستطع تحمل فقدان كتابات ملتزمة، قل ذلك صراحة.
- خرّط أين يوجد المستخدمون، وحدد الإجراءات التي تعتمد على الكتابة. اذكر مناطقك والإجراءات الرئيسية: التسجيل، الشراء، إعادة تعيين كلمة المرور، نشر تعليق، مشاهدة خلاصة. ليست كل الكتابات متساوية الأهمية.
- حدّد حاجة الاتساق لكل ميزة. المدفوعات، المخزون، وأرصدة الحساب عادة تحتاج صحة صارمة. الخلاصات، التحليلات، و"آخر ظهور" غالبًا تقبل تأخيرات بسيطة.
- عيّن ميزانية زمنية واختبر من المناطق المستهدفة. قرر ما معنى "سريع بما يكفي" (مثلاً 200 إلى 400 ملّي ثانية للإجراءات الرئيسية)، ثم قِس زمن الرحلة من المناطق التي تهمك.
- اختر نموذج تشغيل يمكن لفريقك دعمه. كن صريحًا بشأن وقت الاستدعاء، مهارات قاعدة البيانات، والقدرة على تحمل التعقيد.
مثال سريع
إذا كان معظم المستخدمين في الولايات المتحدة وجزء صغير في الاتحاد الأوروبي، قد تحتفظ بالكتابات في منطقة أساسية واحدة، تشدّد أهداف الاسترداد، وتضيف تحسينات قراءة للاتحاد الأوروبي للشاشات غير الحرجة. إذا كانت تدفقات الكتابة في الاتحاد الأوروبي بحاجة لتجربة أفضل، فكر بطبقة خدمة محلية أو طابور حتى تستجيب الواجهة بسرعة. راجع اختيار قاعدة البيانات عندما تصبح صحة متعدد المناطق مطلوبة للجداول الأساسية (الحسابات، الفوترة، الصلاحيات).
سيناريو مثال: عملاء الولايات المتحدة والاتحاد الأوروبي على نفس المنتج
تخيل SaaS B2B حيث لدى حساب زملاء في نيويورك وبرلين. الجميع يرى نفس التذاكر، الفواتير، وحدود الاستخدام. الفوترة مشتركة، لذا يجب أن تؤثر عملية دفع فورًا على صلاحية الوصول للحساب بأكمله.
مع PostgreSQL، إعداد شائع هو مفتاح واحد في الولايات المتحدة ونسخ قراءة في الاتحاد الأوروبي. يحصل مستخدمو الولايات المتحدة على قراءات وكتابات سريعة. يمكن لمستخدمي الاتحاد الأوروبي قراءة محليًا، لكن أي شيء يجب أن يكون صحيحًا الآن (الخطة الحالية، أحدث الصلاحيات، حالة الفواتير) غالبًا يجب أن يصل للمفتاح الأمريكي. إذا أتت قراءات الاتحاد الأوروبي من نسخة، تقبل أنها قد تتأخر. قد يبدو هذا كمستخدم مالي في برلين يدفع فاتورة، ثم عند التحديث يرى "متأخر الدفع" لبعض الوقت.
مع قاعدة موزعة متعددة المناطق مثل CockroachDB، يمكنك وضع البيانات أقرب لكلا المنطقتين مع الاحتفاظ بقاعدة منطقية واحدة. المقابل أن العديد من الكتابات وبعض القراءات يجب أن تنسق عبر المناطق للحفاظ على الاتساق. هذه الجولة الزائدة عبر المناطق تصبح جزءًا من المسار الطبيعي، خاصةً للسجلات المشتركة مثل إعدادات الحساب والفوترة.
خطة مرحلية تعمل عادة:
- ابدأ بمنطقة واحدة ومفتاح PostgreSQL، ثم قس أين يوجد المستخدمون والكتابات فعليًا.
- أضف نسخ قراءة في الاتحاد الأوروبي للتقارير والشاشات غير الحرجة.
- إذا احتاجت تدفقات كتابة الاتحاد الأوروبي إلى تجربة أفضل، ضع طبقة خدمة محلية أو طابور للحفاظ على استجابة الواجهة.
- أعد النظر في اختيار قاعدة البيانات عندما يصبح صحة متعدد المناطق مطلوبة للجداول الأساسية (الحسابات، الفواتير، الصلاحيات).
إذا بنيت على AppMaster، فالحفاظ على المنطق في عمليات أعمال مرئية قد يجعل تغييرات النشر أو استراتيجية قاعدة البيانات أسهل لاحقًا.
أخطاء شائعة ترتكبها الفرق
أكبر خطأ هو افتراض أن "متعدد المناطق" يعني تلقائيًا سريع للجميع. قاعدة موزعة لا تتغلب على الفيزياء. إن كانت المعاملة تحتاج تأكيدًا في مكانين بعيدين، يظهر زمن الرحلة في كل كتابة.
فخ شائع آخر هو مزج توقعات الصحة دون الإفصاح عنها. تطالب الفرق بدقة صارمة للأرصدة، المخزون، والصلاحيات، لكنها تعامل أجزاء أخرى من التطبيق كـ "قريبة بما يكفي". عندها يرى المستخدم قيمة على شاشة وقيمة مختلفة على التالية.
أنماط يجب الحذر منها:
- توقع أن كل الكتابات ستشعر كمحلية حتى عندما تتطلب تأكيدًا عبر المناطق
- التعامل مع الاتساق النهائي كتفصيل واجهة مستخدم واكتشاف أنه يكسر قواعد العمل (استردادات، حصص، التحكم في الوصول)
- تعلم الواقع التشغيلي فقط بعد الحادث الأول (النسخ الاحتياطية، التحديثات، صحة العقد، فشل المناطق)
- التقليل من زمن استكشاف المعاملات البطيئة عندما تكون السجلات واللوجز موزعة عبر المناطق
- اعتبار القرار الأول دائمًا بدلاً من تخطيط مسار تطوري
تستحق الترحيلات اهتمامًا خاصًا لأنها تحدث غالبًا عندما ينمو المنتج بسرعة. تغيير مخطط سهل على عقدة واحدة قد يصبح محفوفًا بالمخاطر عندما يجب الحفاظ على التناسق عبر عدة عقد ومناطق.
اعتبر اختيار قاعدة البيانات الأولى خطوة، لا قدرًا مكتوبًا. إذا كنت تبني مع AppMaster، يمكنك تصميم تجارب ونماذج بيانات بسرعة، ثم التحقق من زمن الاستجابة والسلوك عند الفشل قبل الالتزام بإعداد موزع معقد.
قائمة تحقق سريعة قبل الالتزام
قبل أن تختار اتجاهًا، عرّف ما معنى "جيد" لمنتجك. إعدادات متعدد المناطق يمكن أن تحل مشاكل حقيقية، لكنها تجبرك على اختيارات مستمرة حول الزمن، الاتساق، والتشغيل.
اجعل قائمة التحقق قصيرة ومحددة:
- حدّد أهم 3 إجراءات للمستخدم (مثال: تسجيل الدخول، الدفع، تحديث سجل مشترك) وأين يوجد هؤلاء المستخدمون.
- قرر ما يجب أن يكون متسقًا بقوة عبر المناطق، وما يمكن أن يتحمل تأخيرًا.
- اكتب قصة الفشل بكلمات بسيطة: "إذا تعطلت المنطقة X لمدة ساعة، يمكن لمستخدمي المنطقة Y أن يقوموا بـ A و B، لكن ليس C."
- خصّص ملكية للنسخ الاحتياطية، اختبار الاستعادة، التحديثات، والمراقبة.
- صغ خطة لتغييرات المخطط تحافظ على التوافق أثناء الإطلاق المرحلي.
إذا كنت تبني بمنصة بدون كود مثل AppMaster، وضع هذه القائمة في ملاحظات البناء يساعد في محاذاة نموذج البيانات والمنطق وخطوات النشر مع تغير المتطلبات.
الخطوات التالية: اختبر فروضك واختر مسار البناء
معظم الفرق لا تحتاج قاعدة موزعة منذ اليوم الأول. يحتاجون سلوكًا متوقعًا، عمليات أبسط، وطريقة واضحة للنمو.
هذا القرار عادة يعود إلى سؤال واحد: هل تحتاج كتابات صحيحة ونشطة في مناطق متعددة لتدفقات العمل الأساسية؟
- إذا استطعت الاحتفاظ بمنطقة أساسية واحدة واستخدام نسخ، ذاكرات مؤقتة، أو نسخ قراءة في أماكن أخرى، فـ PostgreSQL غالبًا مناسب جدًا.
- إذا كنت تحتاج حقًا لكتابة متعددة المناطق مع اتساق قوي، فـ SQL الموزع قد يناسب طالما قبلت زمن كتابة أساسي أعلى وتعقيدًا تشغيليًا أكبر.
طريقة عملية لاختبار الاختيار هي إجراء إثبات مركز باستخدام تدفقات عمل حقيقية.
خطة إثبات صغيرة (1-2 يوم)
- قس زمن p95 من كل منطقة تهتم بها (قراءات وكتابات).
- حاكي وضع فشل واحد (أوقف عقدة، حجب منطقة، أو عطّل حركة المرور بين المناطق) وسجل ما تعطل.
- شغّل 2-3 معاملات حرجة كاملة (تسجيل، دفع، تحديث ملف) وراقب المحاولات، المهلات، والأخطاء المرئية للمستخدم.
- جرّب تغيير مخطط واحد تتوقع القيام به كثيرًا (إضافة عمود، إضافة فهرس). وقّت العملية وسجل ما تعطل.
بعد ذلك، اكتب ملكية البيانات. أي منطقة "تمتلك" سجل العميل؟ أي جداول يجب أن تكون متسقة بقوة، وأيها يمكن أن يكون متسقًا في النهاية (مثل أحداث التحليلات)؟ كما قرر ما الذي سيطلق ترحيل لاحقًا، كيف ستملأ البيانات بأثر رجعي، وكيف ستتراجع.
مسار بناء شائع هو البدء على PostgreSQL، الحفاظ على مخطط نظيف (مفاتيح أساسية واضحة، عدد أقل من نقاط الكتابة العرضية عبر جداول)، وتصميم بحيث يكون تقسيم البيانات الإقليمية أسهل لاحقًا.
إذا كنت تستخدم AppMaster، يمكنك نمذجة مخطط PostgreSQL في مصمم البيانات وتوليد تطبيقات جاهزة للإنتاج لنشرها على السحابة بينما تتحقق مما إذا كانت الكتابات متعددة المناطق مطلوبة فعلاً.
إذا أردت استكشاف هذا النهج، AppMaster on appmaster.io طريقة مباشرة لنمذجة الكومة الكاملة (الخلفية، الويب، والهواتف) دون الالتزام مبكرًا بهندسة متعدد المناطق المعقدة.
الأسئلة الشائعة
ابدأ بكتابة الفشل الدقيق الذي تريد تحمّله (انقطاع كامل لمنطقة، فقدان عقدة قاعدة بيانات، أو فصل شبكي بين المناطق) وماذا يجب أن يظل المستخدمون قادرين على فعله خلال هذا الحدث. ثم عيّن أهدافًا واضحة لمدى البيانات المقبولة أن تُفقد (RPO) وكم بسرعة يجب الاسترداد (RTO). بمجرد أن تصبح هذه النقاط صريحة، تصبح مقايضات PostgreSQL مقابل CockroachDB أسهل لتقييمها.
PostgreSQL غالبًا خيار افتراضي جيد إذا استطعت الاحتفاظ بمنطقة رئيسية واحدة للكتابة وتقبلت عملية فشل قصيرة خلال انقطاع منطقة. تشغيله أبسط، التوظيف أسهل لأن الخبرة شائعة، وعادة ما تكون زمنات الكتابة أسرع بالقرب من المنطقة الأساسية. أضف نسخًا قراءة في مناطق أخرى عندما تريد قراءات أسرع ويمكنك تحمل بعض تأخر التكرار.
CockroachDB يناسب عندما تحتاج فعلاً أن يبقى النظام صحيحًا وقابلاً للكتابة حتى أثناء انقطاع منطقة، بدون ترقية يدوية للمفتاح الأساسي. المقابل هو زمن كتابة أساسي أعلى وتعقيد تشغيلي أكبر لأن قاعدة البيانات يجب أن تُنسق بين النسخ للحفاظ على الاتساق القوي. مناسب عندما تكون صحة البيانات عبر المناطق مطلبًا لا تفاوض فيه.
نمط شائع هو وجود مفتاح PostgreSQL واحد للقراءة والكتابة، مع نسخ قراءة في مناطق أخرى لأداء القراءة المحلي. توجه الشاشات القرائية أو غير الحساسة للتأخر نحو النسخ، وكل ما يتطلب صحة صارمة (كحالة الفواتير أو الصلاحيات) يذهب للمفتاح الأساسي. هذا يحسّن تجربة المستخدم دون تبنّي تعقيد الكتابة الموزعة فورًا.
تأخر النسخ قد يجعل المستخدمين يرون بيانات قديمة لفترة قصيرة، وهذا قد يكسر سير العمل إذا افترضت الخطوات التالية أن الكتابة الأخيرة مرئية في كل مكان. للحد من المخاطر، احتفظ بالقراءات الحرجة على المفتاح الأساسي، صمّم واجهة المستخدم لتحمّل تأخيرات قصيرة في الشاشات غير الحرجة، وأضف محاولات إعادة أو مطالبات بالتحديث حيث يلزم. الفكرة الأساسية هي تحديد مسبقًا الميزات التي يمكن أن تكون "متسقة في النهاية" وتلك التي لا يمكن.
الكتابات متعددة المناطق عادة تزيد الزمن لأن قاعدة البيانات تحتاج تأكيد الكتابة من نسخ موجودة في مناطق مختلفة قبل إعلانها "مكتملة". كلما كانت المناطق أبعد، كلما ظهر زمن التنسيق هذا في زمن الاستجابة (خصوصًا في p95). إذا كان التطبيق كثير الكتابة أو يحتوي على معاملات متعددة الخطوات التي تلمس صفوفًا مشتركة، فالجولات الإضافية قد تكون ملحوظة جدًا للمستخدمين.
ركّز على زمن p95 لأهم إجراءات المستخدمين، وليس المتوسطات أو المقاييس التركيبية فقط. قسّ أوقات القراءة والكتابة الحقيقية من المناطق التي يوجود فيها مستخدموك، واختبر عددًا من تدفقات العمل الحرجة نهاية إلى نهاية (تسجيل، شراء، تغييرات صلاحيات). كذلك قم بمحاكاة وضع فشل واحد على الأقل وسجل ما يراه المستخدمون، لأن "يعمل في ظروف طبيعية" ليس هو نفسه "يعمل أثناء انقطاع".
مع PostgreSQL، الجزء المخيف غالبًا هو زمن القفل وعرقلة الكتابات أثناء بعض تغييرات المخطط على الجداول الكبيرة. في الأنظمة الموزعة، قد تظل التغييرات "عبر الإنترنت" لكنها تستغرق وقتًا أطول لانتشارها وقد تكشف عن نقاط ساخنة أو تغييرات في خطة الاستعلام عبر المناطق. النهج الأكثر أمانًا في كلتا الحالتين هو الترحيلات المرحلية والإضافية التي تحافظ على توافق التطبيق أثناء تحول البيانات وحركة المرور تدريجيًا.
انقطاع كامل لمنطقة في PostgreSQL غالبًا ما يؤدي إلى فشل مخطط حيث ترقي نسخة وتوجّه التطبيق للمفتاح الجديد، أحيانًا مع توقف قصير عن الكتابة. في نظام موزع، السيناريو الأصعب غالبًا هو انقسام الشبكة، حيث قد ترفض قاعدة البيانات بعض الكتابات لحماية الاتساق حتى تتوفر أغلبية quorum مجددًا. يجب أن تغطي إجراءات التشغيل كلا النوعين من الأحداث، وليس فقط "قاعدة البيانات متوقفة".
نعم، إذا عاملت القرار كخطوة تطورية بدلًا من قرار نهائي. ابدأ بنموذج كتابة بولاية منطقة واحدة، حافظ على مخطط نظيف، وجعل احتياجات تعدد المناطق صريحة لكل ميزة حتى لا تعتمد عن غير قصد على قراءات متأخرة في سير عمل حرج. إذا بنيت على AppMaster، يمكنك التكرار سريعًا على نماذج البيانات والمنطق، والتحقق من زمن الاستجابة والسلوك عند الفشل في اختبارات تشبه الإنتاج، ثم الانتقال إلى خطة أكثر تعقيدًا عند إثبات الحاجة.


