معماريات التوفر العالي
معماريات التوفر العالي
قاعدة البيانات التي تتوقف تُسقط معها المنتج بأكمله. كل طبقة أخرى في المكدس — موازنات الأحمال وخوادم التطبيقات وشبكات توصيل المحتوى — يمكن جعلها عديمة الحالة واستبدالها في ثوانٍ. قواعد البيانات لا يمكن ذلك. هي تملك الحالة، وفقدانها يعني فقدان بيانات المستخدم وتاريخ المعاملات وكثيراً ما يعني فقدان العمل بأكمله. معمارية التوفر العالي (HA) هي مجموعة الأنماط التي تجعل مجموعة قواعد البيانات تتحمل إخفاقات العقد وتقسيمات الشبكة وانقطاعات منطقة التوفر دون تدخل بشري. يُغطي هذا الدرس الركائز الثلاث للتوفر العالي في الإنتاج: طوبولوجيا التكرار، ومقايضات التكرار المتزامن مقابل غير المتزامن، والتحويل التلقائي عند الإخفاق.
نموذج الأساسي/النسخة المتماثلة
النمط الأساسي للتوفر العالي في قواعد البيانات العلائقية هو التكرار بين الأساسي والنسخة المتماثلة (Primary/Replica) (يُسمى تاريخياً master/slave). عقدة واحدة — الأساسية — تقبل جميع عمليات الكتابة. عقدة واحدة أو أكثر من النسخ المتماثلة تستقبل تدفقاً من التغييرات من الأساسي وتُعيد تشغيلها للحفاظ على نسخة متطابقة من البيانات.
يُعطيك هذا الفصل ثلاثة أشياء في وقت واحد:
- التكرار: إذا مات الأساسي، يمكن ترقية نسخة متماثلة لتحل محله.
- قابلية التوسع في القراءة: أحمال عمل القراءة الكثيفة يمكنها توزيع استعلامات SELECT عبر النسخ المتماثلة، مما يُخفّف ضغط الكتابة على الأساسي.
- السلامة التشغيلية: استعلامات التحليلات الطويلة تعمل على نسخة متماثلة دون إبطاء عمليات الكتابة التشغيلية على الأساسي.
DROP TABLE المدمر. التكرار والنسخ الاحتياطي يحلان أنماط إخفاق مختلفة وكلاهما مطلوب في الإنتاج.في PostgreSQL، يُبنى التكرار على بث سجل الكتابة المسبقة (WAL Streaming). كل معاملة على الأساسي تُكتب أولاً في WAL؛ تتصل النسخ المتماثلة كعملاء بث التكرار وتستقبل مقاطع WAL في شبه وقت فعلي. في MySQL/MariaDB، المكافئ هو سجل الثنائيات (binlog) المُبثّ بتنسيق قائم على الصفوف. كلا الآليتين تعنيان أن النسخ المتماثلة لا تقرأ مباشرة من جداول الأساسي — إنها تُعيد تشغيل سجل التغييرات، مما يجعل التكرار خفيفاً حتى عند معدلات كتابة عالية.
التكرار المتزامن مقابل غير المتزامن
أهم قرار معماري في التوفر العالي لقواعد البيانات هو ما إذا كان التكرار متزامناً أم غير متزامن. هذا ليس تفضيلاً — إنه مقايضة مباشرة بين ضمانات المتانة وزمن استجابة الكتابة، والاختيار الخاطئ يُسبب فقدان البيانات أو إبطاء مقبول.
التكرار غير المتزامن (الافتراضي في معظم المحركات): يكتب الأساسي إلى WAL الخاص به، ويُنفّذ، ويُقرّ بالنجاح للعميل، ثم يشحن WAL إلى النسخ المتماثلة في الخلفية. إذا تعطل الأساسي قبل أن تستهلك النسخة المتماثلة أحدث الإدخالات، تضيع تلك الإدخالات نهائياً — يُسمى هذا تأخر التكرار الذي يصبح فقدان بيانات أثناء التحويل عند الإخفاق. الميزة: مسار التنفيذ على الأساسي لا يُضيف أي زمن استجابة من رحلات الشبكة إلى النسخ المتماثلة.
التكرار المتزامن: يكتب الأساسي إلى WAL ولا يُقرّ بتنفيذ العميل إلا بعد أن تؤكد نسخة متماثلة متزامنة محددة على الأقل أنها استلمت إدخال WAL وحوّلته إلى تخزين دائم. لا يمكن فقدان أي بيانات عند التحويل إلى تلك النسخة المتماثلة. التكلفة: كل عملية كتابة تتحمل رحلة شبكة إضافية إلى النسخة المتماثلة — عادةً 0.5–2 مللي ثانية في نفس منطقة التوفر، و5–30 مللي ثانية عبر مناطق التوفر. عند معدلات كتابة عالية (آلاف المعاملات في الثانية)، يتراكم هذا الزمن.
الحل الصناعي في شركات مثل Google (Spanner, AlloyDB) وAWS (Aurora) هو استخدام بروتوكول كتابة قائم على النصاب القانوني يحقق متانة متزامنة عبر عقد متعددة بينما يُخفي معظم عقوبة زمن الاستجابة. Aurora مثلاً تكتب سجل السجل إلى 6 عقد تخزين عبر 3 مناطق توفر وتُقرّ بالتنفيذ بعد أن تؤكد 4 من 6 — يوفر هذا ضمانات متزامنة مع توافر أفضل بكثير من نسخة متماثلة متزامنة واحدة.
بالنسبة لـ PostgreSQL تحديداً، يمكنك ضبط تنفيذ متزامن على مستوى الجلسة أو الخادم:
يوفر MySQL/InnoDB Group Replication ومكونات شبه المتزامنة الإضافية ضوابط مماثلة. في الخدمات المُدارة (RDS Multi-AZ, CloudSQL)، يُضبط وضع المزامنة على مستوى المثيل ويتولى المحرك شحن WAL بشفافية.
التحويل التلقائي عند الإخفاق
وجود نسخة متماثلة دافئة ليس توفراً عالياً. التوفر العالي يتطلب أنه عند إخفاق الأساسي، تُرقَّى نسخة متماثلة لتصبح أساسية تلقائياً — دون أن يستيقظ إنسان في الثالثة صباحاً ليُشغّل pg_ctl promote. التحويل التلقائي هو المُميّز التشغيلي بين نظام به نسخ متماثلة ونظام بتوفر عالي حقيقي.
مكونات نظام التحويل التلقائي في الإنتاج هي:
- مراقبة الصحة: وكيل أو حاوية جانبية تستطلع الأساسي باستمرار. نبضة قلب مفقودة وحدها غير كافية — التطبيقات الجيدة تُميّز بين "الأساسي غير متاح من هذه العقدة" و"الأساسي غير متاح من غالبية المجموعة" لتجنب الدماغ المنقسم.
- انتخاب القائد / النصاب القانوني: آلية توافق موزعة (عادةً قائمة على Raft أو Paxos — etcd أو ZooKeeper أو توافق مدمج في المحرك) تنتخب بأمان أساسياً جديداً واحداً بالضبط. يمنع متطلب النصاب القانوني عقدتين من ترقية نفسيهما في وقت واحد وقبول كتابات متضاربة.
- الترقية: تُرقَّى النسخة المتماثلة الفائزة لتصبح أساسية — يتوقف إعادة تشغيل WAL وتُقبل اتصالات الكتابة.
- إعادة التوجيه: طبقة الاتصال (IP افتراضي أو تحويل DNS أو وسيط مثل PgBouncer/ProxySQL) تُعيد توجيه حركة التطبيق إلى الأساسي الجديد. يجب أن تستخدم التطبيقات نقطة نهاية واحدة تشير دائماً إلى الأساسي الحالي — تضمين عناوين IP للنسخ المتماثلة يكسر هذا.
- عزل الأساسي القديم (STONITH): يُعزل الأساسي السابق قبل أن يقبل الأساسي الجديد عمليات الكتابة. بدون العزل، يمكن لأساسي توقف مؤقتاً (جمع القمامة، انقطاع الشبكة) ثم عاد، أن يعتقد لفترة أنه لا يزال أساسياً، مما يُسبب نافزة كتابة بدماغ منقسم.
Patroni: التحويل التلقائي في الإنتاج لـ PostgreSQL
الحل الأكثر شيوعاً مفتوح المصدر للتوفر العالي في PostgreSQL هو Patroni، المستخدم في الإنتاج في Zalando وGitLab وAiven وكثيرين آخرين. يعمل Patroni كحاوية جانبية على كل عقدة PostgreSQL ويستخدم etcd (أو Consul أو ZooKeeper) كمخزن توافق موزع للاحتفاظ بقفل قائد المجموعة. العقدة التي تحمل القفل هي الأساسية؛ وجميع الأخريات نسخ متماثلة. تبدو إعدادات Patroni البسيطة هكذا:
مع ضبط maximum_lag_on_failover، يرفض Patroni ترقية نسخة متماثلة تخلفت كثيراً — مما يمنع ترقية عقدة قديمة تُلغي معاملات مُنفَّذة. مزيج synchronous_mode: true وحد تأخر منخفض يمنحك ضمانات متانة قوية دون بناء تنسيق مخصص.
RTO وRPO للتحويل عند الإخفاق في الممارسة
مقياسان يحكمان ما تعِد به معمارية التوفر العالي للأعمال فعلياً:
- هدف وقت الاسترداد (RTO): مدة عدم إتاحة قاعدة البيانات أثناء التحويل. مع Patroni، يكتمل التحويل التلقائي النموذجي في 15–45 ثانية من لحظة توقف الأساسي عن إرسال نبضات القلب (إعداد
ttlفي Patroni هو العامل المهيمن). تحقق الخدمات المُدارة مثل RDS Multi-AZ عادةً 20–60 ثانية. صمّم منطق إعادة المحاولة في اتصال تطبيقك حول هذه النافزة — قواطع الدائرة وإعادة المحاولة مع التراجع ليست اختيارية. - هدف نقطة الاسترداد (RPO): كمية البيانات التي يمكن فقدانها في أسوأ الحالات. مع التكرار غير المتزامن، يساوي RPO تأخر التكرار وقت الإخفاق — يحتمل أن تكون ثواني إلى دقائق من المعاملات المُنفَّذة. مع التكرار المتزامن على نسخة متماثلة واحدة على الأقل، يكون RPO صفراً للتحويل إلى تلك النسخة المتماثلة.
التوفر العالي متعدد مناطق التوفر مقابل متعدد المناطق
التكرار المتزامن عبر مناطق التوفر (AZs داخل نفس منطقة AWS) هو الأساس في الإنتاج — رحلة الشبكة 0.5–2 مللي ثانية، مما يجعل التنفيذ المتزامن عملياً. التكرار المتزامن عبر مناطق (زمن استجابة 50–200 مللي ثانية) نادراً ما يُستخدم لـ OLTP لأن عقوبة زمن استجابة الكتابة حظرية. النسخ المتماثلة عبر المناطق تكون دائماً تقريباً غير متزامنة وتُستخدم كأهداف استرداد الكوارث (DR)، لا مرشحات للتحويل التلقائي. المقايضة: إذا فُقدت المنطقة الأساسية بالكامل، فإن ترقية نسخة متماثلة غير متزامنة عبر المناطق هي عملية يدوية وتقبل فقدان البيانات المساوي لتأخر التكرار.
تحل قاعدة بيانات AWS Aurora العالمية جزءاً من هذا باستخدام طبقة التخزين المخصصة للتكرار عبر المناطق بأقل من ثانية واحدة من التأخر — لا تزال غير متزامنة بمعنى CAP، لكن تشغيلياً أسرع بكثير من التكرار التدفقي التقليدي. للأنظمة التي تتطلب RPO صفري عبر المناطق، تكون Spanner أو CockroachDB مع التوافق المتزامن متعدد المناطق هي الخيارات، بتكلفة وتعقيد كبيرين.