دليل لفهم أنماط توسيع قاعدة البيانات

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

لذلك ، أخطط لمناقشة بعض التقنيات بالتفصيل في مقالات مستقبلية. للبدء ، أشعر أنه من الأفضل أن أناقش التقنيات خطوة بخطوة مع بعض السياق بطريقتي الخاصة. هذه المقالة هي مقالة عالية المستوى - لن أناقش تقنيات القياس بالتفصيل هنا ، لكنني سأقدم نظرة عامة. اذا هيا بنا نبدأ.

دراسة حالة

افترض أنك قد أنشأت شركة ناشئة تقدم مشاركة الركوب بتكلفة رخيصة. في البداية ، عندما تبدأ ، فإنك تستهدف مدينة وبالكاد يكون لديك عشرات العملاء بعد إعلانك الأولي.

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

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

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

النمط 1 - تحسين الاستعلام وتنفيذ تجمع الاتصال:

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

أنت تحدد أن قاعدة البيانات الخاصة بك ربما تكون طبيعية بشكل كبير ، لذلك تقوم بإدخال بعض الأعمدة الزائدة (تظهر هذه الأعمدة بشكل متكرر في الاستعلامات WHEREأو JOIN ONعبارة في الاستعلامات) في جداول مستخدمة بشكل كبير من أجل عدم التطابق. يؤدي ذلك إلى تقليل استعلامات الانضمام ، وتقسيم استعلام كبير إلى استعلامات متعددة أصغر ، وإضافة نتائجها في طبقة التطبيق.

التحسين المتوازي الآخر الذي يمكنك القيام به هو التغيير والتبديل حول اتصالات قاعدة البيانات. مكتبات عملاء قاعدة البيانات والمكتبات الخارجية متوفرة بجميع لغات البرمجة تقريبًا. يمكنك استخدام مكتبات تجمّع الاتصال لتخزين اتصالات قاعدة البيانات مؤقتًا أو يمكنك تكوين حجم تجمع الاتصال في نظام إدارة قاعدة البيانات نفسه.

يعد إنشاء أي اتصال بالشبكة مكلفًا لأنه يتطلب بعض الاتصالات ذهابًا وإيابًا بين العميل والخادم. قد تساعدك اتصالات التجميع على تحسين عدد الاتصالات. قد تساعدك مكتبات تجمع الاتصالات في اتصالات متعددة - يمكن أن تستخدم مؤشرات ترابط تطبيق متعددة نفس اتصال قاعدة البيانات. سأرى ما إذا كان بإمكاني شرح تجميع الاتصالات بالتفصيل في مقال منفصل لاحقًا.

كمون القياس الخاص بك لواجهات برمجة التطبيقات الخاصة بك وربما تجد 20-50٪ أو أكثر من تقليل وقت الاستجابة. هذا تحسين جيد في هذه المرحلة من الزمن.

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

النمط 2 - التحجيم الرأسي أو التوسع:

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

ولكن كيف يمكنك إعداد آلة للقياس الرأسي؟

أنت تخصص آلة أكبر. تتمثل إحدى الطرق في عدم ترحيل البيانات يدويًا من الجهاز القديم بدلاً من ضبط الجهاز الجديد على الجهاز replicaالحالي ( primary) - قم بعمل primary replicaتكوين مؤقت . دع التكرار يحدث بشكل طبيعي. بمجرد الانتهاء من النسخ المتماثل ، قم بترقية الجهاز الجديد إلى الأساسي وانقل الجهاز الأقدم إلى وضع عدم الاتصال. نظرًا لأنه من المتوقع أن تخدم الآلة الأكبر حجمًا كل الطلبات ، فستحدث كل القراءة / الكتابة على هذا الجهاز.

رائع. النظام الخاص بك يعمل مرة أخرى مع زيادة الأداء.

عملك يعمل بشكل جيد للغاية وقررت التوسع إلى 3 مدن أخرى - أنت الآن تعمل في 5 مدن إجمالاً. كانت حركة المرور 3 أضعاف مما كانت عليه سابقًا ، ومن المتوقع أن تقوم بحجز حوالي 300 في الدقيقة. حتى قبل تحقيق هذا الحجز المستهدف ، فإنك تضغط مرة أخرى على أزمة الأداء ، ويزداد حجم فهرس قاعدة البيانات بشكل كبير في الذاكرة ، ويحتاج إلى صيانة مستمرة ، ومسح الجدول باستخدام الفهرس أصبح أبطأ من أي وقت مضى. تقوم بحساب تكلفة توسيع نطاق الجهاز بشكل أكبر ولكنك غير مقتنع بالتكلفة. ماذا تعمل الأن؟

النمط 3 - الفصل بين مسؤولية استعلام الأوامر (CQRS):

