سحابة واحدة - نظام تشغيل على مستوى مركز البيانات في Odnoklassniki

سحابة واحدة - نظام تشغيل على مستوى مركز البيانات في Odnoklassniki

الوها أيها الناس! اسمي Oleg Anastasyev، أعمل في Odnoklassniki في فريق المنصة. وبجانبي، هناك الكثير من الأجهزة التي تعمل في Odnoklassniki. لدينا أربعة مراكز بيانات بها حوالي 500 حامل وأكثر من 8 آلاف خادم. عند نقطة معينة، أدركنا أن إدخال نظام إدارة جديد من شأنه أن يسمح لنا بتحميل المعدات بشكل أكثر كفاءة، وتسهيل إدارة الوصول، وأتمتة (إعادة) توزيع موارد الحوسبة، وتسريع إطلاق خدمات جديدة، وتسريع الاستجابات لحوادث واسعة النطاق.

ماذا جاء منه؟

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

سحابة واحدة - نظام تشغيل على مستوى مركز البيانات في Odnoklassniki

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

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

لماذا هذا؟ وكان لهذا النهج العديد من المزايا:

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

يتم تخصيص عدة خوادم للخدمة التي تتكون من عدة نسخ متماثلة - خادم لكل منها. ثم يتم تخصيص مورد الحوسبة للخدمة بكل بساطة: عدد الخوادم التي تمتلكها الخدمة، والحد الأقصى لمقدار الموارد التي يمكن أن تستهلكها. ""سهل"" هنا لا يعني أنه سهل الاستخدام، ولكن بمعنى أن تخصيص الموارد يتم يدويًا.

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

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

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

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

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

سحابة واحدة - نظام تشغيل على مستوى مركز البيانات في Odnoklassniki

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

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

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

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

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

لا يعد توزيع الحاويات يدويًا خيارًا عندما يكون لديك 8 آلاف خادم و8-16 ألف حاوية.

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

من الواضح أننا بحاجة إلى طبقة تحكم تقوم بذلك تلقائيًا.

لذلك وصلنا إلى صورة بسيطة ومفهومة يعشقها جميع المهندسين المعماريين: ثلاثة مربعات.

سحابة واحدة - نظام تشغيل على مستوى مركز البيانات في Odnoklassniki

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

تخصيص الموارد

الآن دعونا نلقي نظرة على مشكلة تخصيص الموارد الأكثر تعقيدًا للعديد من التوابع.

مورد الحوسبة في السحابة الواحدة هو:

  • مقدار طاقة المعالج التي تستهلكها مهمة محددة.
  • مقدار الذاكرة المتوفرة لهذه المهمة.
  • ازدحام انترنت. يتمتع كل من التوابع بواجهة شبكة محددة ذات نطاق ترددي محدود، لذلك من المستحيل توزيع المهام دون مراعاة كمية البيانات التي ينقلونها عبر الشبكة.
  • الأقراص. بالإضافة إلى ذلك، من الواضح أنه بالنسبة للمساحة المخصصة لهذه المهام، فإننا نخصص أيضًا نوع القرص: HDD أو SSD. يمكن للأقراص أن تخدم عددًا محدودًا من الطلبات في الثانية - IOPS. لذلك، بالنسبة للمهام التي تولد عمليات IOPS أكثر مما يمكن لقرص واحد التعامل معه، فإننا نخصص أيضًا "المغازل" - أي أجهزة القرص التي يجب حجزها حصريًا للمهمة.

ثم بالنسبة لبعض الخدمات، على سبيل المثال، ذاكرة التخزين المؤقت للمستخدم، يمكننا تسجيل الموارد المستهلكة بهذه الطريقة: 400 نواة معالج، 2,5 تيرابايت من الذاكرة، 50 جيجابت/ثانية من حركة المرور في كلا الاتجاهين، 6 تيرابايت من مساحة محرك الأقراص الثابتة الموجودة على 100 مغزل. أو في شكل أكثر دراية مثل هذا:

alloc:
    cpu: 400
    mem: 2500
    lan_in: 50g
    lan_out: 50g
    hdd:100x6T

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

دعنا نعود إلى مخططنا المبسط إلى حد كبير لتفاعل المكونات ونعيد رسمه بمزيد من التفاصيل - مثل هذا:

سحابة واحدة - نظام تشغيل على مستوى مركز البيانات في Odnoklassniki

ما يلفت الأنظار:

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

لنعيد رسم الصورة مرة أخرى:

