يجب أن يعرف المزيد من المطورين هذا عن قواعد البيانات

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

يجب أن يعرف المزيد من المطورين هذا عن قواعد البيانات

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

  1. أنت محظوظ إذا كانت الشبكة لا تسبب مشكلات بنسبة 99,999% من الوقت.
  2. ACID يعني أشياء كثيرة مختلفة.
  3. ولكل قاعدة بيانات آلياتها الخاصة لضمان الاتساق والعزلة.
  4. يأتي الحظر المتفائل للإنقاذ عندما يكون من الصعب الحفاظ على الحظر المعتاد.
  5. هناك حالات شاذة أخرى إلى جانب القراءات القذرة وفقدان البيانات.
  6. لا تتفق قاعدة البيانات والمستخدم دائمًا على مسار العمل.
  7. يمكن نقل المشاركة على مستوى التطبيق خارج التطبيق.
  8. يمكن أن تكون الزيادة التلقائية خطيرة.
  9. يمكن أن تكون البيانات القديمة مفيدة ولا تحتاج إلى القفل.
  10. التشوهات نموذجية لأي مصادر زمنية.
  11. التأخير له معاني كثيرة.
  12. يجب تقييم متطلبات الأداء لمعاملة معينة.
  13. يمكن أن تكون المعاملات المتداخلة خطيرة.
  14. لا ينبغي أن تكون المعاملات مرتبطة بحالة التطبيق.
  15. يمكن لمخططي الاستعلامات إخبارك بالكثير عن قواعد البيانات.
  16. الهجرة عبر الإنترنت صعبة، ولكنها ممكنة.
  17. الزيادة الكبيرة في قاعدة البيانات تستلزم زيادة في عدم القدرة على التنبؤ.

أود أن أشكر إيمانويل أوديكي ورين هنريكس وآخرين على تعليقاتهم على نسخة سابقة من هذه المقالة.

أنت محظوظ إذا كانت الشبكة لا تسبب مشكلات بنسبة 99,999% من الوقت.

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

مع معدل توفر يبلغ 99,999% لـ Spanner (قاعدة بيانات Google الموزعة عالميًا)، تدعي Google أن فقط 7,6% ترتبط المشاكل بالشبكة. وفي الوقت نفسه، تصف الشركة شبكتها المتخصصة بأنها "الركيزة الأساسية" للتوفر العالي. يذاكر بايليس وكينجسبري، التي أجريت في عام 2014، تتحدى واحدة من "المفاهيم الخاطئة حول الحوسبة الموزعة"، والتي صاغها بيتر دويتش في عام 1994. هل الشبكة موثوقة حقا؟

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

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

ACID يعني الكثير من الأشياء المختلفة

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

عندما دخلت الصناعة لأول مرة، تحدث قائدنا الفني عن مدى أهمية مفهوم ACID. لكي نكون منصفين، يعتبر ACID وصفًا تقريبيًا وليس معيارًا صارمًا للتنفيذ. اليوم أجده مفيدًا في الغالب لأنه يثير فئة معينة من القضايا (ويقترح مجموعة من الحلول الممكنة).

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

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

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

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

كل قاعدة بيانات لها آليات الاتساق والعزل الخاصة بها

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

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

يجب أن يعرف المزيد من المطورين هذا عن قواعد البيانات
مراجعة نماذج التزامن الموجودة والعلاقات بينها

يحدد معيار SQL أربعة مستويات عزل فقط، على الرغم من وجود مستويات أخرى كثيرة من الناحية النظرية والتطبيقية. Jepson.io يقدم نظرة عامة ممتازة على نماذج التزامن الموجودة. على سبيل المثال، يضمن Google Spanner إمكانية التسلسل الخارجي مع مزامنة الساعة، وعلى الرغم من أن هذه طبقة عزل أكثر صرامة، إلا أنها غير محددة في طبقات العزل القياسية.