أنت تدرك أن الآلة الكبيرة غير قادرة على التعامل مع جميع read/writeالطلبات. أيضًا في معظم الحالات ، تحتاج أي شركة إلى قدرة معاملات writeعلى readالعمليات وليس عليها . أنت أيضًا بخير مع القليل من readالعمليات غير المتسقة أو المتأخرة ، ولا توجد مشكلة في عملك أيضًا. ترى فرصة حيث قد يكون خيارًا جيدًا لفصل read& writeالعمليات الفعلية عن الآلة. سيخلق مجالًا للآلات الفردية للتعامل مع المزيد من read/writeالعمليات.

أنت الآن تأخذ جهازيْن كبيرَين آخرَين وتقوم بإعدادهما replicaعلى الجهاز الحالي. سيهتم نسخ قاعدة البيانات بتوزيع البيانات من primaryالجهاز إلى replicaالأجهزة. يمكنك التنقل في جميع استعلامات القراءة (الاستعلام ( Q) في CQRS) إلى النسخ المتماثلة - replicaيمكن لأي منها أن يخدم أي طلب قراءة ، ويمكنك التنقل في جميع استعلامات الكتابة (الأمر ( C) في CQRS) إلى primary. قد يكون هناك تأخير بسيط في النسخ المتماثل ، ولكن وفقًا لحالة استخدام عملك ، فلا بأس بذلك.

يمكن لمعظم الشركات الناشئة متوسطة الحجم التي تخدم بضع مئات الآلاف من الطلبات يوميًا البقاء على قيد الحياة من خلال إعداد النسخ المتماثلة الأولية بشرط أن تقوم بأرشفة البيانات القديمة بشكل دوري.

أنت الآن تتوسع إلى مدينتين أخريين ، وترى أنه primaryلا يمكنك التعامل مع جميع writeالطلبات العديد من writeالطلبات لديها زمن انتقال. وعلاوة على ذلك، فإن فجوة بين primaryو replicaأحيانا العملاء تأثير والسائقين السابقين - عندما تنتهي الرحلة، ويدفع الزبون برنامج التشغيل بنجاح، ولكن السائق غير قادر على رؤية دفع منذ النشاط الزبون هو writeطلب أن يذهب إلى primary، في حين أن النشاط السائق هو readطلب يذهب إلى إحدى النسخ المتماثلة. نظامك بشكل عام بطيء جدًا لدرجة أن السائق غير قادر على رؤية الدفع لمدة نصف دقيقة على الأقل - وهو أمر محبط لكل من السائق والعميل. كيف يمكن حلها؟

النمط 4 - النسخ المتماثل الأساسي المتعدد

لقد تطورت جيدًا باستخدام primary-replicaالتكوين ، لكنك الآن بحاجة إلى المزيد من أداء الكتابة. قد تكون مستعدًا للتنازل قليلاً عن readأداء الطلب. لماذا لا توزع طلب الكتابة على replicaأيضا؟

في multi-primaryالتكوين ، يمكن لجميع الآلات أن تعمل على حد سواء primary& replica. يمكنك التفكير في multi-primaryدائرة من الآلات A->B->C->D->A. Bيمكن تكرار البيانات من A، Cويمكن تكرار البيانات من B، Dويمكن تكرار البيانات من C، Aويمكن تكرار البيانات من D. يمكنك كتابة البيانات إلى أي عقدة ، أثناء قراءة البيانات ، يمكنك بث الاستعلام إلى جميع العقد ، ومن يرد ذلك. ستحتوي جميع العقد على نفس مخطط قاعدة البيانات ، ونفس مجموعة الجداول ، والفهرس ، وما إلى ذلك ، لذا عليك التأكد من عدم وجود تضارب idبين العقد في نفس الجدول ، وإلا أثناء البث ، فإن العقد المتعددة ستعيد بيانات مختلفة لنفسها id.

بشكل عام ، من الأفضل استخدام UUIDأو GUIDمعرف. هناك عيب آخر لهذه التقنية - readقد تكون الاستعلامات غير فعالة لأنها تتضمن استعلام البث والحصول على النتيجة الصحيحة - نهج التجميع المبعثر بشكل أساسي.

أنت الآن تتوسع إلى 5 مدن أخرى ونظامك يعاني من الألم مرة أخرى. من المتوقع أن تتعامل مع ما يقرب من 50 طلبًا في الثانية. أنت في حاجة ماسة للتعامل مع عدد كبير من الطلبات المتزامنة. كيف حققت هذا؟

النمط 5 - التقسيم:

