5 طرق لنشر كود PHP في ظروف الحمل الزائد

إذا تم تدريس الطريق السريع في المدرسة ، فإن الكتاب المدرسي حول هذا الموضوع سيكون له هذه المهمة. "تحتوي الشبكة الاجتماعية N على 2000 خادم ، يوجد بها 150.000 ملف بسعة 900 ميجابايت لكل رمز PHP ومجموعة نظام تشغيل لـ 50 جهازًا. يتم نشر الكود على الخوادم مرتين في اليوم ، على الكتلة المؤقتة يتم تحديث الكود كل بضع دقائق ، وهناك "إصلاحات عاجلة" إضافية - مجموعات صغيرة من الملفات التي تم إيقاف تشغيلها بالكامل أو على الجزء المحدد من الخوادم ، دون انتظار الحساب الكامل. السؤال: هل تعتبر مثل هذه الظروف عبئا كبيرا وكيفية نشرها؟ اكتب 5 خيارات نشر على الأقل. " لا يسعنا إلا أن نحلم بكتاب مشكلة الحمولة ، لكن الآن نعرف الآن أن يوري ناسريتدينوف ( youROCK ) سيحل هذه المشكلة بالتأكيد وسيحصل على "الخمسة".


لم يتوقف يوري عن حل بسيط ، لكنه قدم تقريراً كشف فيه عن مفهوم "نشر الكود" ، وتحدث عن الحلول الكلاسيكية والبديلة لنشر PHP على نطاق واسع ، وتحليل أدائها وعرض نظام نشر MDK.

مفهوم "نشر الكود"


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

تتكون عملية النشر عادة من عدة مراحل.

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

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

نظام النشر القديم في Badoo


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

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



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

الحلول القائمة الأخرى


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



لقد قسمت تقليديًا طرق نشر كود PHP إلى 4 فئات.

  • بناءً على نظام التحكم في الإصدار : svn up ، git pull ، hg up.
  • بناءً على أداة rsync - إلى دليل جديد أو "في المقدمة".
  • نشر ملف واحد - بغض النظر عن: phar ، hhbc ، حلقة.
  • الطريقة الخاصة التي اقترحها Rasmus Lerdorf هي rsync و 2 من الدلائل و realpath_root .

كل أسلوب له إيجابيات وسلبيات على حد سواء ، والتي تخلينا عنها. النظر في هذه الأساليب 4 بمزيد من التفصيل.

نشر يعتمد على نظام التحكم في إصدار svn


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

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

نشر على أساس rsync فائدة


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

rsync إلى دليل جديد


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

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



رسينك على القمة


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

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

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

نشر ملف واحد


مهما كان الملف الفردي الذي تحمّله ، فمن السهل نسبيًا استخدام BitTorrent أو الأداة المساعدة UFTP. من السهل فك ملف واحد ، ويمكن استبداله تلقائيًا على Unix ، ومن السهل التحقق من سلامة الملف الذي تم إنشاؤه على خادم الإنشاء وتسليمه إلى الأجهزة المستهدفة عن طريق حساب كميات MD5 أو SHA-1 من الملف (في حالة rsync ، لا تعرف ما هو موجود على الخوادم الوجهة ).

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

الانحدار الغنائي حول UFTP


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

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

خيارات نشر ملف واحد


tar.gz

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

PHAR

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

hhbc

هذه الطريقة هي موطن HHVM - HipHop Virtual Machine وتستخدم بواسطة Facebook. هذا شيء يشبه أرشيف phar ، ولكنه لا يحتوي على رموز المصدر ، ولكنه يحتوي على شفرة بايت مجمعة للجهاز الظاهري HHVM - مترجم PHP من Facebook. يحظر تغيير أي شيء في هذا الملف: لا يمكنك إنشاء فئات ووظائف جديدة ، ويتم تعطيل بعض الميزات الديناميكية الأخرى في هذا الوضع. بسبب هذه القيود ، يمكن للجهاز الظاهري استخدام تحسينات إضافية. وفقًا لموقع Facebook ، يمكن أن يصل هذا إلى 30٪ من سرعة تنفيذ التعليمات البرمجية. ربما هذا هو خيار جيد بالنسبة لهم. من المستحيل أيضًا تغيير ملف واحد هنا ( Yuri من المستقبل: في الواقع كان ذلك ممكنًا ، لأنه قاعدة sqlite ). إذا كنت تريد تغيير سطر واحد ، فأنت بحاجة إلى إعادة الأرشفة بأكملها مرة أخرى.

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

أنشوطة

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

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

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

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

مشاكل مع عامل ميناء


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

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

لقد حاولنا القيام بأشياء غريبة ، على سبيل المثال ، لرفع خادم NFS محلي أو تحميل دليل باستخدام SSHFS ، لكن لسبب ما لم يتجذر هذا معنا. نتيجة لذلك ، في cron ، سجلنا rsync من "الحلقة" الأخيرة في الدليل الحالي ، وتم تشغيل الأمر مرة واحدة في الدقيقة:
rsync /var/loop/<N>/ /var/www/ 

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

رسينك ، 2 الدلائل و realpath_root