يذكر معيار SQL مستويات العزل التالية:

  • تسلسل (الأكثر صرامة وتكلفة): التنفيذ القابل للتسلسل له نفس تأثير بعض عمليات تنفيذ المعاملات المتسلسلة. التنفيذ المتسلسل يعني أن كل معاملة لاحقة تبدأ فقط بعد اكتمال المعاملة السابقة. تجدر الإشارة إلى أن المستوى تسلسل غالبًا ما يتم تنفيذه على أنه ما يسمى بعزل اللقطة (على سبيل المثال، في Oracle) نظرًا للاختلافات في التفسير، على الرغم من عدم تمثيل عزل اللقطة نفسه في معيار SQL.
  • القراءات المتكررة: السجلات غير الملتزم بها في المعاملة الحالية متاحة للمعاملة الحالية، ولكن التغييرات التي يتم إجراؤها بواسطة المعاملات الأخرى (مثل الصفوف الجديدة) غير مرئية.
  • قراءة ملتزمة: البيانات غير الملتزم بها غير متاحة للمعاملات. في هذه الحالة، يمكن للمعاملات رؤية البيانات الملتزم بها فقط، وقد تحدث عمليات قراءة وهمية. إذا قامت إحدى المعاملات بإدراج صفوف جديدة وتنفيذها، فستتمكن المعاملة الحالية من رؤيتها عند الاستعلام عنها.
  • قراءة غير ملتزمة (المستوى الأقل صرامة وتكلفة): يُسمح بالقراءات القذرة، ويمكن للمعاملات رؤية التغييرات غير الملتزم بها التي تم إجراؤها بواسطة المعاملات الأخرى. ومن الناحية العملية، قد يكون هذا المستوى مفيدًا للتقديرات التقريبية، مثل الاستعلامات COUNT(*) على الطاولة.

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

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

يجب أن يعرف المزيد من المطورين هذا عن قواعد البيانات
مراجعة حالات شذوذ التزامن عند مستويات عزل مختلفة لأنظمة إدارة قواعد البيانات المختلفة

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

يأتي الحظر المتفائل للإنقاذ عندما يكون من الصعب الحفاظ على الحظر المعتاد.

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

قفل متفائل هي طريقة يتم من خلالها عند قراءة سلسلة ما، أخذ إصدارها أو مجموعها الاختباري أو وقت آخر تعديل بعين الاعتبار. يسمح لك هذا بالتأكد من عدم وجود تغيير في الإصدار الذري قبل تغيير الإدخال:

UPDATE products
SET name = 'Telegraph receiver', version = 2
WHERE id = 1 AND version = 1

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

هناك حالات شاذة أخرى إلى جانب القراءات القذرة وفقدان البيانات

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

أحد الأمثلة على هذه الحالات الشاذة هو تسجيل التشويه (اكتب الانحرافات). من الصعب اكتشاف التشوهات لأنه لا يتم البحث عنها بشكل نشط عادةً. وهي ليست نتيجة لقراءات سيئة أو فقدان البيانات، ولكن بسبب انتهاكات القيود المنطقية المفروضة على البيانات.

على سبيل المثال، لنفكر في تطبيق مراقبة يتطلب أن يكون مشغل واحد تحت الطلب في جميع الأوقات:

BEGIN tx1;                      BEGIN tx2;
SELECT COUNT(*)
FROM operators
WHERE oncall = true;
0                               SELECT COUNT(*)
                                FROM operators
                                WHERE oncall = TRUE;
                                0
UPDATE operators                UPDATE operators
SET oncall = TRUE               SET oncall = TRUE
WHERE userId = 4;               WHERE userId = 2;
COMMIT tx1;                     COMMIT tx2;

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

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

لا تتفق قاعدة البيانات والمستخدم دائمًا على ما يجب فعله

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

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

للوهلة الأولى، في البرنامج أدناه، يتم استدعاء T1 وT2 بشكل تسلسلي، ولكن إذا كانت هذه الوظائف غير محظورة وترجع النتيجة على الفور في النموذج وعد، فسيتم تحديد ترتيب المكالمات حسب اللحظات التي دخلت فيها قاعدة البيانات:

result1 = T1() // النتائج الحقيقية هي الوعود
النتيجة 2 = T2 ()

إذا كانت الذرية مطلوبة (أي أنه يجب إكمال جميع العمليات أو إحباطها) وكان التسلسل مهمًا، فيجب تنفيذ العمليتين T1 وT2 ضمن معاملة واحدة.

يمكن نقل المشاركة على مستوى التطبيق خارج التطبيق

