البرنامج التعليمي: تشغيل حمل عمل متوازي مع Azure Batch باستخدام واجهة برمجة تطبيقات Python

استخدم Azure Batch لتشغيل مهام الحوسبة المتوازية وعالية الأداء (HPC) على نطاق واسع بكفاءة في Azure. يستعرض هذا البرنامج التعليمي مثال Python لتشغيل حمل عمل متوازي باستخدام Batch. ستتعلم سير العمل الشائع لتطبيق Batch وطريقة التفاعل برمجياً مع موارد Batch وStorage.

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

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

إذا لم يكن لديك اشتراك في Azure، فأنشئ حساب Azure مجاني قبل أن تبدأ.

المتطلبات الأساسية

  • إصدار Python 3.8 أو أحدث

  • مدير حزمة pip

  • حساب Azure Batch وحساب تخزين Azure مرتبط. لإنشاء هذه الحسابات، راجع إرشادات التشغيل السريع Batch لمدخل Azure أو Azure CLI.

تسجيل الدخول إلى Azure

قم بتسجيل الدخول إلى بوابة Azure.

الحصول على بيانات اعتماد الحساب

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

  1. حدد All services>Batch accounts، ثم حدد اسم حساب Batch الخاص بك.

  2. لمشاهدة بيانات اعتماد Batch، حدد Keys. انسخ قيم حساب Batch وعنوان URL ومفتاح الوصول الأساسي إلى محرر نص.

  3. لمشاهدة اسم حساب التخزين ومفاتيحه، حدد حساب التخزين. انسخ قيم اسم حساب التخزين وKey1 إلى محرر نص.

تنزيل عينة التطبيق وتشغيلها

تنزيل التطبيق النموذج

قم بتنزيل أو نسخ نموذج التطبيق من GitHub. لنسخ نموذج مستودع التطبيق باستخدام عميل Git، استخدم الأمر التالي:

git clone https://github.com/Azure-Samples/batch-python-ffmpeg-tutorial.git

انتقل إلى الدليل الذي يحتوي على batch_python_tutorial_ffmpeg.py الملف.

في بيئة تطوير Python الخاصة بك، قم بتثبيت الحزم المطلوبة باستخدام pip.

pip install -r requirements.txt

استخدم محرر التعليمات البرمجية لفتح الملف config.py. قم بتحديث سلاسل بيانات اعتماد حساب Batch وStorage بالقيم الفريدة الخاصة بحساباتك. على سبيل المثال:

_BATCH_ACCOUNT_NAME = 'yourbatchaccount'
_BATCH_ACCOUNT_KEY = 'xxxxxxxxxxxxxxxxE+yXrRvJAqT9BlXwwo1CwF+SwAYOxxxxxxxxxxxxxxxx43pXi/gdiATkvbpLRl3x14pcEQ=='
_BATCH_ACCOUNT_URL = 'https://yourbatchaccount.yourbatchregion.batch.azure.com'
_STORAGE_ACCOUNT_NAME = 'mystorageaccount'
_STORAGE_ACCOUNT_KEY = 'xxxxxxxxxxxxxxxxy4/xxxxxxxxxxxxxxxxfwpbIC5aAWA8wDu+AFXZB827Mt9lybZB1nUcQbQiUrkPtilK5BQ=='

تشغيل التطبيق

لتشغيل البرنامج النصي:

python batch_python_tutorial_ffmpeg.py

عند تشغيل التطبيق النموذجي، يكون إخراج وحدة التحكم مشابهاً لما يلي. أثناء التنفيذ، تواجه توقفاً مؤقتاً عند Monitoring all tasks for 'Completed' state, timeout in 00:30:00... أثناء بدء عقد حساب التجمع.

Sample start: 11/28/2018 3:20:21 PM

Container [input] created.
Container [output] created.
Uploading file LowPriVMs-1.mp4 to container [input]...
Uploading file LowPriVMs-2.mp4 to container [input]...
Uploading file LowPriVMs-3.mp4 to container [input]...
Uploading file LowPriVMs-4.mp4 to container [input]...
Uploading file LowPriVMs-5.mp4 to container [input]...
Creating pool [LinuxFFmpegPool]...
Creating job [LinuxFFmpegJob]...
Adding 5 tasks to job [LinuxFFmpegJob]...
Monitoring all tasks for 'Completed' state, timeout in 00:30:00...
Success! All tasks completed successfully within the specified timeout period.
Deleting container [input]....