سحابة واحدة - نظام تشغيل على مستوى مركز البيانات في Odnoklassniki

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

من خلال إزالة الخطوط الإضافية، يمكننا كتابة كل عقدة من صورتنا في شكل مسطح: group1.web.front, api.music.front, user-cache.cache.

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

دعونا نلقي نظرة فاحصة على الخدمات. تحتوي الخدمة على اسم مؤهل بالكامل، والذي يتضمن دائمًا اسم قائمة الانتظار. ثم سيكون لخدمة الويب الأمامية الاسم موافق-web.group1.web.front. وسيتم استدعاء خدمة خادم التطبيقات التي يصل إليها ok-app.group1.web.front. تحتوي كل خدمة على بيان يحدد جميع المعلومات اللازمة لوضعها على أجهزة معينة: عدد الموارد التي تستهلكها هذه المهمة، والتكوين المطلوب لها، وعدد النسخ المتماثلة التي يجب أن تكون موجودة، وخصائص التعامل مع فشل هذه الخدمة. وبعد وضع الخدمة مباشرة على الأجهزة تظهر مثيلاتها. يتم تسميتها أيضًا بشكل لا لبس فيه - كرقم المثيل واسم الخدمة: 1.ok-web.group1.web.front، 2.ok-web.group1.web.front، ...

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

الآن دعونا نلقي نظرة فاحصة على ما تؤديه هذه الحالات فعليًا: المهام.

فئات عزل المهام

يمكن تقسيم جميع المهام في "موافق" (وربما في كل مكان) إلى مجموعات:

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

دعونا نرى كيف تستهلك هذه المهام الموارد، على سبيل المثال، المعالج المركزي.

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

سحابة واحدة - نظام تشغيل على مستوى مركز البيانات في Odnoklassniki

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

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

alloc: cpu = 4 (max)

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

المهام الحسابية. سيكون نمطهم مختلفًا قليلاً:

سحابة واحدة - نظام تشغيل على مستوى مركز البيانات في Odnoklassniki

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

alloc: cpu = [1,*)

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

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

سحابة واحدة - نظام تشغيل على مستوى مركز البيانات في Odnoklassniki

ولكن كيف نفعل ذلك؟

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

  • باستخدام الخيار --cpuset=1-4، أي تخصيص أربعة مراكز محددة على الجهاز لهذه المهمة.
  • استخدم --cpuquota=400_000 --cpuperiod=100_000، قم بتعيين حصة لوقت المعالج، أي الإشارة إلى أن كل 100 مللي ثانية من الوقت الفعلي، لا تستهلك المهمة أكثر من 400 مللي ثانية من وقت المعالج. يتم الحصول على نفس النوى الأربعة.

ولكن أي من هذه الطرق مناسبة؟

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

دعونا نتعرف على كيفية إجراء الحجز في Docker بناءً على الحد الأدنى لعدد النوى. لم تعد الحصة النسبية للمهام المجمعة قابلة للتطبيق، لأنه ليست هناك حاجة لتحديد الحد الأقصى، يكفي ضمان الحد الأدنى فقط. وهنا الخيار يناسب بشكل جيد docker run --cpushares.

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

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

  • SCHED_OTHER
    بشكل افتراضي، يتم تلقي كافة عمليات المستخدم العادية على جهاز Linux.
  • SCHED_BATCH
    مصممة للعمليات كثيفة الاستخدام للموارد. عند وضع مهمة على المعالج، يتم فرض ما يسمى بعقوبة التنشيط: تقل احتمالية حصول هذه المهمة على موارد المعالج إذا كانت قيد الاستخدام حاليًا بواسطة مهمة ذات SCHED_OTHER
  • SCHED_IDLE
    عملية خلفية ذات أولوية منخفضة للغاية، حتى أقل من لطيفة -19. نحن نستخدم مكتبتنا مفتوحة المصدر واحد نيولتعيين السياسة اللازمة عند بدء تشغيل الحاوية عن طريق الاتصال

one.nio.os.Proc.sched_setscheduler( pid, Proc.SCHED_IDLE )

ولكن حتى لو لم تكن تبرمج بلغة Java، فيمكن القيام بنفس الشيء باستخدام الأمر chrt:

chrt -i 0 $pid

دعونا نلخص جميع مستويات العزل لدينا في جدول واحد من أجل الوضوح:

فئة العزل
تخصيص المثال
خيارات تشغيل عامل الميناء
sched_setscheduler crt*

همز
وحدة المعالجة المركزية = 4
--cpuquota=400000 --cpuperiod=100000
SCHED_OTHER