المشاركة هي طريقة لتقسيم قاعدة البيانات أفقيًا. يمكن لبعض قواعد البيانات تقسيم البيانات أفقيًا تلقائيًا، بينما لا تستطيع قواعد البيانات الأخرى القيام بذلك، أو لا تتقنه. عندما يكون مهندسو/مطورو البيانات قادرين على التنبؤ بالضبط بكيفية الوصول إلى البيانات، يمكنهم إنشاء أقسام أفقية في مساحة المستخدم بدلاً من تفويض هذا العمل إلى قاعدة البيانات. تسمى هذه العملية "التقسيم على مستوى التطبيق" (التقسيم على مستوى التطبيق).

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

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

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

يمكن أن تكون الزيادة التلقائية خطيرة

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

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

قبل اتخاذ قرار بشأن أحد الأساليب، ضع في اعتبارك تأثير المعرفات المتزايدة تلقائيًا والمعرفات الفريدة الفريدة (UUID) على الفهرسة والتقسيم والتقسيم.

يمكن أن تكون البيانات القديمة مفيدة ولا تتطلب القفل

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

يمكن أن تكون قراءة البيانات القديمة قليلاً مفيدة، على سبيل المثال، عند إنشاء تحليلات من البيانات أو حساب القيم الإجمالية التقريبية.

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

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

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

أي مصادر زمنية تخضع للتشويه

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

تُستخدم خوادم NTP للمزامنة، لكن عملية المزامنة نفسها تخضع لتأخيرات الشبكة. حتى أن المزامنة مع خادم NTP في نفس مركز البيانات تستغرق بعض الوقت. من الواضح أن العمل مع خادم NTP عام يمكن أن يؤدي إلى تشويه أكبر.

تعتبر الساعات الذرية ونظيراتها من نظام تحديد المواقع العالمي (GPS) أفضل لتحديد الوقت الحالي، ولكنها باهظة الثمن وتتطلب إعدادًا معقدًا، لذلك لا يمكن تثبيتها على كل سيارة. ولهذا السبب، تستخدم مراكز البيانات نهجًا متدرجًا. تُظهر الساعات الذرية و/أو نظام تحديد المواقع العالمي (GPS) الوقت المحدد، وبعد ذلك يتم بثه إلى الأجهزة الأخرى من خلال خوادم ثانوية. وهذا يعني أن كل جهاز سيواجه إزاحة معينة عن الوقت المحدد.

ويتفاقم الوضع بسبب حقيقة أن التطبيقات وقواعد البيانات غالبًا ما تكون موجودة على أجهزة مختلفة (إن لم يكن في مراكز بيانات مختلفة). وبالتالي، فإن الوقت سيختلف ليس فقط على عقد قاعدة البيانات الموزعة عبر أجهزة مختلفة. سيكون الأمر مختلفًا أيضًا على خادم التطبيق.

يتخذ Google TrueTime نهجًا مختلفًا تمامًا. يعتقد معظم الناس أن تقدم Google في هذا الاتجاه يرجع إلى الانتقال المبتذل إلى الساعات الذرية ونظام تحديد المواقع العالمي (GPS)، لكن هذا ليس سوى جزء من الصورة الكبيرة. إليك كيفية عمل TrueTime:

  • يستخدم TrueTime مصدرين مختلفين: GPS والساعات الذرية. تحتوي هذه الساعات على أوضاع فشل غير مرتبطة. [انظر الصفحة 5 للحصول على التفاصيل هنا - تقريبا. ترجمة.)وبالتالي فإن استخدامها المشترك يزيد من الموثوقية.
  • يحتوي TrueTime على واجهة برمجة تطبيقات غير عادية. تقوم بإرجاع الوقت كفاصل زمني به خطأ في القياس وعدم اليقين. اللحظة الفعلية في الوقت المناسب تقع في مكان ما بين الحدود العلوية والسفلية للفاصل الزمني. Spanner، قاعدة بيانات Google الموزعة، تنتظر ببساطة حتى يصبح من الآمن القول بأن الوقت الحالي خارج النطاق. تقدم هذه الطريقة بعض الكمون في النظام، خاصة إذا كان عدم اليقين بشأن العناصر الرئيسية مرتفعًا، ولكنها تضمن الصحة حتى في الموقف الموزع عالميًا.