Sample end: 11/28/2018 3:29:36 PM
Elapsed time: 00:09:14.3418742

الانتقال إلى حساب Batch في مدخل Microsoft Azure لمراقبة المجموعة وعقد الحساب والوظيفة والمهام. على سبيل المثال، لمشاهدة خريطة التمثيل اللوني لعقد الحوسبة في التجمع الخاص بك، حدد Pools>LinuxFFmpegPool.

عند تشغيل المهام، تكون خريطة التمثيل اللوني مشابهة لما يلي:

Screenshot of Pool heat map.

يبلغ وقت التنفيذ المُعتاد حوالي 5 دقائق عند تشغيل التطبيق في تكوينه الافتراضي. يستغرق إنشاء المجموعة معظم الوقت.

استرجاع ملفات الإخراج

يمكنك استخدام مدخل Azure لتنزيل ملفات MP3 الناتجة عن مهام ffmpeg.

  1. انقر فوق جميع حسابات تخزين الخدمات>، ثم انقر فوق اسم حساب التخزين الخاص بك.
  2. انقر فوق إخراج Blobs>.
  3. انقر بزر الماوس الأيمن فوق أحد ملفات MP3 الناتجة ثم انقر فوق تنزيل. اتبع المطالبات في المستعرض لفتح الملف أو حفظه.

Download output file

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

مراجعة الرمز

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

مصادقة عملاء Blob وBatch

للتفاعل مع حساب التخزين Storage، يستخدم التطبيق حزمة azure-storage-blob لإنشاء كائن BlockBlobService.

blob_client = azureblob.BlockBlobService(
    account_name=_STORAGE_ACCOUNT_NAME,
    account_key=_STORAGE_ACCOUNT_KEY)

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

credentials = batchauth.SharedKeyCredentials(_BATCH_ACCOUNT_NAME,
                                             _BATCH_ACCOUNT_KEY)

batch_client = batch.BatchServiceClient(
    credentials,
    base_url=_BATCH_ACCOUNT_URL)

تحميل ملفات الإدخال

يستخدم التطبيق المرجع blob_client إنشاء حاوية تخزين لملفات MP4 الإدخال وحاوية تخزين مخرجات المهمة. ثم يستدعي الدالة upload_file_to_container لتحميل ملفات MP4 في دليل InputFiles المحلي إلى الحاوية. يتم تعريف الملفات المخزنة على أنها كائنات مجمعة ResourceFile والتي يمكن لـ Batch تنزيلها لاحقاً إلى عقد الحساب.

blob_client.create_container(input_container_name, fail_on_exist=False)
blob_client.create_container(output_container_name, fail_on_exist=False)
input_file_paths = []

for folder, subs, files in os.walk(os.path.join(sys.path[0], './InputFiles/')):
    for filename in files:
        if filename.endswith(".mp4"):
            input_file_paths.append(os.path.abspath(
                os.path.join(folder, filename)))

# Upload the input files. This is the collection of files that are to be processed by the tasks.
input_files = [
    upload_file_to_container(blob_client, input_container_name, file_path)
    for file_path in input_file_paths]

قم بإنشاء مجموعة من العقد الحسابية

بعد ذلك، يُنشئ النموذج مجموعة من عُقد الحساب في حساب Batch مع استدعاء create_pool. تستخدم هذه الدالة المُحددة فئة PoolAddParameter في Batch لتحديد عدد العقد، وحجم VM، وتكوين المجموعة. نجد هنا، أن عنصر VirtualMachineConfiguration يعيَّن ImageReference إلى صورة Ubuntu Server 20.04 LTS المنشورة في Azure Marketplace. Batch يدعم مجموعة كبيرة من صور VM في Azure Marketplace، بالإضافة إلى صور VM المخصصة.

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

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

ترسل طريقة pool.add التجمع إلى خدمة Batch.