دفعة
وحدة المعالجة المركزية = [1، *)
--cpushares=1024
SCHED_BATCH

الخمول
وحدة المعالجة المركزية = [2، *)
--cpushares=2048
SCHED_IDLE

*إذا كنت تقوم بإجراء chrt من داخل حاوية، فقد تحتاج إلى إمكانية sys_nice، لأن Docker يقوم افتراضيًا بإزالة هذه الإمكانية عند بدء تشغيل الحاوية.

لكن المهام لا تستهلك المعالج فحسب، بل تستهلك أيضًا حركة المرور، مما يؤثر على زمن الوصول لمهمة الشبكة أكثر من التخصيص غير الصحيح لموارد المعالج. لذلك، نريد بطبيعة الحال الحصول على نفس الصورة تمامًا لحركة المرور. أي أنه عندما تقوم مهمة إنتاجية بإرسال بعض الحزم إلى الشبكة، فإننا نحد من السرعة القصوى (الصيغة تخصيص: الشبكة المحلية = [*، 500 ميغابت في الثانية) )، مع أي منتج يمكنه القيام بذلك. وبالنسبة للدفعة، فإننا نضمن فقط الحد الأدنى من الإنتاجية، ولكن لا نحد من الحد الأقصى (الصيغة التخصيص: الشبكة المحلية=[10 ميجابت في الثانية،*) ) في هذه الحالة، يجب أن تحظى حركة مرور المنتج بالأولوية على المهام المجمعة.
هنا لا يحتوي Docker على أي عناصر أولية يمكننا استخدامها. لكنه يأتي لمساعدتنا التحكم في حركة المرور لينكس. تمكنا من تحقيق النتيجة المرجوة بمساعدة الانضباط منحنى الخدمة العادلة الهرمي. وبمساعدتها، نميز بين فئتين من حركة المرور: الإنتاج ذو الأولوية العالية والدفعة/الخاملة ذات الأولوية المنخفضة. ونتيجة لذلك، يكون تكوين حركة المرور الصادرة كما يلي:

سحابة واحدة - نظام تشغيل على مستوى مركز البيانات في Odnoklassniki

هنا 1:0 هو "القرص الجذري" لنظام hsfc؛ 1:1 - فئة فرعية hsfc بحد إجمالي لعرض النطاق يبلغ 8 جيجابت/ثانية، والتي توضع تحتها الفئات الفرعية لجميع الحاويات؛ 1:2 - تعتبر الفئة الفرعية hsfc شائعة في جميع المهام المجمعة والمهام الخاملة ذات الحد "الديناميكي"، الذي سيتم مناقشته أدناه. فئات hsfc الفرعية المتبقية هي فئات مخصصة لحاويات الإنتاج التي يتم تشغيلها حاليًا بحدود تتوافق مع بياناتها - 450 و400 ميجابت/ثانية. يتم تعيين قائمة انتظار qdisc fq أو fq_codel لكل فئة hsfc، اعتمادًا على إصدار Linux kernel، لتجنب فقدان الحزمة أثناء انفجارات حركة المرور.

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

سحابة واحدة - نظام تشغيل على مستوى مركز البيانات في Odnoklassniki

أثناء التجارب، اكتشفنا أن hsfc يُظهر أفضل النتائج عندما تكون فئة 1:2 من حركة المرور المجمعة/الخاملة غير ذات الأولوية محدودة على الأجهزة التابعة بما لا يزيد عن مسار مجاني معين. وبخلاف ذلك، فإن حركة المرور غير ذات الأولوية لها تأثير كبير جدًا على زمن انتقال مهام الإنتاج. يحدد miniond المقدار الحالي من النطاق الترددي المجاني كل ثانية، ويقيس متوسط ​​استهلاك حركة المرور لجميع المهام الخاصة بتابع معين سحابة واحدة - نظام تشغيل على مستوى مركز البيانات في Odnoklassniki وطرحه من عرض النطاق الترددي لواجهة الشبكة سحابة واحدة - نظام تشغيل على مستوى مركز البيانات في Odnoklassniki بهامش صغير، أي.

سحابة واحدة - نظام تشغيل على مستوى مركز البيانات في Odnoklassniki

يتم تعريف النطاقات بشكل مستقل لحركة المرور الواردة والصادرة. ووفقًا للقيم الجديدة، يقوم العميل بإعادة تكوين حد الفئة غير ذات الأولوية 1:2.

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

