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

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

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

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

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

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

امنح حق الوصول إلى حسابات الدفعات والتخزين الخاصة بك

يوضح هذا الدليل كيفية المصادقة على Azure Batch و تخزين Azure باستخدام Microsoft Entra ID مع DefaultAzureCredential. التطبيق لا يستخدم مفاتيح الحساب. قبل تشغيل التطبيق، تأكد من أن الهوية التي تستخدمها تحتوي على الأدوار المطلوبة في كلا الحسابين.

  1. تسجيل الدخول باستخدام Azure CLI. DefaultAzureCredential يلتقط تلقائيا هذا تسجيل الدخول:

    az login
    
  2. خصص لحساب المستخدم لك دورا يسمح بعمليات مستوى البيانات على حساب Batch مثل Azure Batch Data Contributor. هذا الدور مطلوب لإنشاء مجموعات ووظائف ومهام. يمكنك تعيين الدور في صفحة التحكم في الوصول (IAM) لحساب Batch في بوابة Azure، أو استخدام Azure CLI:

    az role assignment create \
        --assignee "<your-user-principal-name>" \
        --role "Azure Batch Data Contributor" \
        --scope "/subscriptions/<subscription-id>/resourceGroups/<resource-group>/providers/Microsoft.Batch/batchAccounts/<batch-account-name>"
    
  3. خصص دور مساهم بيانات كتلة التخزين في حساب المستخدم الخاص بكتيرة التخزين الخاصة بك. يتطلب هذا الدور إنشاء الحاويات، ورفع ملفات الإدخال، وطلب مفتاح تفويض المستخدم الذي يوقع على عناوين توقيع الوصول المشترك (SAS) المستخدمة في المهام:

    az role assignment create \
        --assignee "<your-user-principal-name>" \
        --role "Storage Blob Data Contributor" \
        --scope "/subscriptions/<subscription-id>/resourceGroups/<resource-group>/providers/Microsoft.Storage/storageAccounts/<storage-account-name>"
    
  4. لاحظ القيم التالية، والتي تضيفها إلى ملف config.py العينة في القسم التالي. يمكنك العثور عليها في صفحة النظرة العامة لكل حساب في بوابة Azure:

    • اسم حساب الدفعة
    • على سبيل المثال، رابط حساب الدفعة https://mybatchaccount.westus2.batch.azure.com
    • اسم حساب التخزين

ملحوظة

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

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

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

قم بتنزيل أو نسخ نموذج التطبيق من GitHub. العينة موجودة في مستودع عينات azure دفعة تحت Python/Batch/article_samples/ffmpeg. لاستنساخ المستودع باستخدام عميل Git، استخدم الأمر التالي:

git clone https://github.com/Azure-Samples/azure-batch-samples.git

انتقل إلى مجلد Python/Batch/article_samples/ffmpeg، الذي يحتوي على batch_python_tutorial_ffmpeg.py الملف.

cd azure-batch-samples/Python/Batch/article_samples/ffmpeg

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

pip install -r requirements.txt

