بيثون استبدال عملية متعددة! بيركلي المصدر المفتوح إطار توزيع راي

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

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

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

لماذا استخدام راي؟

ويوضح الكثير من البرنامج التعليمي كيفية استخدام بيثون متعدد المعالجة (https://docs.python.org/2/library/multiprocessing.html) وحدة. للأسف، وحدة متعدد المعالجة هناك أوجه قصور خطيرة في تطبيق متطلبات جوانب المعالجة الحديثة. وتشمل هذه الاحتياجات من العناصر التالية:

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

راي (https://github.com/ray-project/ray) عناوين كل هذه القضايا، مع الحفاظ على البساطة جعل سلوك معقد ممكن.

المفاهيم الضرورية

تعتمد البرمجة التقليدية على اثنين من المفاهيم الأساسية: وظائف والطبقات. هذه اللبنات يمكن استخدامها لبناء العديد من التطبيقات.

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

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

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

أدوات الحوسبة الموزعة

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

التي راي

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

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

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

المهام المتوازية

لتحويل وظيفة بيثون و "وظيفة عن بعد" (وظيفة لا يمكن أن يؤديها عن بعد وغير المتزامن)، يمكنك استخدام @ الديكور ray.remote للإعلان عن وظيفة. ثم f.remote استدعاء دالة () إرجاع مباشرة مع المستقبل (المستقبل هو إشارة إلى الناتج النهائي)، وسيتم تنفيذ وظيفة الفعلي في الخلفية (ونحن سوف أداء هذه الوظيفة يسمى مهمة).

نسخ رمز

راي استيراد الوقت استيراد # بدء راي. ray.init () @ Ray.remote الط صفر (س): time.sleep (1) عودة س # بدء 4 المهام بشكل متواز. result_ids = لأنني في مجموعة (4): result_ids.append (f.remote (ط)) # انتظر المهام كاملة واسترداد النتائج. # مع لا يقل عن 4 النوى، وهذا سوف يأخذ 1 ثانية. النتائج = ray.get (result_ids) #

تشغيل المهام موازية في التعليمات البرمجية بايثون

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

تبعيات المهام

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

نسخ رمز

استيراد نمباي كما أرستها @ Ray.remote create_matrix صفر (حجم): عودة np.random.normal (حجم = حجم) @ Ray.remote مواطنه multiply_matrices (س، ص): عودة np.dot (س، ص) x_id = create_matrix.remote () y_id = create_matrix.remote () z_id = multiply_matrices.remote (x_id، y_id) # الحصول على النتائج. ض = ray.get (z_id)

هناك ثلاث مهام، والمهمة الثالثة تعتمد على الانتاج من المهام السابقتين

بلمرة القيم بشكل فعال

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

الاعتماد على العمق على اليسار هو 7، والحق هو عمق الرسم البياني التبعية 3. يحسب لإنتاج نفس النتائج، ولكن الاعتماد على الرسم البياني الحق أسرع التنفيذ.

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

نسخ رمز

الوقت استيراد @ Ray.remote مواطنه إضافة (س، ص): time.sleep (1) عودة س + ص # تجميع القيم ببطء. يأخذ هذا النهج O (ن) حيث n هو # عدد من القيم يجري تجميعها. في هذه الحالة، 7 ثواني. ID1 = add.remote (1، 2) ID2 = add.remote (ID1، 3) ID3 = add.remote (ID2، 4) id4 = add.remote (ID3، 5) id5 = add.remote (id4، 6) ID6 = add.remote (id5، 7) ID7 = add.remote (ID6، 8) يؤدي = ray.get (ID7) # تجميع القيم في نمط منظم شجرة. هذا النهج # تحيط O (سجل (ن)). وفي هذه الحالة، 3 ثوان. ID1 = add.remote (1، 2) ID2 = add.remote (3 و 4) ID3 = add.remote (5، 6) id4 = add.remote (7، 8) id5 = add.remote (ID1، ID2) ID6 = add.remote (ID3، id4) ID7 = add.remote (id5، ID6) يؤدي = ray.get (ID7)

القيمة الإجمالية بطريقة خطية في بنية شجرة من قيمة مقارنة البوليمرية

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

نسخ رمز

# نهج بطيء. قيم = بينما ليون (قيم) >  1: قيم = + القيم يؤدي = ray.get (القيم ) # نهج سريع. قيم = بينما ليون (قيم) >  1: قيم = القيم + يؤدي = ray.get (القيم )

تنفيذ البلمرة نظافة. والفرق الوحيد بين الكتلتين من التعليمات البرمجية "add.remote" هو الإخراج على الجبهة أو مؤخرة القائمة.

من فئة إلى الفاعل

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

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

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

نسخ رمز

@ Ray.remote الطبقة عداد (كائن): __init مواطنه __ (النفس): self.x = 0 مواطنه المؤتمر الوطني العراقي (النفس): self.x + 1 = get_value صفر (النفس): عودة self.x # إنشاء عملية الفاعل. ج = Counter.remote () # تحقق قيمة العداد الفاعل. طباعة (ray.get (c.get_value.remote ())) # 0 # الاضافة العداد مرتين والتحقق من القيمة مرة أخرى. c.inc.remote () c.inc.remote () طباعة (ray.get (c.get_value.remote ())) # 2

إنشاء مثيل الطبقة بيثون كممثل

المثال أعلاه هو الممثل معظم استخدام بسيط. Counter.remote () بإنشاء عملية الممثل الجديد، الذي يحمل نسخة من الأجسام المضادة. والدعوة إلى c.get_value.remote () وc.inc.remote () أداء المهام على عملية الممثل النائية وتغيير حالة الفاعل.

مقابض الممثل

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

يقوم المثال التالي الفاعل يمكن أن ينقذ رسالة. عدة مهمة عامل مرارا يدفع رسالة إلى الفاعل، بيثون النصي الرئيسي يقرأ الرسالة على أساس منتظم.

نسخ رمز

الوقت استيراد @ Ray.remote الطبقة MessageActor (كائن): __init مواطنه __ (النفس): self.messages = ADD_MESSAGE صفر (النفس، الرسالة): self.messages.append (الرسالة) get_and_clear_messages صفر (النفس): رسائل = self.messages self.messages = رسائل العودة # تحديد وظيفة عن بعد الذي يلتف حول والدفعات # رسائل إلى الفاعل. @ Ray.remote عامل صفر (message_actor، ي): لأنني في مجموعة (100): time.sleep (1) message_actor.add_message.remote ( "رسالة {} {} من الفاعل." صيغة (ط، ي)) # إنشاء الممثل الرسالة. message_actor = MessageActor.remote () # البداية 3 المهام التي تدفع رسائل إلى الفاعل. # دوري الحصول على الرسائل وطباعتها. ل_ مجموعة في (100): new_messages = ray.get (message_actor.get_and_clear_messages.remote ()) طباعة ( "رسائل جديدة:" new_messages) time.sleep (1) # هذا السيناريو طباعة شيء من هذا القبيل ما يلي: # رسائل جديدة: # رسائل جديدة: # رسائل جديدة: # رسائل جديدة: # رسائل جديدة: # رسائل جديدة: # رسائل جديدة:

استدعاء الأسلوب الفاعل في مهام متعددة متزامنة

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

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

النص الانكليزي:

https://medium.com/@robertnishihara/modern-parallel-and-distributed-python-a-quick-tutorial-on-ray-99f8d70369b8