تم اقتراح هذه الطريقة من قبل Rasmus Lerdorf ، مؤلف PHP ، وهو يعرف كيفية النشر.

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



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

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



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

على غرار راسموس


يقترح Rasmus بدلاً من تعديل الشفرة يدويًا وإنشاء ثوابت لتعديل Apache قليلاً أو استخدام nginx.



بالنسبة إلى document_root ، حدد الارتباط إلى أحدث إصدار. إذا كان لديك nginx ، فيمكنك تسجيل root $realpath_root ، لأن Apache ستحتاج إلى وحدة منفصلة بها الإعدادات التي يمكن رؤيتها على الشريحة. يعمل مثل هذا - عندما يصل طلب ما ، يعتبر nginx أو Apache مرة واحدة من حين لآخر realpath () من المسار ، ويحفظه من الارتباطات ، ويمرر هذا المسار كـ document_root. في هذه الحالة ، ستشير document_root دائمًا إلى دليل منتظم بدون روابط ، وقد لا يضطر رمز PHP إلى التفكير في أي دليل يتم استدعاؤه منه.

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

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

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

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

إذا كنت تستخدم Apache لسبب ما ، فأنت بحاجة إلى وحدة نمطية تابعة لجهة خارجية كتبها Rasmus أيضًا.

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

النظام الجديد - MDK


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

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

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

الحلول الممكنة:

  • loop xN (-staging، -ocker، -opcache)؛
  • rsync xN (-الإنتاج ، -opcache xN) ؛
  • SVN xN (- إنتاج ، xpcache).

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

لذلك ، توصلنا إلى نظام جديد أطلق عليه MDK. وهي تقف مع Multiversion Deployment Kit ، وهي أداة نشر متعددة الإصدارات. لقد فعلنا ذلك بناءً على الافتراضات التالية.

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

إعادة تسمية جميع الملفات من file.php إلى file.php. <version>. نظرًا لأن كل الملفات التي تم تخزينها لدينا بسيطة على القرص ، فإذا أردنا تخزين عدة إصدارات من نفس الملف ، فيجب علينا إضافة لاحقة مع الإصدار.

أنا أحب الذهاب ، لذلك لسرعة كتبت نظام على الذهاب.

كيف تعمل مجموعة أدوات النشر المتعددة


أخذنا فكرة لقطات من بوابة. لقد قمت بتبسيطها قليلاً وأخبرك عن كيفية تنفيذها في MDK.

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



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



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

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

كيف تكمن MDK على القرص




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

أتوقع السؤال: " وكيف يمكن لهذه العملية طلب الويب؟ ما الملفات التي سيأتي إليها رمز المستخدم؟ "

نعم ، لقد خدعتك - هناك أيضًا ملفات بدون إصدارات ، لأنه إذا تلقيت طلبًا للحصول على index.php ، ولم يكن لديك في الدليل ، فلن يعمل الموقع.



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

 <?php require_once "mdk.inc"; require mdk_resolve_path("a.php"); 

يتم ذلك ، وليس مرتبطًا بأحدث إصدار ، لأنه إذا استبعدت b.php من ملف a.php بدون إصدار ، فمنذ أن يتم كتابة require_once ، سيتذكر النظام بطاقة الجذر التي بدأ منها ، وسيستخدمها ، و الحصول على نسخة ثابتة من الملفات.

بالنسبة لبقية الملفات ، لدينا فقط رابط إلى أحدث إصدار.

كيفية النشر باستخدام MDK


هذا النموذج يشبه إلى حد كبير دفع جيت.

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

مثال


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



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



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



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

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

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

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

بالنسبة لي ، بالإضافة إلى حقيقة أن MDK مكتوب في Go يعني أنه يعمل بسرعة.

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

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

MDK بالأرقام


لدينا 50 خادمًا على مراحل ، وننشر عليها من 3 إلى 5 ثوانٍ . مقارنة بكل شيء ما عدا rsync ، فهو سريع جدًا. في الإنتاج ، نقوم بنشر حوالي دقيقتين ، بقع صغيرة - 5-10 ثوان .

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

النظام ليس في المصدر المفتوح ، ولكن إذا كنت مهتمًا ، فاكتب في التعليقات - قد يتم طرحه ( يوري من المستقبل: النظام لا يزال غير مفتوح المصدر في وقت كتابة هذا التقرير ).

استنتاج


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

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

قررنا العودة إلى هذا الموضوع ، الذي تمت مناقشته على HighLoad ++ ، وربما لم يحظَ بالاهتمام الواجب ، لأنه كان مجرد واحد من العديد من الطوب لتحقيق الأداء العالي. ولكن الآن لدينا مؤتمر منفصل PHP روسيا المهنية مكرسة بالكامل ل PHP. وهنا نأتي حقا إلى أقصى حد. سنتحدث بدقة عن الأداء ، وعن المعايير ، وعن الأدوات - الكثير عن ذلك ، بما في ذلك إعادة التوطين .

اشترك في قناة Telegram مع تحديثات برنامج المؤتمر وأراك في 17 مايو.

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


All Articles