سحابة واحدة - نظام تشغيل على مستوى مركز البيانات في Odnoklassniki

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

مع إزالة الأسطر الإضافية مرة أخرى، يمكننا كتابة أسماء خدماتنا بشكل مسطح عن طريق إضافة فئة عزل المهام إلى نهاية اسم الخدمة الكامل: web.front.prod, catalog.music.batch, converter.music.idle.

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

كل شيء على ما يرام، ولكن هناك حقيقة واحدة مريرة. من المستحيل عزل المهام التي تعمل على جهاز واحد بشكل كامل.

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

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

بالإضافة إلى ذلك، لم نتمكن حتى الآن إلا من حل مشكلة تحديد أولويات حركة مرور TCP: لا يعمل نهج hsfc مع UDP. وحتى في حالة حركة مرور TCP، إذا كانت المهمة الدفعية تولد الكثير من حركة المرور، فإن هذا يوفر أيضًا زيادة بنسبة 10% تقريبًا في تأخير مهمة المنتج.

التسامح مع الخطأ

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

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

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

ماذا يمكنك أن تفعل إذا كان العميل بأكمله غير متاح؟

من الواضح، تشغيل الحاوية على جهاز آخر. الجزء المثير للاهتمام هنا هو ما يحدث لعنوان (عناوين) IP المخصصة للحاوية.

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

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

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

في السحابة الواحدة، يتبع عنوان IP الحاوية، أي أن كل مثيل مهمة له عنوان IP خاص به. هذا العنوان "ثابت": يتم تعيينه لكل مثيل عند إرسال الخدمة لأول مرة إلى السحابة. إذا كان لدى الخدمة عدد مختلف من المثيلات خلال عمرها الافتراضي، فسيتم في النهاية تخصيص عدد من عناوين IP يساوي الحد الأقصى للمثيلات.

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

وبالتالي، نادرًا ما يتغير تعيين اسم الخدمة لقائمة عناوين IP الخاصة به. إذا نظرت مرة أخرى إلى أسماء مثيلات الخدمة التي ذكرناها في بداية المقال (1.ok-web.group1.web.front.prod، 2.ok-web.group1.web.front.prod، ...)، سنلاحظ أنها تشبه FQDNs المستخدمة في DNS. هذا صحيح، لتعيين أسماء مثيلات الخدمة لعناوين IP الخاصة بها، نستخدم بروتوكول DNS. علاوة على ذلك، يقوم DNS هذا بإرجاع جميع عناوين IP المحجوزة لجميع الحاويات - سواء كانت قيد التشغيل أو متوقفة (لنفترض أنه تم استخدام ثلاث نسخ متماثلة، ولدينا خمسة عناوين محجوزة هناك - سيتم إرجاع الخمسة جميعًا). سيحاول العملاء، بعد تلقي هذه المعلومات، إنشاء اتصال بجميع النسخ المتماثلة الخمس - وبالتالي تحديد تلك التي تعمل. يعد هذا الخيار لتحديد مدى التوفر أكثر موثوقية؛ فهو لا يتضمن DNS أو اكتشاف الخدمة، مما يعني عدم وجود مشكلات صعبة لحلها في ضمان ملاءمة المعلومات والتسامح مع الأخطاء في هذه الأنظمة. علاوة على ذلك، في الخدمات الهامة التي يعتمد عليها تشغيل البوابة بأكملها، لا يمكننا استخدام DNS على الإطلاق، ولكن ببساطة أدخل عناوين IP في التكوين.

يمكن أن يكون تنفيذ نقل IP خلف الحاويات أمرًا بسيطًا - وسننظر في كيفية عمله من خلال المثال التالي:

سحابة واحدة - نظام تشغيل على مستوى مركز البيانات في Odnoklassniki

لنفترض أن سيد السحابة الواحدة يعطي الأمر للعميل M1 للتشغيل 1.ok-web.group1.web.front.prod مع العنوان 1.1.1.1. يعمل على العميل طائر، والتي تعلن عن هذا العنوان لخوادم خاصة عاكس الطريق. لدى الأخير جلسة BGP مع جهاز الشبكة، حيث يتم ترجمة مسار العنوان 1.1.1.1 على M1. يقوم M1 بتوجيه الحزم داخل الحاوية باستخدام Linux. توجد ثلاثة خوادم عاكسة للمسار، نظرًا لأن هذا جزء بالغ الأهمية من البنية التحتية للسحابة الواحدة - وبدونها، لن تعمل الشبكة في السحابة الواحدة. ونضعها في رفوف مختلفة، إذا أمكن، في غرف مختلفة بمركز البيانات، لتقليل احتمالية فشل الثلاثة جميعًا في نفس الوقت.