أنت تعرف أن لديك locationقاعدة بيانات شيء والتي تزداد عالية writeو readحركة المرور. ربما تكون write:readالنسبة 7:3. هذا يضع الكثير من الضغط على قواعد البيانات الموجودة. في locationالجداول تحتوي على القليل من البيانات الأساسية مثل longitude، latitude، timestamp، driver id، trip idوما إلى ذلك لم يكن لديك الكثير لتفعله مع رحلات المستخدم، بيانات المستخدم والبيانات دفع الخ ماذا عن فصل locationالجداول في مخطط قاعدة بيانات منفصلة؟ ماذا عن وضع قاعدة البيانات هذه في أجهزة منفصلة ذات تهيئة مناسبة primary-replicaأو مناسبة multi-primary؟

وهذا ما يسمى بتقسيم البيانات حسب الوظيفة. يمكن لقاعدة البيانات المختلفة أن تستضيف البيانات المصنفة حسب وظائف مختلفة ، إذا لزم الأمر ، يمكن تجميع النتيجة في طبقة النهاية الخلفية. باستخدام هذه التقنية ، يمكنك التركيز على توسيع نطاق تلك الوظائف التي تتطلب read/writeطلبات عالية بشكل جيد . على الرغم من أن النهاية الخلفية أو طبقة التطبيق يجب أن تتحمل مسؤولية الانضمام إلى النتائج عند الضرورة مما يؤدي إلى المزيد من التغييرات في الكود على الأرجح.

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

النمط 6 - القياس الأفقي:

أنت تقوم بالكثير من البحث على Google ، وتقرأ كثيرًا عن كيفية حل الشركات الأخرى للمشكلة - وتوصلت إلى استنتاج أنك بحاجة إلى التوسع أفقيًا. يمكنك تخصيص 50 جهازًا - تحتوي جميعها على نفس مخطط قاعدة البيانات الذي يحتوي بدوره على نفس مجموعة الجداول. كل الآلات تحتوي فقط على جزء من البيانات.

نظرًا لأن جميع قواعد البيانات تحتوي على نفس المجموعة من الجداول ، يمكنك تصميم النظام بطريقة تجعل مكان البيانات موجودًا أي ؛ جميع البيانات ذات الصلة تقع في نفس الجهاز. يمكن أن يكون لكل جهاز نسخ متماثلة خاصة به ، ويمكن استخدام النسخ المتماثلة في استرداد الفشل. يتم استدعاء كل من قواعد البيانات shard. يمكن أن تحتوي الآلة المادية على واحد أو أكثر shards- الأمر متروك لتصميمك بالطريقة التي تريدها. تحتاج إلى اتخاذ قرار sharding keyبطريقة sharding keyتشير فيها دائمًا إلى نفس الجهاز. لذلك يمكنك تخيل الكثير من الأجهزة التي تحتفظ جميعها ببيانات ذات صلة في نفس مجموعة الجداول ، أو read/writeطلبات لنفس الصف أو نفس مجموعة أراضي الموارد في نفس جهاز قاعدة البيانات.

التقاسم صعب بشكل عام - على الأقل المهندسين من شركات مختلفة يقولون ذلك. ولكن عندما تقدم ملايين أو مليارات الطلبات ، عليك اتخاذ مثل هذا القرار الصعب.

سأناقش shardingبمزيد من التفصيل في رسالتي التالية ، لذا كبح إغرائي لمناقشة المزيد في هذا المنشور.

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

النمط 7 - القسم الحكيم لمركز البيانات:

ينمو عملك في أمريكا وجنوب آسيا وفي عدد قليل من البلدان في أوروبا. أنت تقوم بملايين الحجوزات يوميًا مع وصول مليارات الطلبات إلى خادمك. تهانينا - هذه هي ذروة نشاطك التجاري.

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

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

تكون تقنية القياس هذه مفيدة عندما يكون لديك ملايين العملاء للخدمة عبر البلدان ولا يمكنك استيعاب أي فقدان للبيانات ، وعليك دائمًا الحفاظ على توفر النظام.

هذه بعض الأساليب العامة خطوة بخطوة لتوسيع نطاق قاعدة البيانات. على الرغم من أن معظم المهندسين لا يحصلون على فرصة كافية لتنفيذ هذه التقنيات ، إلا أنه من الأفضل بشكل عام الحصول على فكرة أوسع حول هذا النظام والتي قد تساعدك في المستقبل على القيام بتصميم أفضل للنظام والهندسة المعمارية.

سأحاول في مقالاتي القادمة مناقشة بعض المفاهيم بالتفصيل. لا تتردد في تقديم الملاحظات المناسبة لهذا المنشور إن وجدت.

تم نشر المقال في الأصل على حساب المؤلف المتوسط: //medium.com/@kousiknath/understanding-database-scaling-patterns-ac24e5223522