قم بتوليد ملفات الإدخال النموذجية. المستودع لا يشحن الوسائط الثنائية، لذا أنشئ مقاطع InputFiles/* المحلية.mp4 باستخدام المساعد المرفق (يتطلب ffmpeg على PATH):

python generate_input_files.py

يكتب هذا الأمر خمسة مقاطع عينة قصيرة (LowPriVMs-1.mp4 إلى LowPriVMs-5.mp4) في مجلد InputFiles . بدلا من ذلك، ضع ملفات .mp4 الخاصة بك في InputFiles.

استخدم محرر التعليمات البرمجية لفتح الملف config.py. قم بتحديث قيم حسابات الدفعة والتخزين بالأسماء الفريدة لحساباتك. يستخدم العينة DefaultAzureCredential للمصادقة، لذا لم تعد مفاتيح الحساب مطلوبة. على سبيل المثال:

_BATCH_ACCOUNT_NAME = 'yourbatchaccount'
_BATCH_ACCOUNT_URL = 'https://yourbatchaccount.yourbatchregion.batch.azure.com'
_STORAGE_ACCOUNT_NAME = 'mystorageaccount'

تأكد من تسجيل الدخول باستخدام az login المستخدم وأن هويتك تحمل الأدوار الموصوفة في Grant Access إلى حسابات Batch وStorage الخاصة بك. DefaultAzureCredentialيمكنه أيضا اكتشاف مصادر بيانات معتمدة أخرى، مثل هوية مدارة، تعليمة Visual Studio برمجية، أو متغيرات البيئة.

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

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

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 reached the 'Completed' state 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.

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

لقطة شاشة لخريطة التمثيل اللوني للتجمع.

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

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

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

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

قم بتحميل ملف الإخراج

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

مراجعة الرمز

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

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

يتم التحقق من صحة العينة باستخدام كل من Storage وBatch باستخدام DefaultAzureCredential من حزمة azure-identity . DefaultAzureCredential يحاول عدة أنواع بيانات اعتماد بالترتيب (متغيرات البيئة، الهوية المدارة، تسجيل دخول Azure CLI، وهكذا)، مما يجعل نفس الكود يعمل في التطوير المحلي وفي الإنتاج دون تخزين مفاتيح الحساب.

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

يستورد العينة أنواع الهوية والتخزين التالية، ويقرأ أسماء الحسابات من config.py:

import config
from azure.identity import DefaultAzureCredential
from azure.storage.blob import (
    BlobServiceClient,
    BlobSasPermissions,
    ContainerSasPermissions,
    generate_blob_sas,
    generate_container_sas,
)
credential = DefaultAzureCredential()

blob_service_client = BlobServiceClient(
    account_url=f"https://{config._STORAGE_ACCOUNT_NAME}.blob.core.windows.net/",
    credential=credential)

يقوم التطبيق بإنشاء كائن BatchClient لإنشاء وإدارة مجموعات التجمع والوظائف والمهام في خدمة Batch (الدفع). يستخدم عميل الدفعة نفس DefaultAzureCredential للمصادقة من خلال Microsoft Entra ID.

batch_client = BatchClient(
    endpoint=config._BATCH_ACCOUNT_URL,
    credential=credential)

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

start = datetime.datetime.now(datetime.timezone.utc)
expiry = start + datetime.timedelta(hours=4)
user_delegation_key = blob_service_client.get_user_delegation_key(
    key_start_time=start, key_expiry_time=expiry)

# Sign the SAS tokens with the same expiry as the user delegation key.
sas_expiry = expiry

ملحوظة

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

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

بعد إنشاء حاويات الإدخال والإخراج باستخدام blob_service_client، يقوم التطبيق برفع كل ملف MP4 محلي في مجلد InputFiles إلى حاوية الإدخال. يقوم المساعد التالي upload_file_to_container برفع ملف واحد، ويولد رمز SAS للقراءة فقط له موقعا بمفتاح تفويض المستخدم، ويعيد كائن Batch ResourceFile يتضمن رابط URL رمز SAS حتى يتمكن Batch لاحقا من تحميل الملف إلى عقدة حسابية. يستدعي التطبيق هذا المساعد مرة واحدة لكل ملف إدخال:

def upload_file_to_container(blob_service_client, user_delegation_key,
                             sas_expiry, container_name, file_path):
    blob_name = os.path.basename(file_path)
    blob_client = blob_service_client.get_blob_client(container_name, blob_name)

    with open(file_path, "rb") as data:
        blob_client.upload_blob(data, overwrite=True)

    sas_token = generate_blob_sas(
        account_name=config._STORAGE_ACCOUNT_NAME,
        container_name=container_name,
        blob_name=blob_name,
        user_delegation_key=user_delegation_key,
        permission=BlobSasPermissions(read=True),
        expiry=sas_expiry)

    sas_url = f"{blob_client.url}?{sas_token}"

    return models.ResourceFile(http_url=sas_url, file_path=blob_name)

كما يولد التطبيق رابط SAS لحاوية الإخراج التي تمنح حق الكتابة. تستخدم المهام هذا الرابط لرفع ملفات الإخراج إلى التخزين:

sas_token = generate_container_sas(
    account_name=config._STORAGE_ACCOUNT_NAME,
    container_name=output_container_name,
    user_delegation_key=user_delegation_key,
    permission=ContainerSasPermissions(write=True, create=True, list=True),
    expiry=sas_expiry)

output_container_sas_url = (
    f"https://{config._STORAGE_ACCOUNT_NAME}.blob.core.windows.net/"
    f"{output_container_name}?{sas_token}")

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

بعد ذلك، ينشئ العينة مجموعة من عقد الحوسبة في حساب الدفعة عن طريق استدعاء create_pool. تستخدم هذه الدالة المعرفة فئة Batch BatchPoolCreateOptions لتحديد عدد العقد، وحجم الآلة الافتراضية، وتكوين المجموعة. في هذا التكوين، يحدد كائن VirtualMachineConfigurationBatchVmImageReference إلى صورة LTS لخادم أوبونتو 24.04 منشورة في Azure Marketplace. Batch يدعم مجموعة كبيرة من صور VM في Azure Marketplace، بالإضافة إلى صور VM المخصصة.

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

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

طريقة create_pool تقدم المجموعة إلى خدمة الدفعات.

new_pool = models.BatchPoolCreateOptions(
    id=pool_id,
    virtual_machine_configuration=models.VirtualMachineConfiguration(
        image_reference=models.BatchVmImageReference(
            publisher="canonical",
            offer="ubuntu-24_04-lts",
            sku="server-gen1",
            version="latest"
        ),
        node_agent_sku_id="batch.node.ubuntu 24.04"),
    vm_size=_POOL_VM_SIZE,
    target_dedicated_nodes=_DEDICATED_POOL_NODE_COUNT,
    target_low_priority_nodes=_LOW_PRIORITY_POOL_NODE_COUNT,
    start_task=models.BatchStartTask(
        command_line="/bin/bash -c \"apt-get update && apt-get install -y ffmpeg\"",
        wait_for_success=True,
        user_identity=models.UserIdentity(
            auto_user=models.AutoUserSpecification(
                scope=models.AutoUserScope.POOL,
                elevation_level=models.ElevationLevel.ADMIN)),
    )
)
batch_client.create_pool(pool=new_pool)

ملحوظة

صور الآلات الافتراضية في السوق ووكلاء عقد الدفعة لديهم تواريخ نهاية مدعومة. لم تعد صور أوبونتو سيرفر 20.04 LTS ووكيل batch.node.ubuntu 20.04 العقدة مدعومة لتجمعات الدفعات الجديدة. لسرد مراجع الصور ووحدات وكيل العقد التي يدعمها حساب Batch الخاص بك حاليا، اتصل بطريقة list_supported_images .

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

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

job = models.BatchJobCreateOptions(
    id=job_id,
    pool_info=models.BatchPoolInfo(pool_id=pool_id))

batch_client.create_job(job=job)

إنشاء مهام

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

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

ثم يضيف التطبيق المهام إلى المهمة باستخدام طريقة create_tasks ، التي تضعها في قائمة الانتظار لتعمل على عقد الحوسبة.

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(models.BatchTaskCreateOptions(
        id='Task{}'.format(idx),
        command_line=command,
        resource_files=[input_file],
        output_files=[models.OutputFile(
            file_pattern=output_file_path,
            destination=models.OutputFileDestination(
                container=models.OutputFileBlobContainerDestination(
                    container_url=output_container_sas_url)),
            upload_options=models.OutputFileUploadConfiguration(
                upload_condition=models.OutputFileUploadCondition.TASK_SUCCESS))]
    )
    )
batch_client.create_tasks(job_id=job_id, task_collection=tasks)

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

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

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

while datetime.datetime.now() < timeout_expiration:
    print('.', end='')
    sys.stdout.flush()
    tasks = batch_client.list_tasks(job_id=job_id)

    incomplete_tasks = [task for task in tasks if
                        task.state != models.BatchTaskState.COMPLETED]
    if not incomplete_tasks:
        print()
        return True
    else:
        time.sleep(5)
...

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

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

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

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

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

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

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