لنفترض الآن أن الاتصال بين السحابة الرئيسية والتابع M1 مفقود. سيتصرف الآن سيد السحابة الواحدة على افتراض أن M1 قد فشل تمامًا. أي أنه سيعطي الأمر للعميل M2 للإطلاق web.group1.web.front.prod بنفس العنوان 1.1.1.1. الآن لدينا طريقان متعارضان على الشبكة لـ 1.1.1.1: على M1 وعلى M2. من أجل حل مثل هذه التعارضات، نستخدم Multi Exit Discriminator، المحدد في إعلان BGP. هذا رقم يوضح وزن المسار المعلن عنه. من بين المسارات المتعارضة، سيتم اختيار المسار ذو قيمة MED الأقل. تدعم السحابة الرئيسية MED كجزء لا يتجزأ من عناوين IP للحاوية. لأول مرة، يتم كتابة العنوان بـ MED كبير بما فيه الكفاية = 1. في حالة النقل الطارئ للحاويات، يقوم السيد بتقليل MED، وسيتلقى M000 بالفعل الأمر للإعلان عن العنوان 000 بـ MED = 2 سيبقى المثيل الذي يعمل على M1.1.1.1 في هذه الحالة لا يوجد اتصال، ومصيره الإضافي لا يهمنا كثيرًا حتى يتم استعادة الاتصال بالسيد، عندما يتم إيقافه مثل لقطة قديمة.

حوادث

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

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

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

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

ماذا يمكنك أن تفعل حيال كل هذا؟

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

دعونا نلقي نظرة مرة أخرى على التسلسل الهرمي للخدمات التي نعرفها ونحاول تحديد المهام التي نريد تشغيلها أولاً.

سحابة واحدة - نظام تشغيل على مستوى مركز البيانات في Odnoklassniki

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

في المنتج نقوم بتعيين أولويات أعلى، 0؛ على دفعة - أقل قليلا، 100؛ في وضع الخمول - أقل من ذلك، 200. ويتم تطبيق الأولويات بشكل هرمي. جميع المهام الأدنى في التسلسل الهرمي سيكون لها الأولوية المقابلة. إذا أردنا تشغيل ذاكرة التخزين المؤقت داخل المنتج قبل الواجهات الأمامية، فإننا نقوم بتعيين أولويات لذاكرة التخزين المؤقت = 0 ولقوائم الانتظار الفرعية الأمامية = 1. إذا أردنا، على سبيل المثال، تشغيل البوابة الرئيسية من الواجهات أولاً، وواجهة الموسيقى فقط وبعد ذلك، يمكننا إعطاء أولوية أقل للأخيرة - 10.

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

سحابة واحدة - نظام تشغيل على مستوى مركز البيانات في Odnoklassniki

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

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

حوادث العاصمة بأكملها

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

وهذا ما نفعله لمنع أي شخص من التغريد #حيا.

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

لا يحمي هذا الأسلوب من الفشل المادي فحسب، بل يمكنه أيضًا الحماية من أخطاء المشغل.

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

سحابة واحدة - نظام تشغيل على مستوى مركز البيانات في Odnoklassniki

نتائج

السمات المميزة للسحابة الواحدة:

  • نظام التسمية الهرمي والمرئي للخدمات والحاويات، والذي يسمح لك بمعرفة المهمة بسرعة كبيرة وما تتعلق بها وكيف تعمل ومن المسؤول عنها.
  • نحن نطبق لدينا تقنية الجمع بين المنتج والدفعةالمهام على التوابع لتحسين كفاءة تقاسم الجهاز. بدلاً من cpuset، نستخدم حصص وحدة المعالجة المركزية والمشاركات وسياسات جدولة وحدة المعالجة المركزية وجودة خدمة Linux.
  • لم يكن من الممكن عزل الحاويات التي تعمل على نفس الآلة بشكل كامل، لكن تأثيرها المتبادل يبقى في حدود 20%.
  • يساعد تنظيم الخدمات في تسلسل هرمي في التعافي التلقائي من الكوارث باستخدام أولويات التنسيب والاستباق.

التعليمات

لماذا لم نأخذ الحل الجاهز؟

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

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

لأولئك الذين قرأوا السطور الأخيرة، أشكركم على صبركم واهتمامكم!

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

إضافة تعليق