new_pool = batch.models.PoolAddParameter(
    id=pool_id,
    virtual_machine_configuration=batchmodels.VirtualMachineConfiguration(
        image_reference=batchmodels.ImageReference(
            publisher="Canonical",
            offer="UbuntuServer",
            sku="20.04-LTS",
            version="latest"
        ),
        node_agent_sku_id="batch.node.ubuntu 20.04"),
    vm_size=_POOL_VM_SIZE,
    target_dedicated_nodes=_DEDICATED_POOL_NODE_COUNT,
    target_low_priority_nodes=_LOW_PRIORITY_POOL_NODE_COUNT,
    start_task=batchmodels.StartTask(
        command_line="/bin/bash -c \"apt-get update && apt-get install -y ffmpeg\"",
        wait_for_success=True,
        user_identity=batchmodels.UserIdentity(
            auto_user=batchmodels.AutoUserSpecification(
                scope=batchmodels.AutoUserScope.pool,
                elevation_level=batchmodels.ElevationLevel.admin)),
    )
)
batch_service_client.pool.add(new_pool)

قم بإنشاء وظيفة

تحدد وظيفة Batch مخزناً لتشغيل المهام عليه وإعدادات اختيارية مثل الأولوية والجدول الزمني للعمل. يُنشئ النموذج وظيفة باستدعاء create_job. تستخدم هذه الدالة المُحددة فئة JobAddParameter لإنشاء وظيفة في مجموعتك. ترسل طريقة job.add المجموعة إلى خدمة Batch. في البداية المهمة ليس لها مهام.

job = batch.models.JobAddParameter(
    id=job_id,
    pool_info=batch.models.PoolInformation(pool_id=pool_id))

batch_service_client.job.add(job)

إنشاء مهام

يقوم التطبيق على إنشاء مهام في الوظيفة مع استدعاء add_tasks. تُنشئ هذه الدالة قائمة بكائنات المهام باستخدام فئة TaskAddParameter. يُشغل كل ffmpeg لمعالجة كائن إدخال resource_filesباستخدام معلمةcommand_line. سبق تثبيت ffmpeg على كل عقدة عند إنشاء المجموعة. هنا، يقوم سطر الأوامر بتشغيل ffmpeg لتحويل كل ملف إدخال MP4 (فيديو) إلى ملف MP3 (صوتي).

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

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

tasks = list()

for idx, input_file in enumerate(input_files):
    input_file_path = input_file.file_path
    output_file_path = "".join((input_file_path).split('.')[:-1]) + '.mp3'
    command = "/bin/bash -c \"ffmpeg -i {} {} \"".format(
        input_file_path, output_file_path)
    tasks.append(batch.models.TaskAddParameter(
        id='Task{}'.format(idx),
        command_line=command,
        resource_files=[input_file],
        output_files=[batchmodels.OutputFile(
            file_pattern=output_file_path,
            destination=batchmodels.OutputFileDestination(
                container=batchmodels.OutputFileBlobContainerDestination(
                    container_url=output_container_sas_url)),
            upload_options=batchmodels.OutputFileUploadOptions(
                upload_condition=batchmodels.OutputFileUploadCondition.task_success))]
    )
    )
batch_service_client.task.add_collection(job_id, tasks)

مراقبة المهام

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

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

while datetime.datetime.now() < timeout_expiration:
    print('.', end='')
    sys.stdout.flush()
    tasks = batch_service_client.task.list(job_id)

    incomplete_tasks = [task for task in tasks if
                        task.state != batchmodels.TaskState.completed]
    if not incomplete_tasks:
        print()
        return True
    else:
        time.sleep(1)
...

تنظيف الموارد

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

عند عدم الحاجة، احذف مجموعة الموارد وحساب الدفعة وحساب التخزين. للقيام بذلك في مدخل Microsoft Azure، حدد مجموعة الموارد لحساب Batch واختر Delete resource group.

الخطوات التالية

في هذا البرنامج التعليمي، نتعلم طريقة القيام بما يأتي:

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

لمزيد من الأمثلة على استخدام واجهة برمجة تطبيقات Python لجدولة أحمال عمل Batch ومعالجتها، راجع نماذج Batch Python على GitHub.