أول اطلالة له على AppleD Foundation

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

FoundationDB هي قاعدة بيانات موزعة على NoSQL مع معاملات ACID التسلسلية التي تخزن أزواج تخزين القيمة الرئيسية المصنفة. يمكن أن تكون المفاتيح والقيم متسلسلة تعسفية للبايت. ليس لديها نقطة واحدة من حالات الإصابة - جميع آلات الكتلة متساوية. تقوم هي نفسها بتوزيع البيانات بين خوادم الكتلة والمقاييس السريعة: عندما تحتاج إلى إضافة موارد إلى الكتلة ، يمكنك ببساطة إضافة عنوان الجهاز الجديد على خوادم التكوين وقاعدة البيانات تلتقطها بنفسها.

في FoundationDB ، لا تمنع المعاملات بعضها البعض. يتم تنفيذ القراءة من خلال التحكم في إصدار التحويلات المتعددة (MVCC) ، ويتم تنفيذ القراءة من خلال التحكم في التزامن المتفائل (OCC). يدعي المطورون أنه عندما تكون جميع الأجهزة الموجودة في الكتلة في مركز البيانات نفسه ، يكون زمن انتقال الكتابة 2-3 مللي ثانية ، ويكون زمن قراءة القراءة أقل من مللي ثانية. تحتوي الوثائق على تقديرات تتراوح من 10 إلى 15 مللي ثانية ، والتي ربما تكون أقرب إلى النتائج في الظروف الحقيقية.

* لا يدعم خصائص ACID على شظايا متعددة.

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

العمارة


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



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

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



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

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

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

طلب المعالجة


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

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



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

التحجيم


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

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

لنفترض أنك حفظت غيغابايت من البيانات في معاملة. كيف يمكنك تقديم استجابة سريعة؟ بأي حال من الأحوال ، وبالتالي ، يقتصر FoundationDB حجم معاملة واحدة إلى 10 ميغابايت. علاوة على ذلك ، يعد هذا قيدًا على جميع البيانات التي تتعلق بالمعاملة - القراءة أو الكتابة. يقتصر أيضًا كل إدخال في قاعدة البيانات - لا يمكن أن يتجاوز المفتاح 10 كيلو بايت ، والقيمة هي 100 كيلو بايت. (في الوقت نفسه ، للحصول على أفضل أداء ، يوصي المطورون بالمفاتيح بطول 32 بايت وقيم بطول 10 كيلو بايت.)

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

المؤشرات


لنفترض أنك تحتفظ بقائمة من الأشخاص ، ولكل شخص معرف فريد ، ونستخدمه كمفتاح ، وفي القيمة نكتب جميع السمات الأخرى - الاسم ، والجنس ، والعمر ، إلخ.
مفتاحالقيمة
12345(إيفانوف إيفانوفيتش ، م ، 35)

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

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

من المهم أن تتم عمليات إضافة السجل نفسه والفهرس إليه في معاملة واحدة.

الموثوقية


FoundationDB مكتوب بلغة C ++. بدأ المؤلفون العمل عليها في عام 2009 ، تم إصدار النسخة الأولى في عام 2013 ، وفي مارس 2015 ، اشترتها شركة Apple. بعد ثلاث سنوات ، فتحت آبل بشكل غير متوقع شفرة المصدر. تقول الشائعات أن Apple تستخدمها ، من بين أشياء أخرى ، لتخزين بيانات خدمة iCloud.

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

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

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

لذلك يوفر FoundationDB معاملات ACID وأعلى مستوى من العزلة ، Serializable ، على مجموعة من الآلاف من الآلات. جنبا إلى جنب مع مرونة مذهلة والأداء العالي ، يبدو وكأنه السحر. ولكن عليك أن تدفع ثمن كل شيء ، لذلك هناك بعض القيود التكنولوجية.

القيود


بالإضافة إلى القيود المذكورة بالفعل على حجم وطول الصفقة ، من المهم ملاحظة الميزات التالية:

  • لغة الاستعلام ليست لغة SQL ، أي أن المطورين الذين يتمتعون بخبرة SQL سيتعين عليهم إعادة التعلم.
  • لا تدعم مكتبة العميل سوى 5 لغات عالية المستوى (Phyton و Ruby و Java و Golang و C). لا يوجد عميل رسمي لـ C # حتى الآن. نظرًا لعدم وجود REST API ، فإن الطريقة الوحيدة لدعم لغة أخرى هي كتابة برنامج تعليمي عليها أعلى مكتبة C القياسية.
  • لا توجد آليات مشاركة ، يجب تقديم كل هذا المنطق من خلال التطبيق الخاص بك.
  • تنسيق تخزين البيانات غير موثق (على الرغم من أنه عادة لا يتم توثيقه في قواعد البيانات التجارية أيضًا). هذا خطر ، لأنه إذا لم يتم تجميع المجموعة فجأة ، فمن غير الواضح على الفور ما يجب القيام به وسوف تضطر إلى الخوض في الملفات المصدر.
  • قد يبدو نموذج البرمجة غير المتزامن تمامًا معقدًا للمطورين المبتدئين.
  • أنت بحاجة إلى التفكير باستمرار حول قلة المعاملات.
  • إذا كان عليك تقسيم المعاملات الطويلة إلى معاملات صغيرة ، فأنت بحاجة إلى العناية بنزاهة على المستوى العالمي بنفسك.

تُرجم كلمة "Foundation" إلى اللغة الإنجليزية ، وتعني كلمة "Foundation" ، ويرى مؤلفو DBMS دورها بهذه الطريقة: توفير مستوى عالٍ من الموثوقية على مستوى السجلات البسيطة ، ويمكن تنفيذ أي قاعدة بيانات أخرى كإضافة على الوظيفة الأساسية. وبالتالي ، على رأس FoundationDB ، يمكنك إنشاء طبقات أخرى مختلفة - المستندات ، الرسوم البيانية ، إلخ. يبقى السؤال كيف ستتدرج هذه الطبقات دون فقدان الأداء. على سبيل المثال ، اتخذ مؤلفو CockroachDB هذا المسار بالفعل - من خلال بناء طبقة SQL أعلى RocksDB (متجر قيمة المفتاح المحلي) والحصول على مشاكل الأداء الملازمة للوصلة العلائقية.

حتى الآن ، قامت Apple بتطوير ونشر طبقتين على أعلى FoundationDB: Document Layer (يدعم MongoDB API) و Record Layer (تقوم بتخزين السجلات كمجموعات حقول بتنسيق Protocol Buffers ، تدعم الفهارس ، وهي متوفرة فقط في Java). إنه لمن دواعي السرور والمفاجأة أن شركة آبل التي أغلقت تاريخياً اليوم تتبع خطى جوجل ومايكروسوفت وتنشر الكود المصدري للتقنيات المستخدمة في الداخل.

آفاق


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

قبل عام ، كنا متفائلين بشأن تقنية أخرى - CockroachDB ، لكنها لم تلب توقعاتنا للأداء. منذ ذلك الحين ، فقدنا شهيتنا لفكرة طبقة SQL على مخزن القيمة الرئيسية الموزعة ، وبالتالي لم ننظر بعناية ، على سبيل المثال ، TiDB . نحن نخطط لتجربة FoundationDB بعناية كقاعدة بيانات ثانوية لأكبر مجموعات البيانات في مشروعنا. إذا كان لديك بالفعل خبرة في الاستخدام الفعلي لـ FoundationDB أو TiDB في الإنتاج ، فسيسعدنا أن نسمع رأيك في التعليقات.

Source: https://habr.com/ru/post/ar441270/


All Articles