يجب أن يعرف المزيد من المطورين هذا عن قواعد البيانات
تستخدم مكونات Spanner TrueTime، حيث تقوم TT.now() بإرجاع فاصل زمني، لذلك ينام Spanner ببساطة حتى النقطة التي يمكن أن يكون فيها واثقًا من أن الوقت الحالي قد تجاوز نقطة معينة

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

التأخير له معاني كثيرة

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

يجب تقييم متطلبات الأداء لمعاملة معينة

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

  • اكتب الإنتاجية ووقت الاستجابة عند إدراج صف جديد في الجدول X (مع 50 مليون صف) مع القيود المحددة وحشو الصفوف في الجداول ذات الصلة.
  • التأخير في عرض أصدقاء أصدقاء مستخدم معين عندما يكون متوسط ​​عدد الأصدقاء 500.
  • زمن الوصول في استرداد أفضل 100 إدخال من سجل المستخدم عندما يقوم المستخدم بمتابعة 500 مستخدم آخر مع X إدخالات في الساعة.

قد يتضمن التقييم والتجريب مثل هذه الحالات الحرجة حتى تصبح واثقًا من أن قاعدة البيانات تلبي متطلبات الأداء. هناك قاعدة أساسية مماثلة تأخذ أيضًا هذا التقسيم في الاعتبار عند جمع مقاييس زمن الاستجابة وتحديد محددات مستوى الخدمة (SLO).

كن على دراية بالعلاقة الأساسية العالية عند جمع المقاييس لكل عملية. استخدم السجلات أو مجموعة الأحداث أو التتبع الموزع للحصول على بيانات تصحيح الأخطاء عالية الطاقة. في المقالة "هل تريد تصحيح زمن الاستجابة؟» يمكنك التعرف على منهجيات تصحيح الأخطاء.

يمكن أن تكون المعاملات المتداخلة خطيرة

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

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

يمكن أن يؤدي تغليف المعاملات في طبقات مختلفة إلى معاملات متداخلة غير متوقعة، ومن وجهة نظر إمكانية قراءة التعليمات البرمجية، قد يجعل من الصعب فهم نوايا المؤلف. ألق نظرة على البرنامج التالي:

with newTransaction():
   Accounts.create("609-543-222")
   with newTransaction():
       Accounts.create("775-988-322")
       throw Rollback();

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

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

function newAccount(id string) {
  with newTransaction():
      Accounts.create(id)
}

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

function newAccount(id string) {
   Accounts.create(id)
}
// In main application:
with newTransaction():
   // Read some data from database for configuration.
   // Generate an ID from the ID service.
   Accounts.create(id)
   Uploads.create(id) // create upload queue for the user.

لا ينبغي أن تكون المعاملات مرتبطة بحالة التطبيق

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

var seq int64
with newTransaction():
    newSeq := atomic.Increment(&seq)
    Entries.query(newSeq)
    // Other operations...

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

يمكن لمخططي الاستعلامات إخبارك بالكثير عن قاعدة البيانات

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

SELECT * FROM articles where author = "rakyll" order by title;

ويمكن استرجاع النتائج بطريقتين:

  • مسح الجدول الكامل: يمكنك إلقاء نظرة على كل إدخال في الجدول وإرجاع المقالات التي تحتوي على اسم مؤلف مطابق، ثم ترتيبها.
  • مسح الفهرس: يمكنك استخدام فهرس للعثور على المعرفات المطابقة والحصول على تلك الصفوف ثم ترتيبها.

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

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

الهجرة عبر الإنترنت صعبة ولكنها ممكنة

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

هناك نماذج مختلفة للهجرة عبر الإنترنت. هنا هو واحد:

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

للحصول على معلومات إضافية، أوصي بالاتصال مقالة، والذي يعرض تفاصيل استراتيجية الترحيل الخاصة بـ Stripe بناءً على هذا النموذج.

الزيادة الكبيرة في قاعدة البيانات تستلزم زيادة في عدم القدرة على التنبؤ

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

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

...

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

PS

اقرأ أيضًا على مدونتنا:

المصدر: www.habr.com

إضافة تعليق